copy-assets.mjs 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. #!/usr/bin/env node
  2. import { cp, mkdir, readdir, rm } from 'node:fs/promises'
  3. import { existsSync } from 'node:fs'
  4. import { dirname, resolve } from 'node:path'
  5. import { fileURLToPath, pathToFileURL } from 'node:url'
  6. const scriptFile = fileURLToPath(import.meta.url)
  7. const packageDir = resolve(dirname(scriptFile), '..')
  8. const sourceDir = resolve(packageDir, 'viewer')
  9. const isPostinstall = process.argv.includes('--postinstall')
  10. const explicitTarget = process.argv.slice(2).find(arg => !arg.startsWith('--'))
  11. const targetDir = resolve(
  12. process.env.FILE_VIEWER_PUBLIC_DIR ||
  13. explicitTarget ||
  14. resolve(process.env.INIT_CWD || process.cwd(), 'public/file-viewer')
  15. )
  16. const skip = process.env.FILE_VIEWER_SKIP_ASSET_COPY === '1' ||
  17. process.env.FILE_VIEWER_SKIP_ASSET_COPY === 'true'
  18. if (skip) {
  19. process.exit(0)
  20. }
  21. // Workspace installs should not mutate the repository automatically.
  22. if (isPostinstall && !packageDir.includes('node_modules')) {
  23. process.exit(0)
  24. }
  25. if (!existsSync(sourceDir)) {
  26. const message = `[file-viewer-web] 缺少 viewer assets 产物: ${sourceDir}`
  27. if (isPostinstall) {
  28. console.warn(message)
  29. process.exit(0)
  30. }
  31. console.error(message)
  32. process.exit(1)
  33. }
  34. const removeMacMetadata = async dir => {
  35. const entries = await readdir(dir, { withFileTypes: true })
  36. await Promise.all(entries.map(entry => {
  37. const path = resolve(dir, entry.name)
  38. if (entry.name === '.DS_Store') {
  39. return rm(path, { force: true })
  40. }
  41. if (entry.isDirectory()) {
  42. return removeMacMetadata(path)
  43. }
  44. return undefined
  45. }))
  46. }
  47. const copyWithBuiltHelper = async () => {
  48. const helperPath = resolve(packageDir, 'dist/node.js')
  49. if (!existsSync(helperPath)) {
  50. return false
  51. }
  52. const { copyViewerAssets } = await import(pathToFileURL(helperPath).href)
  53. const result = await copyViewerAssets({ sourceDir, targetDir })
  54. if (result.validation?.missingOptional?.length) {
  55. console.warn(
  56. `[file-viewer-web] optional viewer assets missing: ${
  57. result.validation.missingOptional.map(asset => asset.relativePath).join(', ')
  58. }`
  59. )
  60. }
  61. console.log(`[file-viewer-web] viewer assets copied to ${result.targetDir}`)
  62. console.log(`[file-viewer-web] viewer asset manifest written to ${result.assetManifestPath}`)
  63. return true
  64. }
  65. const copyWithFallback = async () => {
  66. await rm(targetDir, { force: true, recursive: true })
  67. await mkdir(targetDir, { recursive: true })
  68. await cp(sourceDir, targetDir, { recursive: true })
  69. await removeMacMetadata(targetDir)
  70. console.log(`[file-viewer-web] viewer assets copied to ${targetDir}`)
  71. }
  72. try {
  73. if (!await copyWithBuiltHelper()) {
  74. await copyWithFallback()
  75. }
  76. } catch (reason) {
  77. const message = reason instanceof Error ? reason.message : String(reason)
  78. if (isPostinstall) {
  79. console.warn(`[file-viewer-web] viewer asset copy skipped: ${message}`)
  80. process.exit(0)
  81. }
  82. console.error(`[file-viewer-web] viewer asset copy failed: ${message}`)
  83. process.exit(1)
  84. }