postprocess-files.cjs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. // @ts-check
  2. const fs = require('fs');
  3. const path = require('path');
  4. const distDir =
  5. process.env['DIST_PATH'] ?
  6. path.resolve(process.env['DIST_PATH'])
  7. : path.resolve(__dirname, '..', '..', 'dist');
  8. async function* walk(dir) {
  9. for await (const d of await fs.promises.opendir(dir)) {
  10. const entry = path.join(dir, d.name);
  11. if (d.isDirectory()) yield* walk(entry);
  12. else if (d.isFile()) yield entry;
  13. }
  14. }
  15. async function postprocess() {
  16. for await (const file of walk(distDir)) {
  17. if (!/(\.d)?[cm]?ts$/.test(file)) continue;
  18. const code = await fs.promises.readFile(file, 'utf8');
  19. // strip out lib="dom", types="node", and types="react" references; these
  20. // are needed at build time, but would pollute the user's TS environment
  21. const transformed = code.replace(
  22. /^ *\/\/\/ *<reference +(lib="dom"|types="(node|react)").*?\n/gm,
  23. // replace with same number of characters to avoid breaking source maps
  24. (match) => ' '.repeat(match.length - 1) + '\n',
  25. );
  26. if (transformed !== code) {
  27. console.error(`wrote ${path.relative(process.cwd(), file)}`);
  28. await fs.promises.writeFile(file, transformed, 'utf8');
  29. }
  30. }
  31. const newExports = {
  32. '.': {
  33. require: {
  34. types: './index.d.ts',
  35. default: './index.js',
  36. },
  37. types: './index.d.mts',
  38. default: './index.mjs',
  39. },
  40. };
  41. for (const entry of await fs.promises.readdir(distDir, { withFileTypes: true })) {
  42. if (entry.isDirectory() && entry.name !== 'src' && entry.name !== 'internal' && entry.name !== 'bin') {
  43. const subpath = './' + entry.name;
  44. newExports[subpath + '/*.mjs'] = {
  45. default: subpath + '/*.mjs',
  46. };
  47. newExports[subpath + '/*.js'] = {
  48. default: subpath + '/*.js',
  49. };
  50. newExports[subpath + '/*'] = {
  51. import: subpath + '/*.mjs',
  52. require: subpath + '/*.js',
  53. };
  54. } else if (entry.isFile() && /\.[cm]?js$/.test(entry.name)) {
  55. const { name, ext } = path.parse(entry.name);
  56. const subpathWithoutExt = './' + name;
  57. const subpath = './' + entry.name;
  58. newExports[subpathWithoutExt] ||= { import: undefined, require: undefined };
  59. const isModule = ext[1] === 'm';
  60. if (isModule) {
  61. newExports[subpathWithoutExt].import = subpath;
  62. } else {
  63. newExports[subpathWithoutExt].require = subpath;
  64. }
  65. newExports[subpath] = {
  66. default: subpath,
  67. };
  68. }
  69. }
  70. await fs.promises.writeFile(
  71. 'dist/package.json',
  72. JSON.stringify(
  73. Object.assign(
  74. /** @type {Record<String, unknown>} */ (
  75. JSON.parse(await fs.promises.readFile('dist/package.json', 'utf-8'))
  76. ),
  77. {
  78. exports: newExports,
  79. },
  80. ),
  81. null,
  82. 2,
  83. ),
  84. );
  85. }
  86. postprocess();