verify-renderer-repos.mjs 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import { existsSync } from 'node:fs'
  2. import { readFile, stat } from 'node:fs/promises'
  3. import { dirname, join, resolve } from 'node:path'
  4. import { fileURLToPath } from 'node:url'
  5. const scriptDir = dirname(fileURLToPath(import.meta.url))
  6. const sourceRoot = resolve(scriptDir, '..')
  7. const args = process.argv.slice(2)
  8. const readArg = (name, fallback) => {
  9. const index = args.indexOf(name)
  10. return index >= 0 ? args[index + 1] : fallback
  11. }
  12. const outputRoot = resolve(
  13. sourceRoot,
  14. readArg(
  15. '--out-dir',
  16. process.env.FILE_VIEWER_COMPONENT_REPO_DIR ||
  17. process.env.FILE_VIEWER_WRAPPER_REPO_DIR ||
  18. '.release/component-repos'
  19. )
  20. )
  21. const selectedPackages = new Set(
  22. args
  23. .filter(arg => arg.startsWith('--package='))
  24. .map(arg => arg.slice('--package='.length))
  25. )
  26. const selectedIds = new Set(
  27. args
  28. .filter(arg => arg.startsWith('--id='))
  29. .map(arg => arg.slice('--id='.length))
  30. )
  31. const readJson = async path => JSON.parse(await readFile(path, 'utf8'))
  32. const ecosystemManifest = await readJson(join(sourceRoot, 'ecosystem', 'wrappers.json'))
  33. const assertFile = async (path, label = path) => {
  34. if (!existsSync(path)) {
  35. throw new Error(`Missing file: ${label}`)
  36. }
  37. const info = await stat(path)
  38. if (!info.isFile()) {
  39. throw new Error(`Not a file: ${label}`)
  40. }
  41. }
  42. const assertNoText = (text, forbidden, label) => {
  43. if (text.includes(forbidden)) {
  44. throw new Error(`${label} unexpectedly includes ${forbidden}`)
  45. }
  46. }
  47. const renderers = (ecosystemManifest.renderers || []).filter(renderer => {
  48. if (selectedPackages.size && !selectedPackages.has(renderer.packageName)) {
  49. return false
  50. }
  51. if (selectedIds.size && !selectedIds.has(renderer.id)) {
  52. return false
  53. }
  54. return true
  55. })
  56. if (!renderers.length) {
  57. throw new Error('No renderer packages selected for verification.')
  58. }
  59. for (const renderer of renderers) {
  60. const targetDir = join(outputRoot, renderer.repository)
  61. await assertFile(join(targetDir, 'package.json'), `${renderer.packageName} package.json`)
  62. await assertFile(join(targetDir, 'README.md'), `${renderer.packageName} README.md`)
  63. await assertFile(join(targetDir, 'README.en.md'), `${renderer.packageName} README.en.md`)
  64. await assertFile(join(targetDir, 'LICENSE'), `${renderer.packageName} LICENSE`)
  65. await assertFile(join(targetDir, 'renderer-repo-manifest.json'), `${renderer.packageName} manifest`)
  66. await assertFile(join(targetDir, 'src', 'index.ts'), `${renderer.packageName} src/index.ts`)
  67. const packageJson = await readJson(join(targetDir, 'package.json'))
  68. if (packageJson.name !== renderer.packageName) {
  69. throw new Error(`${renderer.packageName} export has package name ${packageJson.name}`)
  70. }
  71. if (packageJson.repository?.url !== `git+${renderer.github}.git`) {
  72. throw new Error(`${renderer.packageName} repository URL is not normalized to ${renderer.github}`)
  73. }
  74. const serialized = JSON.stringify(packageJson)
  75. assertNoText(serialized, 'workspace:', `${renderer.packageName} package.json`)
  76. if (existsSync(join(targetDir, 'node_modules')) || existsSync(join(targetDir, 'dist'))) {
  77. throw new Error(`${renderer.packageName} standalone repo must not contain node_modules or dist`)
  78. }
  79. console.log(`Verified renderer ${renderer.packageName}`)
  80. }
  81. console.log(`Verified ${renderers.length} renderer package repo${renderers.length === 1 ? '' : 's'} in ${outputRoot}.`)