ts-arc 1.1.23 → 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 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
@@ -11,7 +11,9 @@ var { transformSync } = require2("esbuild");
11
11
  var config = {
12
12
  baseUrl: null,
13
13
  paths: {},
14
- tsconfigDir: null
14
+ tsconfigDir: null,
15
+ emitDecoratorMetadata: false,
16
+ experimentalDecorators: false
15
17
  };
16
18
  function initialize(initContext) {
17
19
  config = initContext;
@@ -84,6 +86,139 @@ function getFormatSync(urlStr) {
84
86
  }
85
87
  return "commonjs";
86
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
+ }
87
222
  async function resolve2(specifier, context, nextResolve) {
88
223
  let parentPath = process.cwd();
89
224
  if (context.parentURL) {
@@ -151,17 +286,35 @@ function loadSync(urlStr, context, nextLoadSync) {
151
286
  if (urlStr.endsWith(".ts") || urlStr.endsWith(".tsx")) {
152
287
  const esbuildLoader = urlStr.endsWith(".tsx") ? "tsx" : "ts";
153
288
  const filePath = url.fileURLToPath(urlStr);
154
- const rawSource = fs.readFileSync(filePath, "utf8");
155
- const { code } = transformSync(rawSource, {
289
+ let rawSource = fs.readFileSync(filePath, "utf8");
290
+ if (config.emitDecoratorMetadata) {
291
+ rawSource = addMetadataDecorators(rawSource);
292
+ }
293
+ let banner = `
294
+ import { createRequire } from 'module';
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 = {
156
305
  loader: esbuildLoader,
157
306
  format: "esm",
158
307
  target: `node${process.versions.node}`,
159
308
  sourcemap: "inline",
160
309
  sourcefile: filePath,
161
- banner: `
162
- import { createRequire } from 'module';
163
- const require = createRequire(import.meta.url);`
164
- });
310
+ banner,
311
+ tsconfigRaw: {
312
+ compilerOptions: {
313
+ experimentalDecorators: config.experimentalDecorators
314
+ }
315
+ }
316
+ };
317
+ const { code } = transformSync(rawSource, transformOptions);
165
318
  return {
166
319
  format: "module",
167
320
  source: code,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ts-arc",
3
- "version": "1.1.23",
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
  }