cloudflare/cloudflare-typescript

Public

mirrored from https://github.com/cloudflare/cloudflare-typescriptAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
df10e5d04a9c6ac8aaf2feaa7d524216878d7388

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

scripts/utils/postprocess-files.cjs

101lines · modecode

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