ts-arc 1.1.22 → 1.1.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +7 -1
- package/dist/cli.js +7 -1
- package/dist/loader.js +233 -53
- package/package.json +3 -2
package/dist/bin.js
CHANGED
|
@@ -83,7 +83,9 @@ function findTsConfig(dir) {
|
|
|
83
83
|
var tsArcConfig = {
|
|
84
84
|
baseUrl: null,
|
|
85
85
|
paths: {},
|
|
86
|
-
tsconfigDir: null
|
|
86
|
+
tsconfigDir: null,
|
|
87
|
+
emitDecoratorMetadata: false,
|
|
88
|
+
experimentalDecorators: false
|
|
87
89
|
};
|
|
88
90
|
var tsconfigPath = findTsConfig(process.cwd());
|
|
89
91
|
if (tsconfigPath) {
|
|
@@ -94,6 +96,8 @@ if (tsconfigPath) {
|
|
|
94
96
|
tsArcConfig.baseUrl = baseUrlStr ? path.resolve(tsconfigDir, baseUrlStr) : null;
|
|
95
97
|
tsArcConfig.paths = compilerOptions.paths || {};
|
|
96
98
|
tsArcConfig.tsconfigDir = tsconfigDir;
|
|
99
|
+
tsArcConfig.emitDecoratorMetadata = compilerOptions.emitDecoratorMetadata || false;
|
|
100
|
+
tsArcConfig.experimentalDecorators = compilerOptions.experimentalDecorators || false;
|
|
97
101
|
}
|
|
98
102
|
function registerLoader() {
|
|
99
103
|
register(loaderPath, import.meta.url, { data: tsArcConfig });
|
|
@@ -108,6 +112,8 @@ async function setArcTsConfig(directory) {
|
|
|
108
112
|
tsArcConfig.baseUrl = baseUrlStr ? path.resolve(tsconfigDir, baseUrlStr) : null;
|
|
109
113
|
tsArcConfig.paths = compilerOptions.paths || {};
|
|
110
114
|
tsArcConfig.tsconfigDir = tsconfigDir;
|
|
115
|
+
tsArcConfig.emitDecoratorMetadata = compilerOptions.emitDecoratorMetadata || false;
|
|
116
|
+
tsArcConfig.experimentalDecorators = compilerOptions.experimentalDecorators || false;
|
|
111
117
|
}
|
|
112
118
|
}
|
|
113
119
|
async function loadModule(scriptUrl) {
|
package/dist/cli.js
CHANGED
|
@@ -89,7 +89,9 @@ function findTsConfig(dir) {
|
|
|
89
89
|
var tsArcConfig = {
|
|
90
90
|
baseUrl: null,
|
|
91
91
|
paths: {},
|
|
92
|
-
tsconfigDir: null
|
|
92
|
+
tsconfigDir: null,
|
|
93
|
+
emitDecoratorMetadata: false,
|
|
94
|
+
experimentalDecorators: false
|
|
93
95
|
};
|
|
94
96
|
var tsconfigPath = findTsConfig(process.cwd());
|
|
95
97
|
if (tsconfigPath) {
|
|
@@ -100,6 +102,8 @@ if (tsconfigPath) {
|
|
|
100
102
|
tsArcConfig.baseUrl = baseUrlStr ? path.resolve(tsconfigDir, baseUrlStr) : null;
|
|
101
103
|
tsArcConfig.paths = compilerOptions.paths || {};
|
|
102
104
|
tsArcConfig.tsconfigDir = tsconfigDir;
|
|
105
|
+
tsArcConfig.emitDecoratorMetadata = compilerOptions.emitDecoratorMetadata || false;
|
|
106
|
+
tsArcConfig.experimentalDecorators = compilerOptions.experimentalDecorators || false;
|
|
103
107
|
}
|
|
104
108
|
function registerLoader() {
|
|
105
109
|
register(loaderPath, import.meta.url, { data: tsArcConfig });
|
|
@@ -114,6 +118,8 @@ async function setArcTsConfig(directory) {
|
|
|
114
118
|
tsArcConfig.baseUrl = baseUrlStr ? path.resolve(tsconfigDir, baseUrlStr) : null;
|
|
115
119
|
tsArcConfig.paths = compilerOptions.paths || {};
|
|
116
120
|
tsArcConfig.tsconfigDir = tsconfigDir;
|
|
121
|
+
tsArcConfig.emitDecoratorMetadata = compilerOptions.emitDecoratorMetadata || false;
|
|
122
|
+
tsArcConfig.experimentalDecorators = compilerOptions.experimentalDecorators || false;
|
|
117
123
|
}
|
|
118
124
|
}
|
|
119
125
|
async function loadModule(scriptUrl2) {
|
package/dist/loader.js
CHANGED
|
@@ -5,12 +5,15 @@ import * as fs from "fs";
|
|
|
5
5
|
import * as path from "path";
|
|
6
6
|
import * as url from "url";
|
|
7
7
|
import { createRequire } from "module";
|
|
8
|
+
import { builtinModules } from "node:module";
|
|
8
9
|
var require2 = createRequire(import.meta.url);
|
|
9
10
|
var { transformSync } = require2("esbuild");
|
|
10
11
|
var config = {
|
|
11
12
|
baseUrl: null,
|
|
12
13
|
paths: {},
|
|
13
|
-
tsconfigDir: null
|
|
14
|
+
tsconfigDir: null,
|
|
15
|
+
emitDecoratorMetadata: false,
|
|
16
|
+
experimentalDecorators: false
|
|
14
17
|
};
|
|
15
18
|
function initialize(initContext) {
|
|
16
19
|
config = initContext;
|
|
@@ -43,6 +46,179 @@ function resolveLocalSync(baseDir, relativePath) {
|
|
|
43
46
|
async function resolveLocal(baseDir, relativePath) {
|
|
44
47
|
return resolveLocalSync(baseDir, relativePath);
|
|
45
48
|
}
|
|
49
|
+
function resolveBareSync(specifier, parentPath) {
|
|
50
|
+
const requireFromParent = createRequire(path.join(parentPath, "index.js"));
|
|
51
|
+
try {
|
|
52
|
+
const resolved = requireFromParent.resolve(specifier);
|
|
53
|
+
if (resolved === specifier && builtinModules.includes(specifier.replace(/^node:/, ""))) {
|
|
54
|
+
return `node:${specifier.replace(/^node:/, "")}`;
|
|
55
|
+
}
|
|
56
|
+
return url.pathToFileURL(resolved).href;
|
|
57
|
+
} catch (e) {
|
|
58
|
+
if (e.code === "MODULE_NOT_FOUND") {
|
|
59
|
+
throw Object.assign(new Error(`Cannot find module '${specifier}'`), { code: "ERR_MODULE_NOT_FOUND" });
|
|
60
|
+
}
|
|
61
|
+
throw e;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function getFormatSync(urlStr) {
|
|
65
|
+
const urlObj = new URL(urlStr);
|
|
66
|
+
if (urlObj.protocol === "node:") return "builtin";
|
|
67
|
+
if (urlObj.protocol !== "file:") throw new Error(`Unsupported protocol: ${urlObj.protocol}`);
|
|
68
|
+
const filePath = url.fileURLToPath(urlStr);
|
|
69
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
70
|
+
if (ext === ".wasm") return "wasm";
|
|
71
|
+
if (ext === ".json") return "json";
|
|
72
|
+
if (ext === ".node") return "addon";
|
|
73
|
+
if (ext === ".mjs") return "module";
|
|
74
|
+
if (ext === ".cjs") return "commonjs";
|
|
75
|
+
if (ext !== ".js") throw new Error(`Unknown file extension: ${ext}`);
|
|
76
|
+
let currentDir = path.dirname(filePath);
|
|
77
|
+
while (currentDir !== path.parse(currentDir).root) {
|
|
78
|
+
const pkgPath = path.join(currentDir, "package.json");
|
|
79
|
+
if (fs.existsSync(pkgPath)) {
|
|
80
|
+
const pkgContent = fs.readFileSync(pkgPath, "utf8");
|
|
81
|
+
const pkg = JSON.parse(pkgContent);
|
|
82
|
+
if (pkg.type === "module") return "module";
|
|
83
|
+
return "commonjs";
|
|
84
|
+
}
|
|
85
|
+
currentDir = path.dirname(currentDir);
|
|
86
|
+
}
|
|
87
|
+
return "commonjs";
|
|
88
|
+
}
|
|
89
|
+
function getRuntimeType(typeStr) {
|
|
90
|
+
typeStr = typeStr.replace(/\s+/g, "");
|
|
91
|
+
if (typeStr.includes("|") || typeStr.includes("&") || typeStr === "any" || typeStr === "unknown" || typeStr === "never") {
|
|
92
|
+
return "Object";
|
|
93
|
+
}
|
|
94
|
+
if (typeStr === "void") {
|
|
95
|
+
return "undefined";
|
|
96
|
+
}
|
|
97
|
+
if (typeStr.endsWith("[]")) {
|
|
98
|
+
return 'typeof Array === "undefined" ? Object : Array';
|
|
99
|
+
}
|
|
100
|
+
const genericMatch = typeStr.match(/^(\w+)<.*>$/);
|
|
101
|
+
if (genericMatch) {
|
|
102
|
+
const base = genericMatch[1];
|
|
103
|
+
return `typeof ${base} === "undefined" ? Object : ${base}`;
|
|
104
|
+
}
|
|
105
|
+
const mapped = {
|
|
106
|
+
"string": "String",
|
|
107
|
+
"number": "Number",
|
|
108
|
+
"boolean": "Boolean",
|
|
109
|
+
"bigint": "BigInt",
|
|
110
|
+
"symbol": "Symbol",
|
|
111
|
+
"undefined": "undefined",
|
|
112
|
+
"object": "Object",
|
|
113
|
+
"function": "Function"
|
|
114
|
+
};
|
|
115
|
+
const lower = typeStr.toLowerCase();
|
|
116
|
+
if (mapped[lower]) {
|
|
117
|
+
const val = mapped[lower];
|
|
118
|
+
if (val !== "undefined") {
|
|
119
|
+
return `typeof ${val} === "undefined" ? Object : ${val}`;
|
|
120
|
+
}
|
|
121
|
+
return val;
|
|
122
|
+
}
|
|
123
|
+
return `typeof ${typeStr} === "undefined" ? Object : ${typeStr}`;
|
|
124
|
+
}
|
|
125
|
+
function addMetadataDecorators(code) {
|
|
126
|
+
const lines = code.split("\n");
|
|
127
|
+
const newLines = [...lines];
|
|
128
|
+
const insertions = [];
|
|
129
|
+
let inClass = false;
|
|
130
|
+
let classDecoratorEnd = -1;
|
|
131
|
+
let classIndent = "";
|
|
132
|
+
let constructorParamTypes = [];
|
|
133
|
+
let currentDecorators = [];
|
|
134
|
+
for (let i = 0; i < lines.length; i++) {
|
|
135
|
+
const line = lines[i];
|
|
136
|
+
const trimLine = line.trim();
|
|
137
|
+
if (trimLine.startsWith("@")) {
|
|
138
|
+
currentDecorators.push(i);
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
if (trimLine.startsWith("class ") || trimLine.startsWith("export class ")) {
|
|
142
|
+
inClass = true;
|
|
143
|
+
constructorParamTypes = [];
|
|
144
|
+
classIndent = line.match(/^\s*/)?.[0] || "";
|
|
145
|
+
classDecoratorEnd = currentDecorators.length > 0 ? currentDecorators[currentDecorators.length - 1] + 1 : i;
|
|
146
|
+
currentDecorators = [];
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (inClass && trimLine.startsWith("}")) {
|
|
150
|
+
const metas = [];
|
|
151
|
+
if (constructorParamTypes.length > 0 || true) {
|
|
152
|
+
metas.push(`${classIndent}@__metadata("design:paramtypes", [${constructorParamTypes.join(", ")}])`);
|
|
153
|
+
}
|
|
154
|
+
if (metas.length > 0) {
|
|
155
|
+
insertions.push({ line: classDecoratorEnd, content: metas });
|
|
156
|
+
}
|
|
157
|
+
inClass = false;
|
|
158
|
+
currentDecorators = [];
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (inClass) {
|
|
162
|
+
const propMatch = trimLine.match(/^((?:public|private|protected|static|readonly)\s+)*(\w+)\s*:\s*([^;]+);$/);
|
|
163
|
+
if (propMatch && !trimLine.includes("(")) {
|
|
164
|
+
const typeStr = propMatch[3];
|
|
165
|
+
const runtimeType = getRuntimeType(typeStr);
|
|
166
|
+
const indent = line.match(/^\s*/)?.[0] || "";
|
|
167
|
+
const metadataLine = `${indent}@__metadata("design:type", ${runtimeType})`;
|
|
168
|
+
const insertLine = currentDecorators.length > 0 ? currentDecorators[currentDecorators.length - 1] + 1 : i;
|
|
169
|
+
insertions.push({ line: insertLine, content: [metadataLine] });
|
|
170
|
+
currentDecorators = [];
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
const methodMatch = trimLine.match(/^((?:public|private|protected|static|async)\s+)*(\w+)\s*\(([^)]*)\)\s*:\s*([^ {;]+)(;| \{)?$/);
|
|
174
|
+
if (methodMatch) {
|
|
175
|
+
const paramsStr = methodMatch[3];
|
|
176
|
+
const returnStr = methodMatch[4];
|
|
177
|
+
const paramTypes = [];
|
|
178
|
+
if (paramsStr) {
|
|
179
|
+
const params = paramsStr.split(",");
|
|
180
|
+
params.forEach((p) => {
|
|
181
|
+
const ptMatch = p.trim().match(/:\s*([^,]+)/);
|
|
182
|
+
const pt = ptMatch ? ptMatch[1].trim() : "Object";
|
|
183
|
+
paramTypes.push(getRuntimeType(pt));
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
const runtimeReturn = getRuntimeType(returnStr);
|
|
187
|
+
const indent = line.match(/^\s*/)?.[0] || "";
|
|
188
|
+
const metas = [
|
|
189
|
+
`${indent}@__metadata("design:type", Function)`,
|
|
190
|
+
`${indent}@__metadata("design:paramtypes", [${paramTypes.join(", ")}])`,
|
|
191
|
+
`${indent}@__metadata("design:returntype", ${runtimeReturn})`
|
|
192
|
+
];
|
|
193
|
+
const insertLine = currentDecorators.length > 0 ? currentDecorators[currentDecorators.length - 1] + 1 : i;
|
|
194
|
+
insertions.push({ line: insertLine, content: metas });
|
|
195
|
+
currentDecorators = [];
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
const ctorMatch = trimLine.match(/^(?:(public|private|protected)\s+)?constructor\s*\(\s*(.*)\s*\)/);
|
|
199
|
+
if (ctorMatch) {
|
|
200
|
+
const paramsStr = ctorMatch[2];
|
|
201
|
+
constructorParamTypes = [];
|
|
202
|
+
if (paramsStr) {
|
|
203
|
+
const params = paramsStr.split(",");
|
|
204
|
+
params.forEach((p) => {
|
|
205
|
+
const paramMatch = p.trim().match(/^.*?:\s*([^,]+)/);
|
|
206
|
+
const paramType = paramMatch ? paramMatch[1].trim() : "Object";
|
|
207
|
+
constructorParamTypes.push(getRuntimeType(paramType));
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
currentDecorators = [];
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
currentDecorators = [];
|
|
215
|
+
}
|
|
216
|
+
insertions.sort((a, b) => b.line - a.line);
|
|
217
|
+
for (const ins of insertions) {
|
|
218
|
+
newLines.splice(ins.line, 0, ...ins.content);
|
|
219
|
+
}
|
|
220
|
+
return newLines.join("\n");
|
|
221
|
+
}
|
|
46
222
|
async function resolve2(specifier, context, nextResolve) {
|
|
47
223
|
let parentPath = process.cwd();
|
|
48
224
|
if (context.parentURL) {
|
|
@@ -52,8 +228,7 @@ async function resolve2(specifier, context, nextResolve) {
|
|
|
52
228
|
const filePath = url.fileURLToPath(specifier);
|
|
53
229
|
const dir = path.dirname(filePath);
|
|
54
230
|
const baseName = path.basename(filePath);
|
|
55
|
-
const
|
|
56
|
-
const resolved = await resolveLocal(dir, relative);
|
|
231
|
+
const resolved = await resolveLocal(dir, baseName);
|
|
57
232
|
return { ...resolved, shortCircuit: true };
|
|
58
233
|
}
|
|
59
234
|
const isPathLike = specifier.startsWith(".") || specifier.startsWith("/");
|
|
@@ -77,8 +252,8 @@ async function resolve2(specifier, context, nextResolve) {
|
|
|
77
252
|
const mapped = isWildcard ? target.replace(/\*/g, capture) : target;
|
|
78
253
|
if (effectiveBase) {
|
|
79
254
|
try {
|
|
80
|
-
const
|
|
81
|
-
return { ...
|
|
255
|
+
const resolved = await resolveLocal(effectiveBase, mapped);
|
|
256
|
+
return { ...resolved, shortCircuit: true };
|
|
82
257
|
} catch (error) {
|
|
83
258
|
if (error.code !== "ERR_MODULE_NOT_FOUND") {
|
|
84
259
|
throw error;
|
|
@@ -90,63 +265,70 @@ async function resolve2(specifier, context, nextResolve) {
|
|
|
90
265
|
}
|
|
91
266
|
if (effectiveBase) {
|
|
92
267
|
try {
|
|
93
|
-
const
|
|
94
|
-
return { ...
|
|
268
|
+
const resolved = await resolveLocal(effectiveBase, specifier);
|
|
269
|
+
return { ...resolved, shortCircuit: true };
|
|
95
270
|
} catch (error) {
|
|
96
271
|
if (error.code !== "ERR_MODULE_NOT_FOUND") {
|
|
97
272
|
throw error;
|
|
98
273
|
}
|
|
99
274
|
}
|
|
100
275
|
}
|
|
101
|
-
const
|
|
102
|
-
return {
|
|
276
|
+
const resolvedUrl = resolveBareSync(specifier, parentPath);
|
|
277
|
+
return { url: resolvedUrl, shortCircuit: true };
|
|
103
278
|
}
|
|
104
279
|
}
|
|
105
280
|
async function load(urlStr, context, nextLoad) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
}
|
|
109
|
-
const esbuildLoader = urlStr.endsWith(".tsx") ? "tsx" : "ts";
|
|
110
|
-
const filePath = url.fileURLToPath(urlStr);
|
|
111
|
-
const rawSource = fs.readFileSync(filePath, "utf8");
|
|
112
|
-
const { code } = transformSync(rawSource, {
|
|
113
|
-
loader: esbuildLoader,
|
|
114
|
-
format: "esm",
|
|
115
|
-
target: `node${process.versions.node}`,
|
|
116
|
-
sourcemap: "inline",
|
|
117
|
-
sourcefile: filePath,
|
|
118
|
-
banner: `
|
|
119
|
-
import { createRequire } from 'module';
|
|
120
|
-
const require = createRequire(import.meta.url);`
|
|
281
|
+
return loadSync(urlStr, context, () => {
|
|
282
|
+
throw new Error("Chaining not supported");
|
|
121
283
|
});
|
|
122
|
-
return {
|
|
123
|
-
format: "module",
|
|
124
|
-
source: code,
|
|
125
|
-
shortCircuit: true
|
|
126
|
-
};
|
|
127
284
|
}
|
|
128
285
|
function loadSync(urlStr, context, nextLoadSync) {
|
|
129
|
-
if (
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
format: "esm",
|
|
138
|
-
target: `node${process.versions.node}`,
|
|
139
|
-
sourcemap: "inline",
|
|
140
|
-
sourcefile: filePath,
|
|
141
|
-
banner: `
|
|
286
|
+
if (urlStr.endsWith(".ts") || urlStr.endsWith(".tsx")) {
|
|
287
|
+
const esbuildLoader = urlStr.endsWith(".tsx") ? "tsx" : "ts";
|
|
288
|
+
const filePath = url.fileURLToPath(urlStr);
|
|
289
|
+
let rawSource = fs.readFileSync(filePath, "utf8");
|
|
290
|
+
if (config.emitDecoratorMetadata) {
|
|
291
|
+
rawSource = addMetadataDecorators(rawSource);
|
|
292
|
+
}
|
|
293
|
+
let banner = `
|
|
142
294
|
import { createRequire } from 'module';
|
|
143
|
-
const require = createRequire(import.meta.url)
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
295
|
+
const require = createRequire(import.meta.url);
|
|
296
|
+
`;
|
|
297
|
+
if (config.emitDecoratorMetadata) {
|
|
298
|
+
banner += `
|
|
299
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
300
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
301
|
+
};
|
|
302
|
+
`;
|
|
303
|
+
}
|
|
304
|
+
const transformOptions = {
|
|
305
|
+
loader: esbuildLoader,
|
|
306
|
+
format: "esm",
|
|
307
|
+
target: `node${process.versions.node}`,
|
|
308
|
+
sourcemap: "inline",
|
|
309
|
+
sourcefile: filePath,
|
|
310
|
+
banner,
|
|
311
|
+
tsconfigRaw: {
|
|
312
|
+
compilerOptions: {
|
|
313
|
+
experimentalDecorators: config.experimentalDecorators
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
const { code } = transformSync(rawSource, transformOptions);
|
|
318
|
+
return {
|
|
319
|
+
format: "module",
|
|
320
|
+
source: code,
|
|
321
|
+
shortCircuit: true
|
|
322
|
+
};
|
|
323
|
+
} else {
|
|
324
|
+
const format = getFormatSync(urlStr);
|
|
325
|
+
let source;
|
|
326
|
+
if (format !== "builtin") {
|
|
327
|
+
const filePath = url.fileURLToPath(urlStr);
|
|
328
|
+
source = fs.readFileSync(filePath);
|
|
329
|
+
}
|
|
330
|
+
return { format, source, shortCircuit: true };
|
|
331
|
+
}
|
|
150
332
|
}
|
|
151
333
|
function resolveSync(specifier, context) {
|
|
152
334
|
let parentPath = process.cwd();
|
|
@@ -202,10 +384,8 @@ function resolveSync(specifier, context) {
|
|
|
202
384
|
}
|
|
203
385
|
}
|
|
204
386
|
}
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
{ code: "ERR_MODULE_NOT_FOUND" }
|
|
208
|
-
);
|
|
387
|
+
const resolvedUrl = resolveBareSync(specifier, parentPath);
|
|
388
|
+
return { url: resolvedUrl, shortCircuit: true };
|
|
209
389
|
}
|
|
210
390
|
export {
|
|
211
391
|
initialize,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ts-arc",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.24",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A simple typescript runtime.",
|
|
6
6
|
"main": "dist/bin.js",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"dist"
|
|
21
21
|
],
|
|
22
22
|
"devDependencies": {
|
|
23
|
-
"@types/node": "^24.9.1"
|
|
23
|
+
"@types/node": "^24.9.1",
|
|
24
|
+
"reflect-metadata": "^0.2.2"
|
|
24
25
|
}
|
|
25
26
|
}
|