tarball.ts 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. /**
  2. * Reading packed npm tarballs and the order file that accompanies them.
  3. *
  4. * The release steps after pack treat a directory of tarballs as the unit of
  5. * work, so they read what a tarball declares rather than what the checkout
  6. * currently says.
  7. */
  8. import { readFileSync } from 'node:fs'
  9. import { join } from 'node:path'
  10. import { capture } from './process.ts'
  11. /** Name of the file recording the order in which a packed family uploads. */
  12. export const PUBLISH_ORDER_FILE = 'publish-order.txt'
  13. /** What a packed tarball calls itself. */
  14. export interface PackedIdentity {
  15. /** Package name from the packed manifest. */
  16. readonly name: string
  17. /** Package version from the packed manifest. */
  18. readonly version: string
  19. }
  20. /**
  21. * List a tarball's members.
  22. * @param tarball - absolute tarball path.
  23. * @returns Every path inside the archive.
  24. */
  25. export function tarballFiles(tarball: string): string[] {
  26. return capture('tar', ['-tzf', tarball]).split('\n').filter(line => line !== '')
  27. }
  28. /**
  29. * Read a packed tarball's own manifest.
  30. * @param tarball - absolute tarball path.
  31. * @returns The name and version the tarball declares.
  32. */
  33. export function packedIdentity(tarball: string): PackedIdentity {
  34. const manifest: unknown = JSON.parse(capture('tar', ['-xOzf', tarball, 'package/package.json']))
  35. if (manifest === null || typeof manifest !== 'object') throw new Error(`${tarball} has no manifest`)
  36. const { name, version } = manifest as Record<string, unknown>
  37. if (typeof name !== 'string' || typeof version !== 'string') throw new Error(`${tarball} manifest lacks name/version`)
  38. return { name, version }
  39. }
  40. /**
  41. * Read a packed directory's upload order.
  42. * @param directory - absolute path of a pack output directory.
  43. * @returns Tarball filenames in upload order.
  44. */
  45. export function readPublishOrder(directory: string): string[] {
  46. return readFileSync(join(directory, PUBLISH_ORDER_FILE), 'utf8').split('\n').filter(line => line !== '')
  47. }