stub-npm.mjs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. /**
  2. * Stub npm CLI for the publish-path fixture. Records every invocation verbatim,
  3. * fails loudly on a missing tarball, and registers published names with the
  4. * fixture registry so the publisher's own verification step is exercised too.
  5. */
  6. import fs from 'node:fs'
  7. import path from 'node:path'
  8. import { createHash } from 'node:crypto'
  9. import { packageFiles } from '../../tar.mjs'
  10. const [command, ...rest] = process.argv.slice(2)
  11. const log = process.env.SCRIPTOR_STUB_LOG
  12. const registry = process.env.SCRIPTOR_STUB_REGISTRY
  13. const publish = process.env.SCRIPTOR_STUB_PUBLISH
  14. if (!log || !registry || !publish) {
  15. console.error('stub npm: SCRIPTOR_STUB_LOG, SCRIPTOR_STUB_REGISTRY and SCRIPTOR_STUB_PUBLISH are required')
  16. process.exit(2)
  17. }
  18. const record = value => fs.appendFileSync(log, `${JSON.stringify(value)}\n`)
  19. if (command !== 'publish') {
  20. record({ command, rest })
  21. console.error(`stub npm: unexpected command ${command}`)
  22. process.exit(2)
  23. }
  24. const filename = path.resolve(rest[0])
  25. if (!fs.existsSync(filename)) {
  26. record({ command, rest, missing: filename })
  27. console.error(`stub npm: tarball does not exist: ${filename}`)
  28. process.exit(2)
  29. }
  30. const bytes = fs.readFileSync(filename)
  31. const manifest = JSON.parse(packageFiles(filename).get('package.json'))
  32. const dryRun = rest.includes('--dry-run')
  33. const entry = {
  34. name: manifest.name,
  35. version: manifest.version,
  36. tarball: path.basename(filename),
  37. integrity: `sha512-${createHash('sha512').update(bytes).digest('base64')}`,
  38. distTag: rest[rest.indexOf('--tag') + 1],
  39. provenance: rest.includes('--provenance'),
  40. }
  41. const state = JSON.parse(fs.existsSync(publish) ? fs.readFileSync(publish, 'utf8') : '{}')
  42. if (!dryRun) state[manifest.name] = entry
  43. fs.writeFileSync(publish, JSON.stringify(state, null, 2) + '\n')
  44. record({ command, rest, dryRun, name: manifest.name, version: manifest.version, tarball: entry.tarball,
  45. integrity: entry.integrity, provenance: entry.provenance, distTag: entry.distTag, registryConfigured: registry })
  46. console.log(`[stub npm] ${dryRun ? 'dry-run ' : ''}publish ${manifest.name}@${manifest.version}`)