-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstrip-types.js
More file actions
118 lines (96 loc) · 3.46 KB
/
strip-types.js
File metadata and controls
118 lines (96 loc) · 3.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
/* eslint-disable @typescript-eslint/no-require-imports */
const fs = require('fs');
const path = require('path');
const glob = require('glob');
// Track names where we generate Nest suffixes
const renamedNames = [];
function stripNestjsType(typeString) {
const target = 'import("@nestjs/common").Type<';
while (typeString.includes(target)) {
let i = typeString.indexOf(target) + target.length;
let depth = 1;
let inner = '';
while (i < typeString.length && depth > 0) {
if (typeString[i] === '<') depth++;
else if (typeString[i] === '>') depth--;
if (depth > 0) inner += typeString[i];
i++;
}
typeString = typeString.replace(`${target}${inner}>`, inner);
}
return typeString;
}
// Step 1: Flatten all .d.ts files (except index.d.ts if needed)
const dtsFiles = glob.sync(path.join(__dirname, 'dist/**/*.d.ts'));
for (const file of dtsFiles) {
const dtsLines = fs.readFileSync(file, 'utf8').split('\n');
if (path.basename(file) === 'index.d.ts') {
const strippedOfEnums = dtsLines.filter(
(line) => !line.includes('./enums/'),
);
fs.writeFileSync(file, strippedOfEnums.join('\n'));
continue;
}
const outputLines = [];
for (let i = 0; i < dtsLines.length; i++) {
const line = dtsLines[i];
const baseMatch = line.match(/declare const (\w+_base): (.+);/);
if (baseMatch) {
const [_, baseName, baseType] = baseMatch;
const classLine = dtsLines[i + 1] || '';
const classMatch = classLine.match(
/declare class (\w+) extends (\w+_base) \{/,
);
if (!classMatch || classMatch[2] !== baseName) {
outputLines.push(line);
continue;
}
const flatBaseName = baseName;
const flatClassName = classMatch[1];
const nestBaseName = `${flatClassName}Nest_base`;
const nestClassName = `${flatClassName}Nest`;
renamedNames.push(flatClassName);
const flattenedBaseType = stripNestjsType(baseType);
outputLines.push(`declare type ${flatBaseName} = ${flattenedBaseType};`);
const bodyLines = [];
let j = i + 2;
while (j < dtsLines.length && !dtsLines[j].startsWith('}')) {
const trimmed = dtsLines[j].trim();
if (trimmed) bodyLines.push(trimmed.replace(/;$/, ''));
j++;
}
const bodyStr = bodyLines.length
? '& {\n' + bodyLines.map((l) => ' ' + l + ';').join('\n') + '\n};'
: ';';
outputLines.push(
`export declare type ${flatClassName} = ${flatBaseName} ${bodyStr}`,
);
outputLines.push(`declare const ${nestBaseName}: ${baseType};`);
outputLines.push(
`export declare class ${nestClassName} extends ${nestBaseName} {`,
);
outputLines.push(...bodyLines.map((l) => ' ' + l + ';'));
outputLines.push('}');
i = j;
continue;
}
outputLines.push(line);
}
fs.writeFileSync(file, outputLines.join('\n'));
console.log(`✅ Flattened: ${file}`);
}
// Step 2: Patch JS files for runtime exports
const jsFiles = glob.sync(path.join(__dirname, 'dist/**/*.js'));
renamedNames.forEach((name) => {
const regex = new RegExp(`exports\\.${name} = ${name};`);
jsFiles.forEach((file) => {
const code = fs.readFileSync(file, 'utf8');
if (regex.test(code)) {
const appendLine = `\nexports.${name}Nest = ${name};\n`;
if (!code.includes(`exports.${name}Nest =`)) {
fs.appendFileSync(file, appendLine);
}
}
});
});
console.log('✅ JS runtime patching complete.');