@atscript/typescript 0.1.87 → 0.1.89
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/cli.cjs +427 -389
- package/dist/index.cjs +4 -5
- package/dist/index.mjs +1 -2
- package/dist/{json-schema-3mti4G4J.cjs → json-schema-DXEiCfe1.cjs} +206 -97
- package/dist/{json-schema-B64qclVa.mjs → json-schema-DycaD0Rm.mjs} +207 -98
- package/dist/{plugin-CYzZm3rk.mjs → plugin-BOoquMkD.mjs} +117 -152
- package/dist/{plugin-CZ5g5D9I.cjs → plugin-DMBkdYCf.cjs} +180 -211
- package/dist/test-utils.cjs +16 -9
- package/dist/test-utils.mjs +9 -3
- package/dist/utils.cjs +176 -106
- package/dist/utils.mjs +153 -83
- package/package.json +2 -2
package/dist/cli.cjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
//#region rolldown:runtime
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
3
2
|
var __create = Object.create;
|
|
4
3
|
var __defProp = Object.defineProperty;
|
|
5
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
@@ -7,12 +6,16 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
|
7
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
8
|
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function")
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
+
key = keys[i];
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
13
|
+
__defProp(to, key, {
|
|
14
|
+
get: ((k) => from[k]).bind(null, key),
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
}
|
|
16
19
|
}
|
|
17
20
|
return to;
|
|
18
21
|
};
|
|
@@ -22,14 +25,15 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
22
25
|
}) : target, mod));
|
|
23
26
|
|
|
24
27
|
//#endregion
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
let _moostjs_event_cli = require("@moostjs/event-cli");
|
|
29
|
+
let _atscript_core = require("@atscript/core");
|
|
30
|
+
let moost = require("moost");
|
|
31
|
+
let fs = require("fs");
|
|
32
|
+
let path = require("path");
|
|
33
|
+
path = __toESM(path);
|
|
34
|
+
let node_module = require("node:module");
|
|
35
|
+
let node_readline = require("node:readline");
|
|
36
|
+
let node_url = require("node:url");
|
|
33
37
|
|
|
34
38
|
//#region packages/typescript/src/codegen/code-printer.ts
|
|
35
39
|
function _define_property$7(obj, key, value) {
|
|
@@ -39,7 +43,7 @@ function _define_property$7(obj, key, value) {
|
|
|
39
43
|
configurable: true,
|
|
40
44
|
writable: true
|
|
41
45
|
});
|
|
42
|
-
else obj[key] = value;
|
|
46
|
+
else obj[key] = value;
|
|
43
47
|
return obj;
|
|
44
48
|
}
|
|
45
49
|
var CodePrinter = class {
|
|
@@ -100,7 +104,7 @@ var CodePrinter = class {
|
|
|
100
104
|
* Return the entire code as a string. Removes any half-finished current line if empty.
|
|
101
105
|
*/ toString() {
|
|
102
106
|
if (this.currentLine.trim() !== "") this.lines.push(this.currentLine);
|
|
103
|
-
else if (this.currentLine.length > 0) this.lines.push(this.currentLine);
|
|
107
|
+
else if (this.currentLine.length > 0) this.lines.push(this.currentLine);
|
|
104
108
|
return this.lines.join("\n");
|
|
105
109
|
}
|
|
106
110
|
doBlock(pair, withNewLine) {
|
|
@@ -118,7 +122,7 @@ else if (this.currentLine.length > 0) this.lines.push(this.currentLine);
|
|
|
118
122
|
const closing = this.blockStack.pop();
|
|
119
123
|
this.unindent();
|
|
120
124
|
if (withNewLine) this.writeln(closing);
|
|
121
|
-
else this.write(closing);
|
|
125
|
+
else this.write(closing);
|
|
122
126
|
return this;
|
|
123
127
|
}
|
|
124
128
|
indentString() {
|
|
@@ -142,7 +146,7 @@ function _define_property$6(obj, key, value) {
|
|
|
142
146
|
configurable: true,
|
|
143
147
|
writable: true
|
|
144
148
|
});
|
|
145
|
-
else obj[key] = value;
|
|
149
|
+
else obj[key] = value;
|
|
146
150
|
return obj;
|
|
147
151
|
}
|
|
148
152
|
var BaseRenderer = class extends CodePrinter {
|
|
@@ -160,21 +164,21 @@ var BaseRenderer = class extends CodePrinter {
|
|
|
160
164
|
renderInterface(node) {}
|
|
161
165
|
renderType(node) {}
|
|
162
166
|
renderAnnotate(node) {}
|
|
163
|
-
transformFromPath(path
|
|
164
|
-
return `${path
|
|
167
|
+
transformFromPath(path) {
|
|
168
|
+
return `${path}.as`;
|
|
165
169
|
}
|
|
166
170
|
renderImport(node) {
|
|
167
171
|
const def = node.getDefinition();
|
|
168
172
|
const refs = [];
|
|
169
173
|
const from = this.transformFromPath(node.token("path").text);
|
|
170
174
|
let isUnusedImport = true;
|
|
171
|
-
if ((0,
|
|
172
|
-
for (const child of def.unwrap()) if ((0,
|
|
173
|
-
const node
|
|
174
|
-
refs.push(node
|
|
175
|
+
if ((0, _atscript_core.isGroup)(def)) {
|
|
176
|
+
for (const child of def.unwrap()) if ((0, _atscript_core.isRef)(child) && !this.unused.has(child.id)) {
|
|
177
|
+
const node = child;
|
|
178
|
+
refs.push(node.id);
|
|
175
179
|
isUnusedImport = false;
|
|
176
180
|
}
|
|
177
|
-
} else if ((0,
|
|
181
|
+
} else if ((0, _atscript_core.isRef)(def) && !this.unused.has(def.id)) {
|
|
178
182
|
refs.push(def.id);
|
|
179
183
|
isUnusedImport = false;
|
|
180
184
|
}
|
|
@@ -182,22 +186,18 @@ var BaseRenderer = class extends CodePrinter {
|
|
|
182
186
|
}
|
|
183
187
|
renderNode(node) {
|
|
184
188
|
switch (node.entity) {
|
|
185
|
-
case "interface":
|
|
189
|
+
case "interface":
|
|
186
190
|
this.renderInterface(node);
|
|
187
191
|
break;
|
|
188
|
-
|
|
189
|
-
case "type": {
|
|
192
|
+
case "type":
|
|
190
193
|
this.renderType(node);
|
|
191
194
|
break;
|
|
192
|
-
|
|
193
|
-
case "import": {
|
|
195
|
+
case "import":
|
|
194
196
|
this.renderImport(node);
|
|
195
197
|
break;
|
|
196
|
-
|
|
197
|
-
case "annotate": {
|
|
198
|
+
case "annotate":
|
|
198
199
|
this.renderAnnotate(node);
|
|
199
200
|
break;
|
|
200
|
-
}
|
|
201
201
|
default: break;
|
|
202
202
|
}
|
|
203
203
|
}
|
|
@@ -209,7 +209,13 @@ var BaseRenderer = class extends CodePrinter {
|
|
|
209
209
|
//#endregion
|
|
210
210
|
//#region packages/typescript/src/codegen/utils.ts
|
|
211
211
|
const validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
|
|
212
|
-
|
|
212
|
+
/**
|
|
213
|
+
* Wraps a property name in double quotes if it's not a valid identifier (contains special chars, etc.).
|
|
214
|
+
*
|
|
215
|
+
* Examples:
|
|
216
|
+
* - "validName" => "validName"
|
|
217
|
+
* - "some-prop" => "\"some-prop\""
|
|
218
|
+
*/ function wrapProp(name) {
|
|
213
219
|
if (!validIdentifier.test(name)) return `"${escapeQuotes(name)}"`;
|
|
214
220
|
return name;
|
|
215
221
|
}
|
|
@@ -226,7 +232,7 @@ function _define_property$5(obj, key, value) {
|
|
|
226
232
|
configurable: true,
|
|
227
233
|
writable: true
|
|
228
234
|
});
|
|
229
|
-
else obj[key] = value;
|
|
235
|
+
else obj[key] = value;
|
|
230
236
|
return obj;
|
|
231
237
|
}
|
|
232
238
|
var TypeRenderer = class TypeRenderer extends BaseRenderer {
|
|
@@ -255,8 +261,8 @@ var TypeRenderer = class TypeRenderer extends BaseRenderer {
|
|
|
255
261
|
this.write("unknown");
|
|
256
262
|
return;
|
|
257
263
|
}
|
|
258
|
-
if ((0,
|
|
259
|
-
if ((0,
|
|
264
|
+
if ((0, _atscript_core.isStructure)(def)) return this.renderStructure(def);
|
|
265
|
+
if ((0, _atscript_core.isGroup)(def)) {
|
|
260
266
|
const tuple = def.entity === "tuple";
|
|
261
267
|
const operator = tuple ? ", " : ` ${def.op} `;
|
|
262
268
|
const children = def.unwrap();
|
|
@@ -269,14 +275,14 @@ var TypeRenderer = class TypeRenderer extends BaseRenderer {
|
|
|
269
275
|
}
|
|
270
276
|
return this.write(tuple ? "]" : hasSubgroup ? ")" : "");
|
|
271
277
|
}
|
|
272
|
-
if ((0,
|
|
278
|
+
if ((0, _atscript_core.isConst)(def)) {
|
|
273
279
|
const name = def.token("identifier")?.type === "number" ? def.id : `"${escapeQuotes(def.id)}"`;
|
|
274
280
|
return this.write(name);
|
|
275
281
|
}
|
|
276
|
-
if ((0,
|
|
282
|
+
if ((0, _atscript_core.isRef)(def)) {
|
|
277
283
|
const node = def;
|
|
278
284
|
const unwound = this.doc.unwindType(node.id, node.chain);
|
|
279
|
-
if ((0,
|
|
285
|
+
if ((0, _atscript_core.isPrimitive)(unwound?.def)) {
|
|
280
286
|
this.write(renderPrimitiveTypeDef(unwound.def.config.type));
|
|
281
287
|
if (node.hasChain) this.write(` /* ${node.chain.map((c) => c.text).join(".")} */`);
|
|
282
288
|
return;
|
|
@@ -285,21 +291,20 @@ var TypeRenderer = class TypeRenderer extends BaseRenderer {
|
|
|
285
291
|
for (const c of node.chain) name += `["${escapeQuotes(c.text)}"]`;
|
|
286
292
|
return this.write(name);
|
|
287
293
|
}
|
|
288
|
-
if ((0,
|
|
289
|
-
const
|
|
290
|
-
const def2 = node.getDefinition();
|
|
294
|
+
if ((0, _atscript_core.isArray)(def)) {
|
|
295
|
+
const def2 = def.getDefinition();
|
|
291
296
|
const isGrp = def2?.entity === "group";
|
|
292
297
|
if (isGrp) this.write("(");
|
|
293
298
|
this.renderTypeDef(def2);
|
|
294
299
|
if (isGrp) this.write(")");
|
|
295
300
|
return this.write("[]");
|
|
296
301
|
}
|
|
297
|
-
if ((0,
|
|
302
|
+
if ((0, _atscript_core.isPrimitive)(def)) return this.write(renderPrimitiveTypeDef(def.config.type));
|
|
298
303
|
}
|
|
299
304
|
renderStructure(struct, asClass, interfaceNode, filterProps) {
|
|
300
305
|
this.blockln("{}");
|
|
301
306
|
const patterns = [];
|
|
302
|
-
const propsDefs = new Set();
|
|
307
|
+
const propsDefs = /* @__PURE__ */ new Set();
|
|
303
308
|
for (const prop of struct.props.values()) {
|
|
304
309
|
if (filterProps?.has(prop.id)) continue;
|
|
305
310
|
if (prop.token("identifier")?.pattern) {
|
|
@@ -366,14 +371,14 @@ var TypeRenderer = class TypeRenderer extends BaseRenderer {
|
|
|
366
371
|
let firstParentProps;
|
|
367
372
|
if (firstParentUnwound?.def) {
|
|
368
373
|
let fpDef = firstParentUnwound.def;
|
|
369
|
-
if ((0,
|
|
374
|
+
if ((0, _atscript_core.isInterface)(fpDef)) {
|
|
370
375
|
if (fpDef.hasExtends) {
|
|
371
376
|
const fpResolved = firstParentUnwound.doc.resolveInterfaceExtends(fpDef);
|
|
372
|
-
if (fpResolved && (0,
|
|
377
|
+
if (fpResolved && (0, _atscript_core.isStructure)(fpResolved)) firstParentProps = fpResolved.props;
|
|
373
378
|
}
|
|
374
379
|
if (!firstParentProps) fpDef = fpDef.getDefinition() || fpDef;
|
|
375
380
|
}
|
|
376
|
-
if (!firstParentProps && (0,
|
|
381
|
+
if (!firstParentProps && (0, _atscript_core.isStructure)(fpDef)) firstParentProps = fpDef.props;
|
|
377
382
|
}
|
|
378
383
|
this.renderStructure(resolved, node.id, node, firstParentProps);
|
|
379
384
|
} else this.writeln("{}");
|
|
@@ -381,7 +386,7 @@ var TypeRenderer = class TypeRenderer extends BaseRenderer {
|
|
|
381
386
|
this.write(`class ${node.id} `);
|
|
382
387
|
const struct = node.getDefinition();
|
|
383
388
|
if (struct?.entity === "structure") this.renderStructure(struct, node.id, node);
|
|
384
|
-
else this.writeln("{}");
|
|
389
|
+
else this.writeln("{}");
|
|
385
390
|
}
|
|
386
391
|
this.writeln();
|
|
387
392
|
}
|
|
@@ -421,12 +426,12 @@ else this.writeln("{}");
|
|
|
421
426
|
let typeDef = "TAtscriptTypeDef";
|
|
422
427
|
if (inputDef) {
|
|
423
428
|
let realDef = inputDef;
|
|
424
|
-
if ((0,
|
|
429
|
+
if ((0, _atscript_core.isRef)(inputDef)) realDef = this.doc.unwindType(inputDef.id, inputDef.chain)?.def || realDef;
|
|
425
430
|
realDef = this.doc.mergeIntersection(realDef);
|
|
426
|
-
if ((0,
|
|
427
|
-
else if ((0,
|
|
428
|
-
else if ((0,
|
|
429
|
-
else if ((0,
|
|
431
|
+
if ((0, _atscript_core.isStructure)(realDef) || (0, _atscript_core.isInterface)(realDef)) typeDef = `TAtscriptTypeObject<keyof ${name}, ${name}>`;
|
|
432
|
+
else if ((0, _atscript_core.isGroup)(realDef)) typeDef = `TAtscriptTypeComplex<${name}>`;
|
|
433
|
+
else if ((0, _atscript_core.isArray)(realDef)) typeDef = `TAtscriptTypeArray<${name}>`;
|
|
434
|
+
else if ((0, _atscript_core.isPrimitive)(realDef)) typeDef = `TAtscriptTypeFinal<${name}>`;
|
|
430
435
|
}
|
|
431
436
|
this.writeln(`const __is_atscript_annotated_type: true`);
|
|
432
437
|
this.writeln(`const type: ${typeDef}`);
|
|
@@ -462,12 +467,12 @@ else if ((0, __atscript_core.isPrimitive)(realDef)) typeDef = `TAtscriptTypeFina
|
|
|
462
467
|
* not individually queryable)
|
|
463
468
|
* - **Leaf fields** → their original TypeScript type
|
|
464
469
|
*/ renderFlat(node) {
|
|
465
|
-
this.renderFlatMap("__flat", (0,
|
|
470
|
+
this.renderFlatMap("__flat", (0, _atscript_core.flattenInterfaceNode)(this.doc, node));
|
|
466
471
|
}
|
|
467
472
|
/**
|
|
468
473
|
* Renders the `static __ownProps` property — table-owned fields only (no nav props).
|
|
469
474
|
*/ renderOwnProps(node) {
|
|
470
|
-
this.renderFlatMap("__ownProps", (0,
|
|
475
|
+
this.renderFlatMap("__ownProps", (0, _atscript_core.flattenInterfaceNode)(this.doc, node, { skipNavProps: true }), {
|
|
471
476
|
leadingNewline: true,
|
|
472
477
|
trailingNewline: true
|
|
473
478
|
});
|
|
@@ -484,21 +489,20 @@ else if ((0, __atscript_core.isPrimitive)(realDef)) typeDef = `TAtscriptTypeFina
|
|
|
484
489
|
if (opts?.leadingNewline) this.writeln();
|
|
485
490
|
this.write(`static ${propName}: `);
|
|
486
491
|
this.blockln("{}");
|
|
487
|
-
for (const [path
|
|
488
|
-
this.write(`"${escapeQuotes(path
|
|
492
|
+
for (const [path, descriptor] of flatMap) {
|
|
493
|
+
this.write(`"${escapeQuotes(path)}"`);
|
|
489
494
|
if (descriptor.optional) this.write("?");
|
|
490
495
|
this.write(": ");
|
|
491
496
|
if (descriptor.intermediate) this.writeln("never");
|
|
492
|
-
else if (descriptor.dbJson) this.writeln("string");
|
|
493
|
-
else {
|
|
497
|
+
else if (descriptor.dbJson) this.writeln("string");
|
|
498
|
+
else {
|
|
494
499
|
const originalDef = descriptor.propNode?.getDefinition();
|
|
495
|
-
const defToRender = originalDef && !((0,
|
|
496
|
-
|
|
497
|
-
renderedDef.split("\n").forEach((l) => this.writeln(l));
|
|
500
|
+
const defToRender = originalDef && !((0, _atscript_core.isGroup)(descriptor.def) && descriptor.def !== originalDef) ? originalDef : descriptor.def;
|
|
501
|
+
this.renderTypeDefString(defToRender).split("\n").forEach((l) => this.writeln(l));
|
|
498
502
|
}
|
|
499
503
|
}
|
|
500
504
|
if (opts?.trailingNewline) this.popln();
|
|
501
|
-
else this.pop();
|
|
505
|
+
else this.pop();
|
|
502
506
|
}
|
|
503
507
|
/**
|
|
504
508
|
* Renders the `static __navProps` property — a map of navigation property names
|
|
@@ -510,12 +514,12 @@ else this.pop();
|
|
|
510
514
|
let struct;
|
|
511
515
|
if (node.hasExtends) struct = this.doc.resolveInterfaceExtends(node);
|
|
512
516
|
if (!struct) struct = node.getDefinition();
|
|
513
|
-
if (!struct || !(0,
|
|
517
|
+
if (!struct || !(0, _atscript_core.isStructure)(struct)) return;
|
|
514
518
|
const structNode = struct;
|
|
515
519
|
const navProps = [];
|
|
516
520
|
for (const [name, prop] of structNode.props) {
|
|
517
521
|
if (prop.token("identifier")?.pattern) continue;
|
|
518
|
-
if ((0,
|
|
522
|
+
if ((0, _atscript_core.hasNavPropAnnotation)(prop)) navProps.push({
|
|
519
523
|
name,
|
|
520
524
|
prop
|
|
521
525
|
});
|
|
@@ -529,10 +533,8 @@ else this.pop();
|
|
|
529
533
|
if (prop.token("optional")) this.write("?");
|
|
530
534
|
this.write(": ");
|
|
531
535
|
const propDef = prop.getDefinition();
|
|
532
|
-
if (propDef)
|
|
533
|
-
|
|
534
|
-
renderedDef.split("\n").forEach((l) => this.writeln(l));
|
|
535
|
-
} else this.writeln("unknown");
|
|
536
|
+
if (propDef) this.renderTypeDefString(propDef).split("\n").forEach((l) => this.writeln(l));
|
|
537
|
+
else this.writeln("unknown");
|
|
536
538
|
}
|
|
537
539
|
this.popln();
|
|
538
540
|
}
|
|
@@ -541,10 +543,10 @@ else this.pop();
|
|
|
541
543
|
let struct;
|
|
542
544
|
if (node.hasExtends) struct = this.doc.resolveInterfaceExtends(node);
|
|
543
545
|
if (!struct) struct = node.getDefinition();
|
|
544
|
-
if (!struct || !(0,
|
|
546
|
+
if (!struct || !(0, _atscript_core.isStructure)(struct)) return;
|
|
545
547
|
const structNode = struct;
|
|
546
548
|
const pkProps = [];
|
|
547
|
-
const uniqueByIndex = new Map();
|
|
549
|
+
const uniqueByIndex = /* @__PURE__ */ new Map();
|
|
548
550
|
for (const [name, prop] of structNode.props) {
|
|
549
551
|
if (prop.token("identifier")?.pattern) continue;
|
|
550
552
|
if (isMongoCollection && name === "_id") continue;
|
|
@@ -578,7 +580,7 @@ else this.pop();
|
|
|
578
580
|
mongoIdType ?? (mongoIdType = "string");
|
|
579
581
|
}
|
|
580
582
|
const uniqueTypes = [];
|
|
581
|
-
const seenTypes = new Set();
|
|
583
|
+
const seenTypes = /* @__PURE__ */ new Set();
|
|
582
584
|
for (const { prop } of uniqueProps) {
|
|
583
585
|
const rendered = this.renderTypeDefString(prop.getDefinition()).trim();
|
|
584
586
|
if (!seenTypes.has(rendered)) {
|
|
@@ -589,8 +591,8 @@ else this.pop();
|
|
|
589
591
|
this.writeln();
|
|
590
592
|
const uniqueSuffix = uniqueTypes.length > 0 ? ` | ${uniqueTypes.join(" | ")}` : "";
|
|
591
593
|
if (pkProps.length === 0 && !isMongoCollection) this.writeln(`static __pk: ${uniqueTypes.join(" | ")}`);
|
|
592
|
-
else if (pkProps.length === 0) this.writeln(`static __pk: ${mongoIdType}${uniqueSuffix}`);
|
|
593
|
-
else if (pkProps.length === 1) {
|
|
594
|
+
else if (pkProps.length === 0) this.writeln(`static __pk: ${mongoIdType}${uniqueSuffix}`);
|
|
595
|
+
else if (pkProps.length === 1) {
|
|
594
596
|
this.write("static __pk: ");
|
|
595
597
|
if (isMongoCollection) this.write(`${mongoIdType} | `);
|
|
596
598
|
const renderedDef = this.renderTypeDefString(pkProps[0].prop.getDefinition()).trim();
|
|
@@ -601,8 +603,7 @@ else if (pkProps.length === 1) {
|
|
|
601
603
|
this.blockln("{}");
|
|
602
604
|
for (const { name, prop } of pkProps) {
|
|
603
605
|
this.write(wrapProp(name), ": ");
|
|
604
|
-
|
|
605
|
-
renderedDef.split("\n").forEach((l) => this.writeln(l));
|
|
606
|
+
this.renderTypeDefString(prop.getDefinition()).split("\n").forEach((l) => this.writeln(l));
|
|
606
607
|
}
|
|
607
608
|
this.pop();
|
|
608
609
|
this.writeln(uniqueSuffix);
|
|
@@ -612,7 +613,7 @@ else if (pkProps.length === 1) {
|
|
|
612
613
|
let struct;
|
|
613
614
|
if (node.hasExtends) struct = this.doc.resolveInterfaceExtends(node);
|
|
614
615
|
if (!struct) struct = node.getDefinition();
|
|
615
|
-
if (!struct || !(0,
|
|
616
|
+
if (!struct || !(0, _atscript_core.isStructure)(struct)) return;
|
|
616
617
|
const structNode = struct;
|
|
617
618
|
const dims = [];
|
|
618
619
|
const measures = [];
|
|
@@ -627,18 +628,16 @@ else if (pkProps.length === 1) {
|
|
|
627
628
|
if (measures.length > 0) this.writeln(`static __measure: ${measures.map((m) => `"${escapeQuotes(m)}"`).join(" | ")}`);
|
|
628
629
|
}
|
|
629
630
|
phantomPropType(def) {
|
|
630
|
-
if (!def) return
|
|
631
|
-
if ((0,
|
|
632
|
-
if ((0,
|
|
631
|
+
if (!def) return;
|
|
632
|
+
if ((0, _atscript_core.isPrimitive)(def) && def.config.type === "phantom") return def.id;
|
|
633
|
+
if ((0, _atscript_core.isRef)(def)) {
|
|
633
634
|
const ref = def;
|
|
634
635
|
const unwound = this.doc.unwindType(ref.id, ref.chain)?.def;
|
|
635
|
-
if ((0,
|
|
636
|
+
if ((0, _atscript_core.isPrimitive)(unwound) && unwound.config.type === "phantom") return ref.hasChain ? `${ref.id}.${ref.chain.map((c) => c.text).join(".")}` : ref.id;
|
|
636
637
|
}
|
|
637
|
-
return undefined;
|
|
638
638
|
}
|
|
639
639
|
isTypeTarget(name, doc) {
|
|
640
|
-
const
|
|
641
|
-
const decl = d.getDeclarationOwnerNode(name);
|
|
640
|
+
const decl = (doc || this.doc).getDeclarationOwnerNode(name);
|
|
642
641
|
if (!decl?.node) return false;
|
|
643
642
|
if (decl.node.entity === "type") return true;
|
|
644
643
|
if (decl.node.entity === "interface") return false;
|
|
@@ -666,10 +665,7 @@ function renderPrimitiveTypeDef(def) {
|
|
|
666
665
|
case "intersection": return def.items.map(renderPrimitiveTypeDef).join(" & ");
|
|
667
666
|
case "tuple": return `[${def.items.map(renderPrimitiveTypeDef).join(", ")}]`;
|
|
668
667
|
case "array": return `${renderPrimitiveTypeDef(def.of)}[]`;
|
|
669
|
-
case "object": {
|
|
670
|
-
const props = Object.entries(def.props).map(([key, val]) => `${wrapProp(key)}${typeof val === "object" && val.optional ? "?" : ""}: ${renderPrimitiveTypeDef(val)}`).join("; ");
|
|
671
|
-
return `{ ${props} }`;
|
|
672
|
-
}
|
|
668
|
+
case "object": return `{ ${Object.entries(def.props).map(([key, val]) => `${wrapProp(key)}${typeof val === "object" && val.optional ? "?" : ""}: ${renderPrimitiveTypeDef(val)}`).join("; ")} }`;
|
|
673
669
|
default: return "unknown";
|
|
674
670
|
}
|
|
675
671
|
}
|
|
@@ -683,16 +679,36 @@ function _define_property$4(obj, key, value) {
|
|
|
683
679
|
configurable: true,
|
|
684
680
|
writable: true
|
|
685
681
|
});
|
|
686
|
-
else obj[key] = value;
|
|
682
|
+
else obj[key] = value;
|
|
687
683
|
return obj;
|
|
688
684
|
}
|
|
689
|
-
const regexCache = new Map();
|
|
690
|
-
|
|
685
|
+
const regexCache = /* @__PURE__ */ new Map();
|
|
686
|
+
/**
|
|
687
|
+
* Validates values against an {@link TAtscriptAnnotatedType} definition.
|
|
688
|
+
*
|
|
689
|
+
* `DataType` is automatically inferred from the type definition's phantom generic,
|
|
690
|
+
* enabling the {@link validate} method to act as a type guard.
|
|
691
|
+
*
|
|
692
|
+
* @example
|
|
693
|
+
* ```ts
|
|
694
|
+
* // From a generated interface class:
|
|
695
|
+
* const validator = new Validator(MyInterface)
|
|
696
|
+
* if (validator.validate(data, true)) {
|
|
697
|
+
* data // narrowed to MyInterface
|
|
698
|
+
* }
|
|
699
|
+
*
|
|
700
|
+
* // Or use the built-in factory:
|
|
701
|
+
* MyInterface.validator().validate(data)
|
|
702
|
+
* ```
|
|
703
|
+
*
|
|
704
|
+
* @typeParam T - The annotated type definition.
|
|
705
|
+
* @typeParam DataType - The TypeScript type that `validate` narrows to (auto-inferred).
|
|
706
|
+
*/ var Validator = class {
|
|
691
707
|
buildPath() {
|
|
692
708
|
if (this.depth <= 0) return "";
|
|
693
|
-
let path
|
|
694
|
-
for (let i = 1; i < this.depth; i++) path
|
|
695
|
-
return path
|
|
709
|
+
let path = this.pathSegments[0];
|
|
710
|
+
for (let i = 1; i < this.depth; i++) path += `.${this.pathSegments[i]}`;
|
|
711
|
+
return path;
|
|
696
712
|
}
|
|
697
713
|
push(name) {
|
|
698
714
|
this.pathSegments[this.depth] = name;
|
|
@@ -702,21 +718,21 @@ var Validator = class {
|
|
|
702
718
|
pop(saveErrors) {
|
|
703
719
|
this.depth--;
|
|
704
720
|
const popped = this.stackErrors.pop();
|
|
705
|
-
if (saveErrors && popped !== null && popped !==
|
|
721
|
+
if (saveErrors && popped !== null && popped !== void 0 && popped.length > 0) for (const err of popped) this.error(err.message, err.path, err.details);
|
|
706
722
|
return popped;
|
|
707
723
|
}
|
|
708
724
|
clear() {
|
|
709
725
|
this.stackErrors[this.stackErrors.length - 1] = null;
|
|
710
726
|
if (this.limitExceeded) this.limitExceeded = false;
|
|
711
727
|
}
|
|
712
|
-
error(message, path
|
|
728
|
+
error(message, path, details) {
|
|
713
729
|
let errors = this.stackErrors[this.stackErrors.length - 1];
|
|
714
730
|
if (!errors) if (this.stackErrors.length > 0) {
|
|
715
731
|
errors = [];
|
|
716
732
|
this.stackErrors[this.stackErrors.length - 1] = errors;
|
|
717
733
|
} else errors = this.errors;
|
|
718
734
|
const error = {
|
|
719
|
-
path: path
|
|
735
|
+
path: path || this.buildPath(),
|
|
720
736
|
message
|
|
721
737
|
};
|
|
722
738
|
if (details?.length) error.details = details;
|
|
@@ -743,7 +759,7 @@ var Validator = class {
|
|
|
743
759
|
this.limitExceeded = false;
|
|
744
760
|
this.context = context;
|
|
745
761
|
const passed = this.validateSafe(this.def, value);
|
|
746
|
-
this.context =
|
|
762
|
+
this.context = void 0;
|
|
747
763
|
if (!passed) {
|
|
748
764
|
if (safe) return false;
|
|
749
765
|
this.throw();
|
|
@@ -754,13 +770,13 @@ var Validator = class {
|
|
|
754
770
|
if (this.limitExceeded) return false;
|
|
755
771
|
if (this.hasReplace) {
|
|
756
772
|
let replaced = this.replaceCache.get(def);
|
|
757
|
-
if (replaced ===
|
|
773
|
+
if (replaced === void 0) {
|
|
758
774
|
replaced = this.opts.replace(def, this.buildPath());
|
|
759
775
|
this.replaceCache.set(def, replaced);
|
|
760
776
|
}
|
|
761
777
|
def = replaced;
|
|
762
778
|
}
|
|
763
|
-
if (def.optional && (value ===
|
|
779
|
+
if (def.optional && (value === void 0 || value === null)) return true;
|
|
764
780
|
if (this.hasPlugins) for (const plugin of this.opts.plugins) {
|
|
765
781
|
const result = plugin(this, def, value);
|
|
766
782
|
if (result === false || result === true) return result;
|
|
@@ -772,10 +788,9 @@ var Validator = class {
|
|
|
772
788
|
}
|
|
773
789
|
validateAnnotatedType(def, value) {
|
|
774
790
|
switch (def.type.kind) {
|
|
775
|
-
case "":
|
|
791
|
+
case "":
|
|
776
792
|
if (def.type.designType === "phantom") return true;
|
|
777
793
|
return this.validatePrimitive(def, value);
|
|
778
|
-
}
|
|
779
794
|
case "object": return this.validateObject(def, value);
|
|
780
795
|
case "array": return this.validateArray(def, value);
|
|
781
796
|
case "union": return this.validateUnion(def, value);
|
|
@@ -796,10 +811,10 @@ var Validator = class {
|
|
|
796
811
|
const branchErrors = this.stackErrors.pop();
|
|
797
812
|
if (this.limitExceeded) this.limitExceeded = false;
|
|
798
813
|
if (branchErrors) if (details) for (const err of branchErrors) details.push(err);
|
|
799
|
-
else details = branchErrors;
|
|
814
|
+
else details = branchErrors;
|
|
800
815
|
}
|
|
801
816
|
const expected = items.map((item, i) => `[${item.type.kind || item.type.designType}(${i})]`).join(", ");
|
|
802
|
-
this.error(`Value does not match any of the allowed types: ${expected}`,
|
|
817
|
+
this.error(`Value does not match any of the allowed types: ${expected}`, void 0, details);
|
|
803
818
|
return false;
|
|
804
819
|
}
|
|
805
820
|
validateIntersection(def, value) {
|
|
@@ -849,8 +864,8 @@ else details = branchErrors;
|
|
|
849
864
|
const uniqueItems = def.metadata.get("expect.array.uniqueItems");
|
|
850
865
|
if (uniqueItems) {
|
|
851
866
|
const separator = "▼↩";
|
|
852
|
-
const seen = new Set();
|
|
853
|
-
const keyProps = new Set();
|
|
867
|
+
const seen = /* @__PURE__ */ new Set();
|
|
868
|
+
const keyProps = /* @__PURE__ */ new Set();
|
|
854
869
|
if (def.type.of.type.kind === "object") {
|
|
855
870
|
for (const [key, val] of def.type.of.type.props.entries()) if (val.metadata.get("expect.array.key")) keyProps.add(key);
|
|
856
871
|
}
|
|
@@ -892,10 +907,10 @@ else details = branchErrors;
|
|
|
892
907
|
let keysToStrip;
|
|
893
908
|
let skipList;
|
|
894
909
|
if (this.opts.skipList) {
|
|
895
|
-
const path
|
|
896
|
-
for (const item of this.opts.skipList) if (item.startsWith(path
|
|
897
|
-
const key = item.slice(path
|
|
898
|
-
if (!skipList) skipList = new Set();
|
|
910
|
+
const path = this.depth > 0 ? `${this.buildPath()}.` : "";
|
|
911
|
+
for (const item of this.opts.skipList) if (item.startsWith(path)) {
|
|
912
|
+
const key = item.slice(path.length);
|
|
913
|
+
if (!skipList) skipList = /* @__PURE__ */ new Set();
|
|
899
914
|
skipList.add(key);
|
|
900
915
|
}
|
|
901
916
|
}
|
|
@@ -903,12 +918,12 @@ else details = branchErrors;
|
|
|
903
918
|
if (typeof this.opts.partial === "function") partialFunctionMatched = this.opts.partial(def, this.buildPath());
|
|
904
919
|
for (const [key, item] of def.type.props.entries()) {
|
|
905
920
|
if (skipList && skipList.has(key) || isPhantomType(item)) continue;
|
|
906
|
-
if (value[key] ===
|
|
921
|
+
if (value[key] === void 0) {
|
|
907
922
|
if (partialFunctionMatched || this.opts.partial === "deep" || this.opts.partial === true && this.depth === 0) continue;
|
|
908
923
|
}
|
|
909
924
|
this.push(key);
|
|
910
925
|
if (this.validateSafe(item, value[key])) this.pop(false);
|
|
911
|
-
else {
|
|
926
|
+
else {
|
|
912
927
|
passed = false;
|
|
913
928
|
this.pop(true);
|
|
914
929
|
if (this.limitExceeded) return false;
|
|
@@ -958,7 +973,7 @@ else {
|
|
|
958
973
|
return passed;
|
|
959
974
|
}
|
|
960
975
|
validatePrimitive(def, value) {
|
|
961
|
-
if (def.type.value !==
|
|
976
|
+
if (def.type.value !== void 0) {
|
|
962
977
|
if (value !== def.type.value) {
|
|
963
978
|
this.error(`Expected ${def.type.value}, got ${value}`);
|
|
964
979
|
return false;
|
|
@@ -967,47 +982,41 @@ else {
|
|
|
967
982
|
}
|
|
968
983
|
const typeOfValue = Array.isArray(value) ? "array" : typeof value;
|
|
969
984
|
switch (def.type.designType) {
|
|
970
|
-
case "never":
|
|
985
|
+
case "never":
|
|
971
986
|
this.error(`This type is impossible, must be an internal problem`);
|
|
972
987
|
return false;
|
|
973
|
-
}
|
|
974
988
|
case "any": return true;
|
|
975
|
-
case "string":
|
|
989
|
+
case "string":
|
|
976
990
|
if (typeOfValue !== def.type.designType) {
|
|
977
991
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
978
992
|
return false;
|
|
979
993
|
}
|
|
980
994
|
return this.validateString(def, value);
|
|
981
|
-
|
|
982
|
-
case "number": {
|
|
995
|
+
case "number":
|
|
983
996
|
if (typeOfValue !== def.type.designType) {
|
|
984
997
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
985
998
|
return false;
|
|
986
999
|
}
|
|
987
1000
|
return this.validateNumber(def, value);
|
|
988
|
-
|
|
989
|
-
case "boolean": {
|
|
1001
|
+
case "boolean":
|
|
990
1002
|
if (typeOfValue !== def.type.designType) {
|
|
991
1003
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
992
1004
|
return false;
|
|
993
1005
|
}
|
|
994
1006
|
return this.validateBoolean(def, value);
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
if (value !== undefined) {
|
|
1007
|
+
case "undefined":
|
|
1008
|
+
if (value !== void 0) {
|
|
998
1009
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
999
1010
|
return false;
|
|
1000
1011
|
}
|
|
1001
1012
|
return true;
|
|
1002
|
-
|
|
1003
|
-
case "null": {
|
|
1013
|
+
case "null":
|
|
1004
1014
|
if (value !== null) {
|
|
1005
1015
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
1006
1016
|
return false;
|
|
1007
1017
|
}
|
|
1008
1018
|
return true;
|
|
1009
|
-
|
|
1010
|
-
case "decimal": {
|
|
1019
|
+
case "decimal":
|
|
1011
1020
|
if (typeOfValue !== "string") {
|
|
1012
1021
|
this.error(`Expected string (decimal), got ${typeOfValue}`);
|
|
1013
1022
|
return false;
|
|
@@ -1017,7 +1026,6 @@ else {
|
|
|
1017
1026
|
return false;
|
|
1018
1027
|
}
|
|
1019
1028
|
return true;
|
|
1020
|
-
}
|
|
1021
1029
|
default: throw new Error(`Unknown type "${def.type.designType}"`);
|
|
1022
1030
|
}
|
|
1023
1031
|
}
|
|
@@ -1132,10 +1140,10 @@ else {
|
|
|
1132
1140
|
};
|
|
1133
1141
|
this.hasPlugins = this.opts.plugins.length > 0;
|
|
1134
1142
|
this.hasReplace = typeof this.opts.replace === "function";
|
|
1135
|
-
if (this.hasReplace) this.replaceCache = new WeakMap();
|
|
1143
|
+
if (this.hasReplace) this.replaceCache = /* @__PURE__ */ new WeakMap();
|
|
1136
1144
|
}
|
|
1137
1145
|
};
|
|
1138
|
-
var ValidatorError = class extends Error {
|
|
1146
|
+
/** Error thrown by {@link Validator.validate} when validation fails. Contains structured error details. */ var ValidatorError = class extends Error {
|
|
1139
1147
|
constructor(errors) {
|
|
1140
1148
|
super(`${errors[0].path ? errors[0].path + ": " : ""}${errors[0].message}`), _define_property$4(this, "errors", void 0), _define_property$4(this, "name", void 0), this.errors = errors, this.name = "Validation Error";
|
|
1141
1149
|
}
|
|
@@ -1151,7 +1159,10 @@ const COMPLEX_KINDS = new Set([
|
|
|
1151
1159
|
/** Shared validator method reused by all annotated type nodes. */ function validatorMethod(opts) {
|
|
1152
1160
|
return new Validator(this, opts);
|
|
1153
1161
|
}
|
|
1154
|
-
|
|
1162
|
+
/**
|
|
1163
|
+
* Creates a minimal annotated type node from a type def and metadata map.
|
|
1164
|
+
* Centralises the shape so callers never duplicate the boilerplate.
|
|
1165
|
+
*/ function createAnnotatedTypeNode(type, metadata, opts) {
|
|
1155
1166
|
return {
|
|
1156
1167
|
__is_atscript_annotated_type: true,
|
|
1157
1168
|
type,
|
|
@@ -1162,22 +1173,27 @@ function createAnnotatedTypeNode(type, metadata, opts) {
|
|
|
1162
1173
|
ref: opts?.ref
|
|
1163
1174
|
};
|
|
1164
1175
|
}
|
|
1165
|
-
|
|
1176
|
+
/**
|
|
1177
|
+
* Type Guard to check if a type is atscript-annotated
|
|
1178
|
+
*/ function isAnnotatedType(type) {
|
|
1166
1179
|
return type && type.__is_atscript_annotated_type;
|
|
1167
1180
|
}
|
|
1168
|
-
|
|
1181
|
+
/**
|
|
1182
|
+
* Standalone annotate function that handles both replace and append (array) strategies.
|
|
1183
|
+
* Used by the handle's .annotate() method and by generated mutation statements.
|
|
1184
|
+
*/ function annotate(metadata, key, value, asArray) {
|
|
1169
1185
|
if (!metadata) return;
|
|
1170
1186
|
if (asArray) if (metadata.has(key)) {
|
|
1171
1187
|
const a = metadata.get(key);
|
|
1172
1188
|
if (Array.isArray(a)) a.push(value);
|
|
1173
|
-
else metadata.set(key, [a, value]);
|
|
1189
|
+
else metadata.set(key, [a, value]);
|
|
1174
1190
|
} else metadata.set(key, [value]);
|
|
1175
|
-
else metadata.set(key, value);
|
|
1191
|
+
else metadata.set(key, value);
|
|
1176
1192
|
}
|
|
1177
1193
|
function cloneTypeDef(type) {
|
|
1178
1194
|
if (type.kind === "object") {
|
|
1179
1195
|
const obj = type;
|
|
1180
|
-
const props = new Map();
|
|
1196
|
+
const props = /* @__PURE__ */ new Map();
|
|
1181
1197
|
for (const [k, v] of obj.props) props.set(k, createAnnotatedTypeNode(v.type, new Map(v.metadata), {
|
|
1182
1198
|
id: v.id,
|
|
1183
1199
|
optional: v.optional
|
|
@@ -1210,18 +1226,36 @@ function cloneTypeDef(type) {
|
|
|
1210
1226
|
tags: new Set(type.tags)
|
|
1211
1227
|
};
|
|
1212
1228
|
}
|
|
1213
|
-
|
|
1229
|
+
/**
|
|
1230
|
+
* Creates a builder handle for constructing a {@link TAtscriptAnnotatedType} at runtime.
|
|
1231
|
+
*
|
|
1232
|
+
* This is primarily used by generated `.as.js` code. The returned handle provides
|
|
1233
|
+
* a fluent API for setting the type definition, metadata, and properties.
|
|
1234
|
+
*
|
|
1235
|
+
* @example
|
|
1236
|
+
* ```ts
|
|
1237
|
+
* const handle = defineAnnotatedType('object')
|
|
1238
|
+
* .prop('name', defineAnnotatedType().designType('string').$type)
|
|
1239
|
+
* .prop('age', defineAnnotatedType().designType('number').$type)
|
|
1240
|
+
*
|
|
1241
|
+
* handle.$type // the resulting TAtscriptAnnotatedType
|
|
1242
|
+
* ```
|
|
1243
|
+
*
|
|
1244
|
+
* @param _kind - The kind of type to create (e.g. `'object'`, `'array'`, `'union'`). Defaults to `''` (primitive/final).
|
|
1245
|
+
* @param base - Optional existing object to augment with annotated type fields.
|
|
1246
|
+
* @returns A builder handle for fluent type construction.
|
|
1247
|
+
*/ function defineAnnotatedType(_kind, base) {
|
|
1214
1248
|
const kind = _kind || "";
|
|
1215
|
-
const baseProvided = base !==
|
|
1249
|
+
const baseProvided = base !== void 0;
|
|
1216
1250
|
const type = base?.type || {};
|
|
1217
1251
|
type.kind = kind;
|
|
1218
1252
|
if (COMPLEX_KINDS.has(kind)) type.items = [];
|
|
1219
1253
|
if (kind === "object") {
|
|
1220
|
-
type.props = new Map();
|
|
1254
|
+
type.props = /* @__PURE__ */ new Map();
|
|
1221
1255
|
type.propsPatterns = [];
|
|
1222
1256
|
}
|
|
1223
|
-
type.tags = new Set();
|
|
1224
|
-
const metadata = base?.metadata || new Map();
|
|
1257
|
+
type.tags = /* @__PURE__ */ new Set();
|
|
1258
|
+
const metadata = base?.metadata || /* @__PURE__ */ new Map();
|
|
1225
1259
|
const payload = {
|
|
1226
1260
|
__is_atscript_annotated_type: true,
|
|
1227
1261
|
metadata,
|
|
@@ -1229,7 +1263,7 @@ function defineAnnotatedType(_kind, base) {
|
|
|
1229
1263
|
validator: validatorMethod
|
|
1230
1264
|
};
|
|
1231
1265
|
base = base ? Object.assign(base, payload) : payload;
|
|
1232
|
-
|
|
1266
|
+
return {
|
|
1233
1267
|
$type: base,
|
|
1234
1268
|
$def: type,
|
|
1235
1269
|
$metadata: metadata,
|
|
@@ -1272,15 +1306,15 @@ function defineAnnotatedType(_kind, base) {
|
|
|
1272
1306
|
for (const [key, value] of fromMetadata.entries()) if (!ignore || !ignore.has(key)) this.$metadata.set(key, value);
|
|
1273
1307
|
return this;
|
|
1274
1308
|
},
|
|
1275
|
-
refTo(type
|
|
1309
|
+
refTo(type, chain) {
|
|
1276
1310
|
const node = this.$type;
|
|
1277
|
-
if (isAnnotatedType(type
|
|
1278
|
-
let newBase = type
|
|
1279
|
-
const typeName = type
|
|
1311
|
+
if (isAnnotatedType(type)) {
|
|
1312
|
+
let newBase = type;
|
|
1313
|
+
const typeName = type.name || "Unknown";
|
|
1280
1314
|
if (chain) for (let i = 0; i < chain.length; i++) {
|
|
1281
1315
|
const c = chain[i];
|
|
1282
1316
|
if (newBase.type.kind === "object" && newBase.type.props.has(c)) newBase = newBase.type.props.get(c);
|
|
1283
|
-
else {
|
|
1317
|
+
else {
|
|
1284
1318
|
const keys = chain.slice(0, i + 1).map((k) => `["${k}"]`).join("");
|
|
1285
1319
|
throw new Error(`Can't find prop ${typeName}${keys}`);
|
|
1286
1320
|
}
|
|
@@ -1288,11 +1322,11 @@ else {
|
|
|
1288
1322
|
node.type = baseProvided ? cloneTypeDef(newBase.type) : newBase.type;
|
|
1289
1323
|
node.id = node.id ?? newBase.id;
|
|
1290
1324
|
if (chain && chain.length > 0) node.ref = {
|
|
1291
|
-
type: () => type
|
|
1325
|
+
type: () => type,
|
|
1292
1326
|
field: chain.join(".")
|
|
1293
1327
|
};
|
|
1294
|
-
} else if (typeof type
|
|
1295
|
-
const lazyType = type
|
|
1328
|
+
} else if (typeof type === "function") {
|
|
1329
|
+
const lazyType = type;
|
|
1296
1330
|
const ownId = node.id;
|
|
1297
1331
|
node.ref = {
|
|
1298
1332
|
type: lazyType,
|
|
@@ -1312,7 +1346,7 @@ else {
|
|
|
1312
1346
|
}
|
|
1313
1347
|
let target = t;
|
|
1314
1348
|
if (chain) for (const c of chain) if (target.type.kind === "object" && target.type.props.has(c)) target = target.type.props.get(c);
|
|
1315
|
-
else return t.type;
|
|
1349
|
+
else return t.type;
|
|
1316
1350
|
node.id = ownId ?? target.id;
|
|
1317
1351
|
const resolved = baseProvided ? cloneTypeDef(target.type) : target.type;
|
|
1318
1352
|
Object.defineProperty(node, "type", {
|
|
@@ -1324,7 +1358,7 @@ else return t.type;
|
|
|
1324
1358
|
},
|
|
1325
1359
|
configurable: true
|
|
1326
1360
|
});
|
|
1327
|
-
} else throw new TypeError(`${type
|
|
1361
|
+
} else throw new TypeError(`${type} is not annotated type`);
|
|
1328
1362
|
return this;
|
|
1329
1363
|
},
|
|
1330
1364
|
annotate(key, value, asArray) {
|
|
@@ -1336,15 +1370,29 @@ else return t.type;
|
|
|
1336
1370
|
return this;
|
|
1337
1371
|
}
|
|
1338
1372
|
};
|
|
1339
|
-
return handle;
|
|
1340
1373
|
}
|
|
1341
|
-
|
|
1374
|
+
/**
|
|
1375
|
+
* Checks whether an annotated type is a phantom type.
|
|
1376
|
+
*
|
|
1377
|
+
* Phantom types do not affect the data type, validation, or schema,
|
|
1378
|
+
* but are discoverable via runtime type traversal.
|
|
1379
|
+
*/ function isPhantomType(def) {
|
|
1342
1380
|
return def.type.kind === "" && def.type.designType === "phantom";
|
|
1343
1381
|
}
|
|
1344
1382
|
|
|
1345
1383
|
//#endregion
|
|
1346
1384
|
//#region packages/typescript/src/runtime/traverse.ts
|
|
1347
|
-
|
|
1385
|
+
/**
|
|
1386
|
+
* Type-safe dispatch over `TAtscriptAnnotatedType` by its `type.kind`.
|
|
1387
|
+
*
|
|
1388
|
+
* Provides the common `switch (def.type.kind)` pattern used by
|
|
1389
|
+
* the validator, JSON-schema builder, and serializer.
|
|
1390
|
+
* Each caller supplies its own handlers that control recursion.
|
|
1391
|
+
*
|
|
1392
|
+
* When a `phantom` handler is provided, phantom types (`designType === 'phantom'`)
|
|
1393
|
+
* are dispatched to it instead of `final`. This allows consumers to skip or
|
|
1394
|
+
* handle phantom props without polluting their `final` handler.
|
|
1395
|
+
*/ function forAnnotatedType(def, handlers) {
|
|
1348
1396
|
switch (def.type.kind) {
|
|
1349
1397
|
case "": {
|
|
1350
1398
|
const typed = def;
|
|
@@ -1362,21 +1410,27 @@ function forAnnotatedType(def, handlers) {
|
|
|
1362
1410
|
|
|
1363
1411
|
//#endregion
|
|
1364
1412
|
//#region packages/typescript/src/runtime/json-schema.ts
|
|
1365
|
-
|
|
1413
|
+
/**
|
|
1414
|
+
* Detects a discriminator property across union items.
|
|
1415
|
+
*
|
|
1416
|
+
* Scans all items for object-typed members that share a common property
|
|
1417
|
+
* with distinct const/literal values. If exactly one such property exists,
|
|
1418
|
+
* it is returned as the discriminator. Returns `null` when no qualifying
|
|
1419
|
+
* property exists, or when more than one does (ambiguous).
|
|
1420
|
+
*/ function detectDiscriminator(items) {
|
|
1366
1421
|
if (items.length < 2) return null;
|
|
1367
1422
|
for (const item of items) if (item.type.kind !== "object") return null;
|
|
1368
1423
|
const firstObj = items[0].type;
|
|
1369
1424
|
const candidates = [];
|
|
1370
|
-
for (const [propName, propType] of firstObj.props.entries()) if (propType.type.kind === "" && propType.type.value !==
|
|
1425
|
+
for (const [propName, propType] of firstObj.props.entries()) if (propType.type.kind === "" && propType.type.value !== void 0) candidates.push(propName);
|
|
1371
1426
|
let result = null;
|
|
1372
1427
|
for (const candidate of candidates) {
|
|
1373
|
-
const values = new Set();
|
|
1428
|
+
const values = /* @__PURE__ */ new Set();
|
|
1374
1429
|
const indexMapping = {};
|
|
1375
1430
|
let valid = true;
|
|
1376
1431
|
for (let i = 0; i < items.length; i++) {
|
|
1377
|
-
const
|
|
1378
|
-
|
|
1379
|
-
if (!prop || prop.type.kind !== "" || prop.type.value === undefined) {
|
|
1432
|
+
const prop = items[i].type.props.get(candidate);
|
|
1433
|
+
if (!prop || prop.type.kind !== "" || prop.type.value === void 0) {
|
|
1380
1434
|
valid = false;
|
|
1381
1435
|
break;
|
|
1382
1436
|
}
|
|
@@ -1398,7 +1452,23 @@ function detectDiscriminator(items) {
|
|
|
1398
1452
|
}
|
|
1399
1453
|
return result;
|
|
1400
1454
|
}
|
|
1401
|
-
|
|
1455
|
+
/**
|
|
1456
|
+
* Builds a JSON Schema from an {@link TAtscriptAnnotatedType}.
|
|
1457
|
+
*
|
|
1458
|
+
* Translates the atscript type structure and validation metadata
|
|
1459
|
+
* (min/max, patterns, integer constraints, etc.) into a standard JSON Schema.
|
|
1460
|
+
*
|
|
1461
|
+
* @example
|
|
1462
|
+
* ```ts
|
|
1463
|
+
* import { buildJsonSchema } from '@atscript/typescript'
|
|
1464
|
+
*
|
|
1465
|
+
* const schema = buildJsonSchema(MyInterface)
|
|
1466
|
+
* // { type: 'object', properties: { ... }, required: [...] }
|
|
1467
|
+
* ```
|
|
1468
|
+
*
|
|
1469
|
+
* @param type - The annotated type to convert.
|
|
1470
|
+
* @returns A JSON Schema object.
|
|
1471
|
+
*/ function buildJsonSchema(type) {
|
|
1402
1472
|
const defs = {};
|
|
1403
1473
|
let hasDefs = false;
|
|
1404
1474
|
const buildObject = (d) => {
|
|
@@ -1406,17 +1476,17 @@ function buildJsonSchema(type) {
|
|
|
1406
1476
|
const required = [];
|
|
1407
1477
|
for (const [key, val] of d.type.props.entries()) {
|
|
1408
1478
|
if (isPhantomType(val)) continue;
|
|
1409
|
-
properties[key] = build
|
|
1479
|
+
properties[key] = build(val);
|
|
1410
1480
|
if (!val.optional) required.push(key);
|
|
1411
1481
|
}
|
|
1412
|
-
const schema
|
|
1482
|
+
const schema = {
|
|
1413
1483
|
type: "object",
|
|
1414
1484
|
properties
|
|
1415
1485
|
};
|
|
1416
|
-
if (required.length > 0) schema
|
|
1417
|
-
return schema
|
|
1486
|
+
if (required.length > 0) schema.required = required;
|
|
1487
|
+
return schema;
|
|
1418
1488
|
};
|
|
1419
|
-
const build
|
|
1489
|
+
const build = (def) => {
|
|
1420
1490
|
if (def.id && def.type.kind === "object" && def !== type) {
|
|
1421
1491
|
const name = def.id;
|
|
1422
1492
|
if (!defs[name]) {
|
|
@@ -1435,20 +1505,20 @@ function buildJsonSchema(type) {
|
|
|
1435
1505
|
return buildObject(d);
|
|
1436
1506
|
},
|
|
1437
1507
|
array(d) {
|
|
1438
|
-
const schema
|
|
1508
|
+
const schema = {
|
|
1439
1509
|
type: "array",
|
|
1440
|
-
items: build
|
|
1510
|
+
items: build(d.type.of)
|
|
1441
1511
|
};
|
|
1442
1512
|
const minLength = meta.get("expect.minLength");
|
|
1443
|
-
if (minLength) schema
|
|
1513
|
+
if (minLength) schema.minItems = typeof minLength === "number" ? minLength : minLength.length;
|
|
1444
1514
|
const maxLength = meta.get("expect.maxLength");
|
|
1445
|
-
if (maxLength) schema
|
|
1446
|
-
return schema
|
|
1515
|
+
if (maxLength) schema.maxItems = typeof maxLength === "number" ? maxLength : maxLength.length;
|
|
1516
|
+
return schema;
|
|
1447
1517
|
},
|
|
1448
1518
|
union(d) {
|
|
1449
1519
|
const disc = detectDiscriminator(d.type.items);
|
|
1450
1520
|
if (disc) {
|
|
1451
|
-
const oneOf = d.type.items.map(build
|
|
1521
|
+
const oneOf = d.type.items.map(build);
|
|
1452
1522
|
const mapping = {};
|
|
1453
1523
|
for (const [val, idx] of Object.entries(disc.indexMapping)) {
|
|
1454
1524
|
const item = d.type.items[idx];
|
|
@@ -1462,47 +1532,47 @@ function buildJsonSchema(type) {
|
|
|
1462
1532
|
}
|
|
1463
1533
|
};
|
|
1464
1534
|
}
|
|
1465
|
-
return { anyOf: d.type.items.map(build
|
|
1535
|
+
return { anyOf: d.type.items.map(build) };
|
|
1466
1536
|
},
|
|
1467
1537
|
intersection(d) {
|
|
1468
|
-
return { allOf: d.type.items.map(build
|
|
1538
|
+
return { allOf: d.type.items.map(build) };
|
|
1469
1539
|
},
|
|
1470
1540
|
tuple(d) {
|
|
1471
1541
|
return {
|
|
1472
1542
|
type: "array",
|
|
1473
|
-
items: d.type.items.map(build
|
|
1543
|
+
items: d.type.items.map(build),
|
|
1474
1544
|
additionalItems: false
|
|
1475
1545
|
};
|
|
1476
1546
|
},
|
|
1477
1547
|
final(d) {
|
|
1478
|
-
const schema
|
|
1479
|
-
if (d.type.value !==
|
|
1548
|
+
const schema = {};
|
|
1549
|
+
if (d.type.value !== void 0) schema.const = d.type.value;
|
|
1480
1550
|
if (d.type.designType && d.type.designType !== "any") {
|
|
1481
1551
|
const dt = d.type.designType;
|
|
1482
|
-
schema
|
|
1483
|
-
if (schema
|
|
1552
|
+
schema.type = dt === "undefined" ? "null" : dt === "decimal" ? "string" : dt;
|
|
1553
|
+
if (schema.type === "number" && meta.get("expect.int")) schema.type = "integer";
|
|
1484
1554
|
}
|
|
1485
|
-
if (schema
|
|
1486
|
-
if (meta.get("meta.required")) schema
|
|
1555
|
+
if (schema.type === "string") {
|
|
1556
|
+
if (meta.get("meta.required")) schema.minLength = 1;
|
|
1487
1557
|
const minLength = meta.get("expect.minLength");
|
|
1488
|
-
if (minLength) schema
|
|
1558
|
+
if (minLength) schema.minLength = typeof minLength === "number" ? minLength : minLength.length;
|
|
1489
1559
|
const maxLength = meta.get("expect.maxLength");
|
|
1490
|
-
if (maxLength) schema
|
|
1560
|
+
if (maxLength) schema.maxLength = typeof maxLength === "number" ? maxLength : maxLength.length;
|
|
1491
1561
|
const patterns = meta.get("expect.pattern");
|
|
1492
|
-
if (patterns?.length) if (patterns.length === 1) schema
|
|
1493
|
-
else schema
|
|
1562
|
+
if (patterns?.length) if (patterns.length === 1) schema.pattern = patterns[0].pattern;
|
|
1563
|
+
else schema.allOf = (schema.allOf || []).concat(patterns.map((p) => ({ pattern: p.pattern })));
|
|
1494
1564
|
}
|
|
1495
|
-
if (schema
|
|
1565
|
+
if (schema.type === "number" || schema.type === "integer") {
|
|
1496
1566
|
const min = meta.get("expect.min");
|
|
1497
|
-
if (min) schema
|
|
1567
|
+
if (min) schema.minimum = typeof min === "number" ? min : min.minValue;
|
|
1498
1568
|
const max = meta.get("expect.max");
|
|
1499
|
-
if (max) schema
|
|
1569
|
+
if (max) schema.maximum = typeof max === "number" ? max : max.maxValue;
|
|
1500
1570
|
}
|
|
1501
|
-
return schema
|
|
1571
|
+
return schema;
|
|
1502
1572
|
}
|
|
1503
1573
|
});
|
|
1504
1574
|
};
|
|
1505
|
-
const schema = build
|
|
1575
|
+
const schema = build(type);
|
|
1506
1576
|
if (hasDefs) return {
|
|
1507
1577
|
...schema,
|
|
1508
1578
|
$defs: defs
|
|
@@ -1519,7 +1589,7 @@ function _define_property$3(obj, key, value) {
|
|
|
1519
1589
|
configurable: true,
|
|
1520
1590
|
writable: true
|
|
1521
1591
|
});
|
|
1522
|
-
else obj[key] = value;
|
|
1592
|
+
else obj[key] = value;
|
|
1523
1593
|
return obj;
|
|
1524
1594
|
}
|
|
1525
1595
|
const QUERY_OP_MAP = {
|
|
@@ -1548,31 +1618,31 @@ var JsRenderer = class extends BaseRenderer {
|
|
|
1548
1618
|
}
|
|
1549
1619
|
getExtendsRefs() {
|
|
1550
1620
|
if (this._extendsRefs) return this._extendsRefs;
|
|
1551
|
-
const out = new Map();
|
|
1552
|
-
const visitedInterfaces = new Set();
|
|
1553
|
-
for (const node of this.doc.nodes) if ((0,
|
|
1621
|
+
const out = /* @__PURE__ */ new Map();
|
|
1622
|
+
const visitedInterfaces = /* @__PURE__ */ new Set();
|
|
1623
|
+
for (const node of this.doc.nodes) if ((0, _atscript_core.isInterface)(node) && node.hasExtends) this.walkExtendsParents(node, this.doc, out, visitedInterfaces);
|
|
1554
1624
|
return this._extendsRefs = out;
|
|
1555
1625
|
}
|
|
1556
1626
|
walkRefs(node, visited, visit) {
|
|
1557
1627
|
if (!node || visited.has(node)) return;
|
|
1558
1628
|
visited.add(node);
|
|
1559
|
-
if ((0,
|
|
1629
|
+
if ((0, _atscript_core.isRef)(node)) {
|
|
1560
1630
|
visit(node);
|
|
1561
1631
|
return;
|
|
1562
1632
|
}
|
|
1563
|
-
if ((0,
|
|
1633
|
+
if ((0, _atscript_core.isGroup)(node)) {
|
|
1564
1634
|
for (const item of node.unwrap()) this.walkRefs(item, visited, visit);
|
|
1565
1635
|
return;
|
|
1566
1636
|
}
|
|
1567
|
-
if ((0,
|
|
1637
|
+
if ((0, _atscript_core.isArray)(node) || (0, _atscript_core.isProp)(node)) this.walkRefs(node.getDefinition(), visited, visit);
|
|
1568
1638
|
}
|
|
1569
1639
|
walkExtendsParents(iface, doc, out, visited) {
|
|
1570
1640
|
if (visited.has(iface)) return;
|
|
1571
1641
|
visited.add(iface);
|
|
1572
|
-
const visitedNodes = new Set();
|
|
1642
|
+
const visitedNodes = /* @__PURE__ */ new Set();
|
|
1573
1643
|
for (const token of iface.extendsTokens) {
|
|
1574
1644
|
const unwound = doc.unwindType(token.text);
|
|
1575
|
-
if (!unwound?.def || !(0,
|
|
1645
|
+
if (!unwound?.def || !(0, _atscript_core.isInterface)(unwound.def)) continue;
|
|
1576
1646
|
const parentInterface = unwound.def;
|
|
1577
1647
|
const parentDoc = unwound.doc;
|
|
1578
1648
|
this.walkRefs(parentInterface.getDefinition(), visitedNodes, (ref) => {
|
|
@@ -1587,18 +1657,18 @@ var JsRenderer = class extends BaseRenderer {
|
|
|
1587
1657
|
const refToOriginDoc = this.getExtendsRefs();
|
|
1588
1658
|
if (refToOriginDoc.size === 0) return;
|
|
1589
1659
|
const taken = new Set(this.doc.registry.definitions.keys());
|
|
1590
|
-
const allocated = new Map();
|
|
1591
|
-
const synthPathCache = new Map();
|
|
1660
|
+
const allocated = /* @__PURE__ */ new Map();
|
|
1661
|
+
const synthPathCache = /* @__PURE__ */ new Map();
|
|
1592
1662
|
for (const [refNode, originDoc] of refToOriginDoc) {
|
|
1593
1663
|
const refId = refNode.id;
|
|
1594
1664
|
if (!refId) continue;
|
|
1595
1665
|
const ownerInfo = this.resolveOwner(originDoc, refId);
|
|
1596
1666
|
if (!ownerInfo?.doc || ownerInfo.doc === this.doc) continue;
|
|
1597
|
-
if (ownerInfo.node && (0,
|
|
1667
|
+
if (ownerInfo.node && (0, _atscript_core.isPrimitive)(ownerInfo.node)) continue;
|
|
1598
1668
|
const ownerDoc = ownerInfo.doc;
|
|
1599
1669
|
let synthPath;
|
|
1600
1670
|
if (synthPathCache.has(ownerDoc)) synthPath = synthPathCache.get(ownerDoc);
|
|
1601
|
-
else {
|
|
1671
|
+
else {
|
|
1602
1672
|
synthPath = this.computeSynthPath(ownerDoc);
|
|
1603
1673
|
synthPathCache.set(ownerDoc, synthPath);
|
|
1604
1674
|
}
|
|
@@ -1615,7 +1685,7 @@ else {
|
|
|
1615
1685
|
resolveOwner(fromDoc, refId) {
|
|
1616
1686
|
const key = `${fromDoc.id}::${refId}`;
|
|
1617
1687
|
let v = this._ownerCache.get(key);
|
|
1618
|
-
if (v ===
|
|
1688
|
+
if (v === void 0 && !this._ownerCache.has(key)) {
|
|
1619
1689
|
v = fromDoc.getDeclarationOwnerNode(refId);
|
|
1620
1690
|
this._ownerCache.set(key, v);
|
|
1621
1691
|
}
|
|
@@ -1624,8 +1694,7 @@ else {
|
|
|
1624
1694
|
allocateSynthInfo(refId, synthPath, ownerInfo, taken) {
|
|
1625
1695
|
const ownerDoc = ownerInfo.doc;
|
|
1626
1696
|
const ownerNode = ownerInfo.node;
|
|
1627
|
-
|
|
1628
|
-
if (existing?.text === synthPath) return {
|
|
1697
|
+
if (this.doc.importedDefs.get(refId)?.text === synthPath) return {
|
|
1629
1698
|
alias: refId,
|
|
1630
1699
|
ownerDoc,
|
|
1631
1700
|
ownerNode
|
|
@@ -1658,26 +1727,26 @@ else {
|
|
|
1658
1727
|
return alias;
|
|
1659
1728
|
}
|
|
1660
1729
|
computeSynthPath(ownerDoc) {
|
|
1661
|
-
if ((0,
|
|
1662
|
-
if (!ownerDoc.id.startsWith("file://")) return
|
|
1663
|
-
return (0,
|
|
1730
|
+
if ((0, _atscript_core.isBareId)(ownerDoc.id)) return ownerDoc.id.slice(5, -3);
|
|
1731
|
+
if (!ownerDoc.id.startsWith("file://")) return;
|
|
1732
|
+
return (0, _atscript_core.getRelPath)(this.doc.id, ownerDoc.id);
|
|
1664
1733
|
}
|
|
1665
1734
|
pre() {
|
|
1666
1735
|
this.writeln("// prettier-ignore-start");
|
|
1667
1736
|
this.writeln("/* eslint-disable */");
|
|
1668
1737
|
this.writeln("/* oxlint-disable */");
|
|
1669
1738
|
let hasMutatingAnnotate = false;
|
|
1670
|
-
const nodesByName = new Map();
|
|
1739
|
+
const nodesByName = /* @__PURE__ */ new Map();
|
|
1671
1740
|
for (const node of this.doc.nodes) {
|
|
1672
1741
|
if (node.entity === "annotate" && node.isMutating) hasMutatingAnnotate = true;
|
|
1673
|
-
if (node.__typeId !== null && node.__typeId !==
|
|
1742
|
+
if (node.__typeId !== null && node.__typeId !== void 0 && node.id) {
|
|
1674
1743
|
const name = node.id;
|
|
1675
1744
|
if (!nodesByName.has(name)) nodesByName.set(name, []);
|
|
1676
1745
|
nodesByName.get(name).push(node);
|
|
1677
1746
|
}
|
|
1678
1747
|
}
|
|
1679
1748
|
for (const [name, nodes] of nodesByName) if (nodes.length === 1) this.typeIds.set(nodes[0], name);
|
|
1680
|
-
else for (let i = 0; i < nodes.length; i++) this.typeIds.set(nodes[i], `${name}__${i + 1}`);
|
|
1749
|
+
else for (let i = 0; i < nodes.length; i++) this.typeIds.set(nodes[i], `${name}__${i + 1}`);
|
|
1681
1750
|
const imports = ["defineAnnotatedType as $", "annotate as $a"];
|
|
1682
1751
|
if (hasMutatingAnnotate) imports.push("cloneRefProp as $c");
|
|
1683
1752
|
const jsonSchemaMode = resolveJsonSchemaMode(this.opts);
|
|
@@ -1692,14 +1761,14 @@ else for (let i = 0; i < nodes.length; i++) this.typeIds.set(nodes[i], `${name}_
|
|
|
1692
1761
|
}
|
|
1693
1762
|
}
|
|
1694
1763
|
buildAdHocMap(annotateNodes) {
|
|
1695
|
-
const map = new Map();
|
|
1764
|
+
const map = /* @__PURE__ */ new Map();
|
|
1696
1765
|
for (const annotateNode of annotateNodes) for (const entry of annotateNode.entries) {
|
|
1697
|
-
const path
|
|
1766
|
+
const path = entry.hasChain ? [entry.id, ...entry.chain.map((c) => c.text)].join(".") : entry.id;
|
|
1698
1767
|
const anns = entry.annotations || [];
|
|
1699
1768
|
if (anns.length > 0) {
|
|
1700
|
-
const existing = map.get(path
|
|
1769
|
+
const existing = map.get(path);
|
|
1701
1770
|
if (existing) existing.push(...anns);
|
|
1702
|
-
else map.set(path
|
|
1771
|
+
else map.set(path, [...anns]);
|
|
1703
1772
|
}
|
|
1704
1773
|
}
|
|
1705
1774
|
return map.size > 0 ? map : null;
|
|
@@ -1717,14 +1786,14 @@ else map.set(path$4, [...anns]);
|
|
|
1717
1786
|
for (const node of this.postAnnotate) if (node.entity === "annotate") {
|
|
1718
1787
|
const annotateNode = node;
|
|
1719
1788
|
if (annotateNode.isMutating) this.renderMutatingAnnotateNode(annotateNode);
|
|
1720
|
-
else {
|
|
1789
|
+
else {
|
|
1721
1790
|
const unwound = this.doc.unwindType(annotateNode.targetName);
|
|
1722
1791
|
if (unwound?.def) {
|
|
1723
1792
|
let def = this.doc.mergeIntersection(unwound.def);
|
|
1724
|
-
if ((0,
|
|
1793
|
+
if ((0, _atscript_core.isInterface)(def)) if (def.hasExtends) {
|
|
1725
1794
|
const resolved = unwound.doc.resolveInterfaceExtends(def);
|
|
1726
1795
|
if (resolved) def = resolved;
|
|
1727
|
-
else def = def.getDefinition() || def;
|
|
1796
|
+
else def = def.getDefinition() || def;
|
|
1728
1797
|
} else def = def.getDefinition() || def;
|
|
1729
1798
|
this._adHocAnnotations = this.buildAdHocMap([annotateNode]);
|
|
1730
1799
|
this.annotateType(def, node.id);
|
|
@@ -1737,7 +1806,7 @@ else def = def.getDefinition() || def;
|
|
|
1737
1806
|
}
|
|
1738
1807
|
} else {
|
|
1739
1808
|
let def = node.getDefinition();
|
|
1740
|
-
if ((0,
|
|
1809
|
+
if ((0, _atscript_core.isInterface)(node) && node.hasExtends) {
|
|
1741
1810
|
const resolved = this.doc.resolveInterfaceExtends(node);
|
|
1742
1811
|
if (resolved) def = resolved;
|
|
1743
1812
|
}
|
|
@@ -1785,8 +1854,7 @@ else def = def.getDefinition() || def;
|
|
|
1785
1854
|
}
|
|
1786
1855
|
renderJsonSchemaMethod(node) {
|
|
1787
1856
|
const mode = resolveJsonSchemaMode(this.opts);
|
|
1788
|
-
|
|
1789
|
-
if (hasAnnotation || mode === "bundle") {
|
|
1857
|
+
if (node.countAnnotations("emit.jsonSchema") > 0 || mode === "bundle") {
|
|
1790
1858
|
const schema = JSON.stringify(buildJsonSchema(this.toAnnotatedType(node)));
|
|
1791
1859
|
this.writeln("static toJsonSchema() {");
|
|
1792
1860
|
this.indent().writeln(`return ${schema}`).unindent();
|
|
@@ -1809,13 +1877,13 @@ else def = def.getDefinition() || def;
|
|
|
1809
1877
|
}
|
|
1810
1878
|
}
|
|
1811
1879
|
renderDimMeasure(node) {
|
|
1812
|
-
if (!(0,
|
|
1880
|
+
if (!(0, _atscript_core.isInterface)(node)) return;
|
|
1813
1881
|
const interfaceNode = node;
|
|
1814
1882
|
if (!interfaceNode.annotations?.some((a) => a.name === "db.table" || a.name === "db.view" || a.name === "db.view.for")) return;
|
|
1815
1883
|
let struct;
|
|
1816
1884
|
if (interfaceNode.hasExtends) struct = this.doc.resolveInterfaceExtends(interfaceNode);
|
|
1817
1885
|
if (!struct) struct = interfaceNode.getDefinition();
|
|
1818
|
-
if (!struct || !(0,
|
|
1886
|
+
if (!struct || !(0, _atscript_core.isStructure)(struct)) return;
|
|
1819
1887
|
const structNode = struct;
|
|
1820
1888
|
const dims = [];
|
|
1821
1889
|
const measures = [];
|
|
@@ -1836,12 +1904,12 @@ else def = def.getDefinition() || def;
|
|
|
1836
1904
|
case "interface":
|
|
1837
1905
|
case "type": {
|
|
1838
1906
|
let def = node.getDefinition();
|
|
1839
|
-
if ((0,
|
|
1907
|
+
if ((0, _atscript_core.isInterface)(node) && node.hasExtends) {
|
|
1840
1908
|
const resolved = this.doc.resolveInterfaceExtends(node);
|
|
1841
1909
|
if (resolved) def = resolved;
|
|
1842
1910
|
}
|
|
1843
1911
|
const handle = this.toAnnotatedHandle(def, true);
|
|
1844
|
-
const typeId = this.typeIds.get(node) ?? (node.__typeId !== null && node.__typeId !==
|
|
1912
|
+
const typeId = this.typeIds.get(node) ?? (node.__typeId !== null && node.__typeId !== void 0 ? node.id : void 0);
|
|
1845
1913
|
if (typeId) handle.id(typeId);
|
|
1846
1914
|
return skipAnnotations ? handle : this.applyExpectAnnotations(handle, this.doc.evalAnnotationsForNode(node));
|
|
1847
1915
|
}
|
|
@@ -1883,14 +1951,13 @@ else def = def.getDefinition() || def;
|
|
|
1883
1951
|
const propHandle = this.toAnnotatedHandle(prop);
|
|
1884
1952
|
const pattern = prop.token("identifier")?.pattern;
|
|
1885
1953
|
if (pattern) handle.propPattern(pattern, propHandle.$type);
|
|
1886
|
-
else handle.prop(prop.id, propHandle.$type);
|
|
1954
|
+
else handle.prop(prop.id, propHandle.$type);
|
|
1887
1955
|
}
|
|
1888
1956
|
return skipAnnotations ? handle : this.applyExpectAnnotations(handle, this.doc.evalAnnotationsForNode(node));
|
|
1889
1957
|
}
|
|
1890
1958
|
case "group": {
|
|
1891
1959
|
const group = node;
|
|
1892
|
-
const
|
|
1893
|
-
const handle = defineAnnotatedType(kind);
|
|
1960
|
+
const handle = defineAnnotatedType(group.op === "|" ? "union" : "intersection");
|
|
1894
1961
|
for (const item of group.unwrap()) handle.item(this.toAnnotatedHandle(item).$type);
|
|
1895
1962
|
return skipAnnotations ? handle : this.applyExpectAnnotations(handle, this.doc.evalAnnotationsForNode(node));
|
|
1896
1963
|
}
|
|
@@ -1916,44 +1983,38 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1916
1983
|
annotations?.forEach((a) => {
|
|
1917
1984
|
switch (a.name) {
|
|
1918
1985
|
case "expect.minLength":
|
|
1919
|
-
case "expect.maxLength":
|
|
1986
|
+
case "expect.maxLength":
|
|
1920
1987
|
if (a.args[0]) handle.annotate(a.name, {
|
|
1921
1988
|
length: Number(a.args[0].text),
|
|
1922
1989
|
message: a.args[1]?.text
|
|
1923
1990
|
});
|
|
1924
1991
|
break;
|
|
1925
|
-
|
|
1926
|
-
case "expect.min": {
|
|
1992
|
+
case "expect.min":
|
|
1927
1993
|
if (a.args[0]) handle.annotate(a.name, {
|
|
1928
1994
|
minValue: Number(a.args[0].text),
|
|
1929
1995
|
message: a.args[1]?.text
|
|
1930
1996
|
});
|
|
1931
1997
|
break;
|
|
1932
|
-
|
|
1933
|
-
case "expect.max": {
|
|
1998
|
+
case "expect.max":
|
|
1934
1999
|
if (a.args[0]) handle.annotate(a.name, {
|
|
1935
2000
|
maxValue: Number(a.args[0].text),
|
|
1936
2001
|
message: a.args[1]?.text
|
|
1937
2002
|
});
|
|
1938
2003
|
break;
|
|
1939
|
-
|
|
1940
|
-
case "expect.pattern": {
|
|
2004
|
+
case "expect.pattern":
|
|
1941
2005
|
handle.annotate(a.name, {
|
|
1942
2006
|
pattern: a.args[0]?.text || "",
|
|
1943
2007
|
flags: a.args[1]?.text,
|
|
1944
2008
|
message: a.args[2]?.text
|
|
1945
2009
|
}, true);
|
|
1946
2010
|
break;
|
|
1947
|
-
|
|
1948
|
-
case "expect.int": {
|
|
2011
|
+
case "expect.int":
|
|
1949
2012
|
handle.annotate(a.name, true);
|
|
1950
2013
|
break;
|
|
1951
|
-
}
|
|
1952
2014
|
case "expect.array.uniqueItems":
|
|
1953
|
-
case "expect.array.key":
|
|
2015
|
+
case "expect.array.key":
|
|
1954
2016
|
handle.annotate(a.name, { message: a.args[0]?.text });
|
|
1955
2017
|
break;
|
|
1956
|
-
}
|
|
1957
2018
|
default:
|
|
1958
2019
|
}
|
|
1959
2020
|
});
|
|
@@ -1967,16 +2028,16 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1967
2028
|
case "ref": {
|
|
1968
2029
|
const ref = node;
|
|
1969
2030
|
const decl = this.doc.unwindType(ref.id, ref.chain)?.def;
|
|
1970
|
-
if ((0,
|
|
1971
|
-
const ownerDecl
|
|
1972
|
-
if (!ownerDecl
|
|
2031
|
+
if ((0, _atscript_core.isPrimitive)(decl)) {
|
|
2032
|
+
const ownerDecl = this.resolveOwner(this.doc, ref.id);
|
|
2033
|
+
if (!ownerDecl?.node || ownerDecl.node.entity !== "type" && ownerDecl.node.entity !== "interface") {
|
|
1973
2034
|
this.annotateType(decl, name);
|
|
1974
2035
|
return this;
|
|
1975
2036
|
}
|
|
1976
2037
|
}
|
|
1977
2038
|
if (this._adHocAnnotations && this.hasAdHocAnnotationsThroughRef()) {
|
|
1978
|
-
let resolved = decl ? this.doc.mergeIntersection(decl) :
|
|
1979
|
-
if (resolved && (0,
|
|
2039
|
+
let resolved = decl ? this.doc.mergeIntersection(decl) : void 0;
|
|
2040
|
+
if (resolved && (0, _atscript_core.isInterface)(resolved)) resolved = resolved.getDefinition() || resolved;
|
|
1980
2041
|
if (resolved) {
|
|
1981
2042
|
this.annotateType(resolved, name);
|
|
1982
2043
|
return this;
|
|
@@ -1989,45 +2050,35 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1989
2050
|
node: synth.ownerNode
|
|
1990
2051
|
} : this.resolveOwner(this.doc, ref.id);
|
|
1991
2052
|
const refName = synth?.alias ?? ref.id;
|
|
1992
|
-
const
|
|
1993
|
-
const refExpr = isImported ? `() => ${refName}` : refName;
|
|
2053
|
+
const refExpr = !!synth || (ownerDecl ? ownerDecl.doc !== this.doc : false) ? `() => ${refName}` : refName;
|
|
1994
2054
|
this.writeln(`$(${name ? `"", ${name}` : ""})`).indent().writeln(`.refTo(${refExpr}${chain})`);
|
|
1995
2055
|
if (!ref.hasChain) {
|
|
1996
|
-
if (ownerDecl?.node) {
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
this.resolveAnnotationValue(ownerDecl.node, an);
|
|
2000
|
-
});
|
|
2001
|
-
}
|
|
2056
|
+
if (ownerDecl?.node) ownerDecl.doc.filterPassedWhenReferred(ownerDecl.doc.evalAnnotationsForNode(ownerDecl.node))?.forEach((an) => {
|
|
2057
|
+
this.resolveAnnotationValue(ownerDecl.node, an);
|
|
2058
|
+
});
|
|
2002
2059
|
}
|
|
2003
2060
|
this.unindent();
|
|
2004
2061
|
return this;
|
|
2005
2062
|
}
|
|
2006
|
-
case "primitive":
|
|
2063
|
+
case "primitive":
|
|
2007
2064
|
this.definePrimitive(node, name);
|
|
2008
2065
|
return this;
|
|
2009
|
-
|
|
2010
|
-
case "const": {
|
|
2066
|
+
case "const":
|
|
2011
2067
|
this.writeln(`$(${name ? `"", ${name}` : ""})`).indent().defineConst(node).unindent();
|
|
2012
2068
|
return this;
|
|
2013
|
-
|
|
2014
|
-
case "structure": {
|
|
2069
|
+
case "structure":
|
|
2015
2070
|
this.writeln(`$("object"${name ? `, ${name}` : ""})`).indent().defineObject(node).unindent();
|
|
2016
2071
|
return this;
|
|
2017
|
-
|
|
2018
|
-
case "group": {
|
|
2072
|
+
case "group":
|
|
2019
2073
|
kind = node.op === "|" ? "union" : "intersection";
|
|
2020
2074
|
this.writeln(`$("${kind}"${name ? `, ${name}` : ""})`).indent().defineGroup(node).unindent();
|
|
2021
2075
|
return this;
|
|
2022
|
-
|
|
2023
|
-
case "tuple": {
|
|
2076
|
+
case "tuple":
|
|
2024
2077
|
this.writeln(`$("tuple"${name ? `, ${name}` : ""})`).indent().defineGroup(node).unindent();
|
|
2025
2078
|
return this;
|
|
2026
|
-
|
|
2027
|
-
case "array": {
|
|
2079
|
+
case "array":
|
|
2028
2080
|
this.writeln(`$("array"${name ? `, ${name}` : ""})`).indent().defineArray(node).unindent();
|
|
2029
2081
|
return this;
|
|
2030
|
-
}
|
|
2031
2082
|
default: return this;
|
|
2032
2083
|
}
|
|
2033
2084
|
}
|
|
@@ -2051,7 +2102,7 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
2051
2102
|
case "final": return this.writeln(`$(${d()}).designType("${def.value === "void" ? "undefined" : def.value}")`);
|
|
2052
2103
|
case "union":
|
|
2053
2104
|
case "intersection":
|
|
2054
|
-
case "tuple":
|
|
2105
|
+
case "tuple":
|
|
2055
2106
|
this.writeln(`$(${d(def.kind)})`);
|
|
2056
2107
|
this.indent();
|
|
2057
2108
|
for (const itemDef of def.items) {
|
|
@@ -2064,8 +2115,7 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
2064
2115
|
}
|
|
2065
2116
|
this.unindent();
|
|
2066
2117
|
return;
|
|
2067
|
-
|
|
2068
|
-
case "array": {
|
|
2118
|
+
case "array":
|
|
2069
2119
|
this.writeln(`$(${d("array")})`);
|
|
2070
2120
|
this.indent();
|
|
2071
2121
|
this.write(".of(");
|
|
@@ -2076,8 +2126,7 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
2076
2126
|
this.writeln(`)`);
|
|
2077
2127
|
this.unindent();
|
|
2078
2128
|
return;
|
|
2079
|
-
|
|
2080
|
-
case "object": {
|
|
2129
|
+
case "object":
|
|
2081
2130
|
this.writeln(`$(${d("object")})`);
|
|
2082
2131
|
this.indent();
|
|
2083
2132
|
for (const [key, propDef] of Object.entries(def.props)) {
|
|
@@ -2104,7 +2153,6 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
2104
2153
|
}
|
|
2105
2154
|
this.unindent();
|
|
2106
2155
|
return;
|
|
2107
|
-
}
|
|
2108
2156
|
default: return this.writeln(`$(${d()}).designType("any")`);
|
|
2109
2157
|
}
|
|
2110
2158
|
}
|
|
@@ -2146,21 +2194,21 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
2146
2194
|
defineMetadata(node) {
|
|
2147
2195
|
let annotations;
|
|
2148
2196
|
const nodeDef = node.getDefinition?.();
|
|
2149
|
-
if (nodeDef && (0,
|
|
2197
|
+
if (nodeDef && (0, _atscript_core.isRef)(nodeDef)) {
|
|
2150
2198
|
const refNode = nodeDef;
|
|
2151
2199
|
if (!refNode.hasChain) {
|
|
2152
2200
|
const resolved = this.doc.unwindType(refNode.id, refNode.chain)?.def;
|
|
2153
|
-
if (resolved && !(0,
|
|
2154
|
-
else if (resolved && (0,
|
|
2201
|
+
if (resolved && !(0, _atscript_core.isPrimitive)(resolved)) annotations = node.annotations ?? [];
|
|
2202
|
+
else if (resolved && (0, _atscript_core.isPrimitive)(resolved)) {
|
|
2155
2203
|
const ownerDecl = this.doc.getDeclarationOwnerNode(refNode.id);
|
|
2156
2204
|
if (ownerDecl?.node && (ownerDecl.node.entity === "type" || ownerDecl.node.entity === "interface")) annotations = node.annotations ?? [];
|
|
2157
2205
|
}
|
|
2158
2206
|
}
|
|
2159
2207
|
}
|
|
2160
|
-
if (annotations ===
|
|
2208
|
+
if (annotations === void 0) annotations = this.doc.evalAnnotationsForNode(node);
|
|
2161
2209
|
if (this._adHocAnnotations && this._propPath.length > 0) {
|
|
2162
|
-
const path
|
|
2163
|
-
const adHoc = this._adHocAnnotations.get(path
|
|
2210
|
+
const path = this._propPath.join(".");
|
|
2211
|
+
const adHoc = this._adHocAnnotations.get(path);
|
|
2164
2212
|
if (adHoc) annotations = this.doc.mergeNodesAnnotations(annotations, adHoc);
|
|
2165
2213
|
}
|
|
2166
2214
|
annotations?.forEach((an) => {
|
|
@@ -2174,9 +2222,8 @@ else if (resolved && (0, __atscript_core.isPrimitive)(resolved)) {
|
|
|
2174
2222
|
*/ defineMetadataForAnnotateAlias(annotateNode) {
|
|
2175
2223
|
const annotateAnnotations = this.doc.evalAnnotationsForNode(annotateNode);
|
|
2176
2224
|
const targetDecl = this.doc.getDeclarationOwnerNode(annotateNode.targetName);
|
|
2177
|
-
const targetAnnotations = targetDecl?.node ? targetDecl.doc.evalAnnotationsForNode(targetDecl.node) :
|
|
2178
|
-
|
|
2179
|
-
merged.forEach((an) => {
|
|
2225
|
+
const targetAnnotations = targetDecl?.node ? targetDecl.doc.evalAnnotationsForNode(targetDecl.node) : void 0;
|
|
2226
|
+
this.doc.mergeNodesAnnotations(targetAnnotations, annotateAnnotations).forEach((an) => {
|
|
2180
2227
|
this.resolveAnnotationValue(annotateNode, an);
|
|
2181
2228
|
});
|
|
2182
2229
|
return this;
|
|
@@ -2184,14 +2231,12 @@ else if (resolved && (0, __atscript_core.isPrimitive)(resolved)) {
|
|
|
2184
2231
|
resolveAnnotationValue(node, an) {
|
|
2185
2232
|
const { value, multiple } = this.computeAnnotationValue(node, an);
|
|
2186
2233
|
if (multiple) this.writeln(`.annotate("${escapeQuotes(an.name)}", ${value}, true)`);
|
|
2187
|
-
else this.writeln(`.annotate("${escapeQuotes(an.name)}", ${value})`);
|
|
2234
|
+
else this.writeln(`.annotate("${escapeQuotes(an.name)}", ${value})`);
|
|
2188
2235
|
}
|
|
2189
2236
|
emitRefValue(text) {
|
|
2190
2237
|
const dotIdx = text.indexOf(".");
|
|
2191
2238
|
if (dotIdx === -1) return `() => ${text}`;
|
|
2192
|
-
|
|
2193
|
-
const field = text.slice(dotIdx + 1);
|
|
2194
|
-
return `{ type: () => ${typeName}, field: "${escapeQuotes(field)}" }`;
|
|
2239
|
+
return `{ type: () => ${text.slice(0, dotIdx)}, field: "${escapeQuotes(text.slice(dotIdx + 1))}" }`;
|
|
2195
2240
|
}
|
|
2196
2241
|
emitArgValue(aSpec, argToken) {
|
|
2197
2242
|
if (aSpec.type === "ref") return this.emitRefValue(argToken.text);
|
|
@@ -2202,14 +2247,12 @@ else this.writeln(`.annotate("${escapeQuotes(an.name)}", ${value})`);
|
|
|
2202
2247
|
return this.emitQueryExpr(queryNode.expression);
|
|
2203
2248
|
}
|
|
2204
2249
|
emitQueryExpr(node) {
|
|
2205
|
-
if ((0,
|
|
2250
|
+
if ((0, _atscript_core.isQueryLogical)(node)) return this.emitQueryLogical(node);
|
|
2206
2251
|
return this.emitQueryComparison(node);
|
|
2207
2252
|
}
|
|
2208
2253
|
emitQueryLogical(node) {
|
|
2209
2254
|
if (node.operator === "not") return `{ "$not": ${this.emitQueryExpr(node.operands[0])} }`;
|
|
2210
|
-
|
|
2211
|
-
const items = node.operands.map((op) => this.emitQueryExpr(op)).join(", ");
|
|
2212
|
-
return `{ "${key}": [${items}] }`;
|
|
2255
|
+
return `{ "${node.operator === "and" ? "$and" : "$or"}": [${node.operands.map((op) => this.emitQueryExpr(op)).join(", ")}] }`;
|
|
2213
2256
|
}
|
|
2214
2257
|
emitQueryComparison(node) {
|
|
2215
2258
|
const left = this.emitQueryFieldRef(node.left);
|
|
@@ -2217,12 +2260,12 @@ else this.writeln(`.annotate("${escapeQuotes(an.name)}", ${value})`);
|
|
|
2217
2260
|
const parts = [`left: ${left}`, `op: "${mappedOp}"`];
|
|
2218
2261
|
if (node.right) {
|
|
2219
2262
|
if ("fieldRef" in node.right && node.right.fieldRef) parts.push(`right: ${this.emitQueryFieldRef(node.right)}`);
|
|
2220
|
-
else if ("values" in node.right && node.right.values) {
|
|
2263
|
+
else if ("values" in node.right && node.right.values) {
|
|
2221
2264
|
const values = node.right.values.map((v) => this.emitQueryLiteral(v)).join(", ");
|
|
2222
2265
|
parts.push(`right: [${values}]`);
|
|
2223
2266
|
} else if ("valueToken" in node.right) parts.push(`right: ${this.emitQueryLiteral(node.right)}`);
|
|
2224
2267
|
} else if (node.operator === "exists") parts.push("right: true");
|
|
2225
|
-
else if (node.operator === "not exists") parts.push("right: false");
|
|
2268
|
+
else if (node.operator === "not exists") parts.push("right: false");
|
|
2226
2269
|
return `{ ${parts.join(", ")} }`;
|
|
2227
2270
|
}
|
|
2228
2271
|
emitQueryFieldRef(node) {
|
|
@@ -2240,11 +2283,10 @@ else if (node.operator === "not exists") parts.push("right: false");
|
|
|
2240
2283
|
const match = /^\/(.*)\/[a-z]*$/.exec(token.text);
|
|
2241
2284
|
return `"${escapeQuotes(match ? match[1] : token.text)}"`;
|
|
2242
2285
|
}
|
|
2243
|
-
case "identifier":
|
|
2286
|
+
case "identifier":
|
|
2244
2287
|
if (token.text === "true" || token.text === "false") return token.text;
|
|
2245
2288
|
if (token.text === "null" || token.text === "undefined") return "null";
|
|
2246
2289
|
return token.text;
|
|
2247
|
-
}
|
|
2248
2290
|
default: return token.text;
|
|
2249
2291
|
}
|
|
2250
2292
|
}
|
|
@@ -2266,7 +2308,7 @@ else if (node.operator === "not exists") parts.push("right: false");
|
|
|
2266
2308
|
} else {
|
|
2267
2309
|
const aSpec = spec.arguments[0];
|
|
2268
2310
|
if (an.args[0]) targetValue = this.emitArgValue(aSpec, an.args[0]);
|
|
2269
|
-
else targetValue = "true";
|
|
2311
|
+
else targetValue = "true";
|
|
2270
2312
|
}
|
|
2271
2313
|
} else {
|
|
2272
2314
|
multiple = node.countAnnotations(an.name) > 1 || an.args.length > 1;
|
|
@@ -2294,7 +2336,7 @@ else targetValue = "true";
|
|
|
2294
2336
|
accessors
|
|
2295
2337
|
});
|
|
2296
2338
|
}
|
|
2297
|
-
const cloneKeys = new Set();
|
|
2339
|
+
const cloneKeys = /* @__PURE__ */ new Set();
|
|
2298
2340
|
for (const clone of allClones) {
|
|
2299
2341
|
const key = `${clone.parentPath}|${clone.propName}`;
|
|
2300
2342
|
if (!cloneKeys.has(key)) {
|
|
@@ -2308,7 +2350,7 @@ else targetValue = "true";
|
|
|
2308
2350
|
this.writeln();
|
|
2309
2351
|
}
|
|
2310
2352
|
emitMutatingAnnotations(node, annotations, accessor) {
|
|
2311
|
-
const cleared = new Set();
|
|
2353
|
+
const cleared = /* @__PURE__ */ new Set();
|
|
2312
2354
|
for (const an of annotations) {
|
|
2313
2355
|
const { value, multiple } = this.computeAnnotationValue(node, an);
|
|
2314
2356
|
if (multiple) {
|
|
@@ -2323,9 +2365,9 @@ else targetValue = "true";
|
|
|
2323
2365
|
}
|
|
2324
2366
|
resolveTargetDef(targetName) {
|
|
2325
2367
|
const unwound = this.doc.unwindType(targetName);
|
|
2326
|
-
if (!unwound?.def) return
|
|
2368
|
+
if (!unwound?.def) return;
|
|
2327
2369
|
let def = unwound.def;
|
|
2328
|
-
if ((0,
|
|
2370
|
+
if ((0, _atscript_core.isInterface)(def)) def = def.getDefinition() || def;
|
|
2329
2371
|
return def;
|
|
2330
2372
|
}
|
|
2331
2373
|
/**
|
|
@@ -2344,7 +2386,7 @@ else targetValue = "true";
|
|
|
2344
2386
|
for (const { prefix, def } of accessors) {
|
|
2345
2387
|
const results = this.buildPropPaths(def, parts[i]);
|
|
2346
2388
|
if (results.length > 0) for (const result of results) if (i < parts.length - 1) {
|
|
2347
|
-
if (result.propDef && (0,
|
|
2389
|
+
if (result.propDef && (0, _atscript_core.isRef)(result.propDef)) clones.push({
|
|
2348
2390
|
parentPath: prefix,
|
|
2349
2391
|
propName: parts[i]
|
|
2350
2392
|
});
|
|
@@ -2356,11 +2398,11 @@ else targetValue = "true";
|
|
|
2356
2398
|
prefix: `${prefix}${result.path}?`,
|
|
2357
2399
|
def: result.propDef
|
|
2358
2400
|
});
|
|
2359
|
-
else {
|
|
2401
|
+
else {
|
|
2360
2402
|
const suffix = `.props.get("${escapeQuotes(parts[i])}")${i < parts.length - 1 ? "?.type" : "?"}`;
|
|
2361
2403
|
nextAccessors.push({
|
|
2362
2404
|
prefix: `${prefix}${suffix}`,
|
|
2363
|
-
def:
|
|
2405
|
+
def: void 0
|
|
2364
2406
|
});
|
|
2365
2407
|
}
|
|
2366
2408
|
}
|
|
@@ -2378,13 +2420,13 @@ else {
|
|
|
2378
2420
|
*/ buildPropPaths(def, propName) {
|
|
2379
2421
|
if (!def) return [];
|
|
2380
2422
|
def = this.doc.mergeIntersection(def);
|
|
2381
|
-
if ((0,
|
|
2423
|
+
if ((0, _atscript_core.isRef)(def)) {
|
|
2382
2424
|
const ref = def;
|
|
2383
2425
|
const unwound = this.doc.unwindType(ref.id, ref.chain)?.def;
|
|
2384
2426
|
return this.buildPropPaths(unwound, propName);
|
|
2385
2427
|
}
|
|
2386
|
-
if ((0,
|
|
2387
|
-
if ((0,
|
|
2428
|
+
if ((0, _atscript_core.isInterface)(def)) return this.buildPropPaths(def.getDefinition(), propName);
|
|
2429
|
+
if ((0, _atscript_core.isStructure)(def)) {
|
|
2388
2430
|
const prop = def.props.get(propName);
|
|
2389
2431
|
if (prop) return [{
|
|
2390
2432
|
path: `.props.get("${escapeQuotes(propName)}")`,
|
|
@@ -2392,9 +2434,8 @@ else {
|
|
|
2392
2434
|
}];
|
|
2393
2435
|
return [];
|
|
2394
2436
|
}
|
|
2395
|
-
if ((0,
|
|
2396
|
-
const
|
|
2397
|
-
const items = group.unwrap();
|
|
2437
|
+
if ((0, _atscript_core.isGroup)(def)) {
|
|
2438
|
+
const items = def.unwrap();
|
|
2398
2439
|
const results = [];
|
|
2399
2440
|
for (let i = 0; i < items.length; i++) for (const result of this.buildPropPaths(items[i], propName)) results.push({
|
|
2400
2441
|
path: `.items[${i}].type${result.path}`,
|
|
@@ -2405,21 +2446,23 @@ else {
|
|
|
2405
2446
|
return [];
|
|
2406
2447
|
}
|
|
2407
2448
|
constructor(doc, opts) {
|
|
2408
|
-
super(doc), _define_property$3(this, "opts", void 0), _define_property$3(this, "postAnnotate", void 0), _define_property$3(this, "_adHocAnnotations", void 0), _define_property$3(this, "_propPath", void 0), _define_property$3(this, "typeIds", void 0), _define_property$3(this, "_unusedJs", void 0), _define_property$3(this, "_extendsRefs", void 0), _define_property$3(this, "_refSynthInfo", void 0), _define_property$3(this, "_synthImports", void 0), _define_property$3(this, "_synthComputed", void 0), _define_property$3(this, "_ownerCache", void 0), this.opts = opts, this.postAnnotate = [], this._adHocAnnotations = null, this._propPath = [], this.typeIds = new Map(), this._refSynthInfo = new Map(), this._synthImports = new Map(), this._synthComputed = false, this._ownerCache = new Map();
|
|
2449
|
+
super(doc), _define_property$3(this, "opts", void 0), _define_property$3(this, "postAnnotate", void 0), _define_property$3(this, "_adHocAnnotations", void 0), _define_property$3(this, "_propPath", void 0), _define_property$3(this, "typeIds", void 0), _define_property$3(this, "_unusedJs", void 0), _define_property$3(this, "_extendsRefs", void 0), _define_property$3(this, "_refSynthInfo", void 0), _define_property$3(this, "_synthImports", void 0), _define_property$3(this, "_synthComputed", void 0), _define_property$3(this, "_ownerCache", void 0), this.opts = opts, this.postAnnotate = [], this._adHocAnnotations = null, this._propPath = [], this.typeIds = /* @__PURE__ */ new Map(), this._refSynthInfo = /* @__PURE__ */ new Map(), this._synthImports = /* @__PURE__ */ new Map(), this._synthComputed = false, this._ownerCache = /* @__PURE__ */ new Map();
|
|
2409
2450
|
}
|
|
2410
2451
|
};
|
|
2411
2452
|
|
|
2412
2453
|
//#endregion
|
|
2413
2454
|
//#region packages/typescript/src/plugin.ts
|
|
2414
|
-
|
|
2415
|
-
|
|
2455
|
+
/**
|
|
2456
|
+
* Resolves the effective JSON schema mode from plugin options.
|
|
2457
|
+
*/ function resolveJsonSchemaMode(opts) {
|
|
2458
|
+
if (opts?.jsonSchema !== void 0) return opts.jsonSchema;
|
|
2416
2459
|
return false;
|
|
2417
2460
|
}
|
|
2418
2461
|
const tsPlugin = (opts) => {
|
|
2419
2462
|
return {
|
|
2420
2463
|
name: "typescript",
|
|
2421
2464
|
render(doc, format) {
|
|
2422
|
-
if (format === "dts" || format ===
|
|
2465
|
+
if (format === "dts" || format === _atscript_core.DEFAULT_FORMAT) return [{
|
|
2423
2466
|
fileName: `${doc.name}.d.ts`,
|
|
2424
2467
|
content: new TypeRenderer(doc, opts).render()
|
|
2425
2468
|
}];
|
|
@@ -2429,21 +2472,21 @@ const tsPlugin = (opts) => {
|
|
|
2429
2472
|
}];
|
|
2430
2473
|
},
|
|
2431
2474
|
async buildEnd(output, format, repo) {
|
|
2432
|
-
if (format === "dts" || format ===
|
|
2475
|
+
if (format === "dts" || format === _atscript_core.DEFAULT_FORMAT) {
|
|
2433
2476
|
const annotations = await repo.getUsedAnnotations();
|
|
2434
|
-
const tags = await repo.getPrimitivesTags() || new Set();
|
|
2477
|
+
const tags = await repo.getPrimitivesTags() || /* @__PURE__ */ new Set();
|
|
2435
2478
|
const rendered = [];
|
|
2436
2479
|
for (const [key, val] of Object.entries(annotations)) {
|
|
2437
2480
|
const multiple = val.multiple;
|
|
2438
2481
|
const typeLine = Array.from(val.types).map((t) => {
|
|
2439
2482
|
if (t.type === "object" && "props" in t) return `{ ${Object.entries(t.props).map(([k, v]) => `${wrapProp(k)}${v.optional ? "?" : ""}: ${v.type}`).join(", ")} }`;
|
|
2440
|
-
else return "optional" in t && t.optional ? `${t.type} | true` : t.type;
|
|
2483
|
+
else return "optional" in t && t.optional ? `${t.type} | true` : t.type;
|
|
2441
2484
|
}).join(" | ");
|
|
2442
2485
|
rendered.push(`${wrapProp(key)}: ${multiple ? "(" : ""}${typeLine}${multiple ? ")[]" : ""}`);
|
|
2443
2486
|
}
|
|
2444
2487
|
const renderedTags = Array.from(tags).map((f) => `"${escapeQuotes(f)}"`).join(" | ");
|
|
2445
2488
|
output.push({
|
|
2446
|
-
content: "// prettier-ignore-start\n/* eslint-disable */\n/* oxlint-disable */\n/**\n * 🪄 This file was generated by Atscript\n * It is generated based on annotations used in this project\n * Do not edit this file!\n *\n * Use `npx asc -f dts` command to re-generate this file\n */\nexport {}\n\ndeclare global {\n interface AtscriptMetadata {\n " + rendered.join("\n ") + "\n }\n
|
|
2489
|
+
content: "// prettier-ignore-start\n/* eslint-disable */\n/* oxlint-disable */\n/**\n * 🪄 This file was generated by Atscript\n * It is generated based on annotations used in this project\n * Do not edit this file!\n *\n * Use `npx asc -f dts` command to re-generate this file\n */\nexport {}\n\ndeclare global {\n interface AtscriptMetadata {\n " + rendered.join("\n ") + "\n }\n type AtscriptPrimitiveTags = " + renderedTags + "\n}\n// prettier-ignore-end",
|
|
2447
2490
|
fileName: "atscript.d.ts",
|
|
2448
2491
|
source: "",
|
|
2449
2492
|
target: path.default.join(repo.root, "atscript.d.ts")
|
|
@@ -2460,20 +2503,20 @@ async function getConfig(configFile, logger) {
|
|
|
2460
2503
|
if (configFile) {
|
|
2461
2504
|
const c = path.default.join(root, configFile);
|
|
2462
2505
|
if (!(0, fs.existsSync)(c)) {
|
|
2463
|
-
logger.error(`Config file ${
|
|
2506
|
+
logger.error(`Config file [4m${configFile}[24m not found`);
|
|
2464
2507
|
process.exit(1);
|
|
2465
2508
|
}
|
|
2466
|
-
logger.log(`Using config file ${
|
|
2467
|
-
return (0,
|
|
2509
|
+
logger.log(`Using config file [36m${configFile}[39m`);
|
|
2510
|
+
return (0, _atscript_core.loadConfig)(c);
|
|
2468
2511
|
} else {
|
|
2469
|
-
const resolved = await (0,
|
|
2512
|
+
const resolved = await (0, _atscript_core.resolveConfigFile)(root);
|
|
2470
2513
|
if (resolved) {
|
|
2471
|
-
logger.log(`Using config file ${
|
|
2472
|
-
return (0,
|
|
2514
|
+
logger.log(`Using config file [36m${resolved}[39m`);
|
|
2515
|
+
return (0, _atscript_core.loadConfig)(resolved);
|
|
2473
2516
|
}
|
|
2474
2517
|
logger.log(`No atscript config file found`);
|
|
2475
2518
|
return {
|
|
2476
|
-
format:
|
|
2519
|
+
format: _atscript_core.DEFAULT_FORMAT,
|
|
2477
2520
|
plugins: [tsPlugin()]
|
|
2478
2521
|
};
|
|
2479
2522
|
}
|
|
@@ -2488,13 +2531,13 @@ function _define_property$2(obj, key, value) {
|
|
|
2488
2531
|
configurable: true,
|
|
2489
2532
|
writable: true
|
|
2490
2533
|
});
|
|
2491
|
-
else obj[key] = value;
|
|
2534
|
+
else obj[key] = value;
|
|
2492
2535
|
return obj;
|
|
2493
2536
|
}
|
|
2494
2537
|
function _ts_decorate$1(decorators, target, key, desc) {
|
|
2495
2538
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2496
2539
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2497
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2540
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2498
2541
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2499
2542
|
}
|
|
2500
2543
|
function _ts_metadata$1(k, v) {
|
|
@@ -2508,9 +2551,9 @@ function _ts_param$1(paramIndex, decorator) {
|
|
|
2508
2551
|
var Commands = class {
|
|
2509
2552
|
async default(configFile, format, noEmit, skipDiag) {
|
|
2510
2553
|
const config = await getConfig(configFile, this.logger);
|
|
2511
|
-
config.format = format ||
|
|
2512
|
-
this.logger.log(`Format: ${
|
|
2513
|
-
const builder = await (0,
|
|
2554
|
+
config.format = format || _atscript_core.DEFAULT_FORMAT;
|
|
2555
|
+
this.logger.log(`Format: [36m${config.format}[39m`);
|
|
2556
|
+
const builder = await (0, _atscript_core.build)(config);
|
|
2514
2557
|
let errorCount = 0;
|
|
2515
2558
|
let warningCount = 0;
|
|
2516
2559
|
if (!skipDiag) {
|
|
@@ -2519,19 +2562,19 @@ var Commands = class {
|
|
|
2519
2562
|
const doc = builder.getDoc(docId);
|
|
2520
2563
|
for (const m of messages) {
|
|
2521
2564
|
if (m.severity === 1) errorCount++;
|
|
2522
|
-
else if (m.severity === 2) warningCount++;
|
|
2565
|
+
else if (m.severity === 2) warningCount++;
|
|
2523
2566
|
if (doc) this.logger.log(doc.renderDiagMessage(m, true, true));
|
|
2524
2567
|
}
|
|
2525
2568
|
}
|
|
2526
2569
|
}
|
|
2527
2570
|
if (!noEmit) {
|
|
2528
2571
|
const out = await builder.write(config);
|
|
2529
|
-
for (const { target } of out) this.logger.log(`✅ created ${
|
|
2572
|
+
for (const { target } of out) this.logger.log(`✅ created [32m${target}[39m`);
|
|
2530
2573
|
}
|
|
2531
2574
|
if (errorCount > 0 || warningCount > 0) {
|
|
2532
2575
|
const parts = [];
|
|
2533
|
-
if (errorCount > 0) parts.push(
|
|
2534
|
-
if (warningCount > 0) parts.push(
|
|
2576
|
+
if (errorCount > 0) parts.push(`[31m${errorCount} error${errorCount > 1 ? "s" : ""}[39m`);
|
|
2577
|
+
if (warningCount > 0) parts.push(`[33m${warningCount} warning${warningCount > 1 ? "s" : ""}[39m`);
|
|
2535
2578
|
this.logger.log(`\nFound ${parts.join(" and ")}`);
|
|
2536
2579
|
}
|
|
2537
2580
|
if (errorCount > 0) process.exit(1);
|
|
@@ -2542,22 +2585,22 @@ else if (m.severity === 2) warningCount++;
|
|
|
2542
2585
|
}
|
|
2543
2586
|
};
|
|
2544
2587
|
_ts_decorate$1([
|
|
2545
|
-
(0,
|
|
2588
|
+
(0, _moostjs_event_cli.Cli)(""),
|
|
2546
2589
|
(0, moost.Description)("Builds .as files using --config and --format"),
|
|
2547
|
-
(0,
|
|
2548
|
-
(0,
|
|
2549
|
-
(0,
|
|
2550
|
-
(0,
|
|
2551
|
-
_ts_param$1(0, (0,
|
|
2590
|
+
(0, _moostjs_event_cli.CliExample)("-c atscript.config.js", "Build .as files using atscript.config.js"),
|
|
2591
|
+
(0, _moostjs_event_cli.CliExample)("-f dts", "Build \"d.ts\" files for \".as\" files"),
|
|
2592
|
+
(0, _moostjs_event_cli.CliExample)("--noEmit", "Only check for errors, do not emit files"),
|
|
2593
|
+
(0, _moostjs_event_cli.CliExample)("--skipDiag", "Emit files without running diagnostics"),
|
|
2594
|
+
_ts_param$1(0, (0, _moostjs_event_cli.CliOption)("c", "config")),
|
|
2552
2595
|
_ts_param$1(0, (0, moost.Optional)()),
|
|
2553
2596
|
_ts_param$1(0, (0, moost.Description)("Path to config file")),
|
|
2554
|
-
_ts_param$1(1, (0,
|
|
2597
|
+
_ts_param$1(1, (0, _moostjs_event_cli.CliOption)("f", "format")),
|
|
2555
2598
|
_ts_param$1(1, (0, moost.Optional)()),
|
|
2556
2599
|
_ts_param$1(1, (0, moost.Description)("Output format (e.g. js, dts). Omit to run all plugins with their default output.")),
|
|
2557
|
-
_ts_param$1(2, (0,
|
|
2600
|
+
_ts_param$1(2, (0, _moostjs_event_cli.CliOption)("noEmit")),
|
|
2558
2601
|
_ts_param$1(2, (0, moost.Optional)()),
|
|
2559
2602
|
_ts_param$1(2, (0, moost.Description)("Only run diagnostics without emitting files")),
|
|
2560
|
-
_ts_param$1(3, (0,
|
|
2603
|
+
_ts_param$1(3, (0, _moostjs_event_cli.CliOption)("skipDiag")),
|
|
2561
2604
|
_ts_param$1(3, (0, moost.Optional)()),
|
|
2562
2605
|
_ts_param$1(3, (0, moost.Description)("Skip diagnostics and always emit files")),
|
|
2563
2606
|
_ts_metadata$1("design:type", Function),
|
|
@@ -2585,17 +2628,17 @@ function _define_property$1(obj, key, value) {
|
|
|
2585
2628
|
configurable: true,
|
|
2586
2629
|
writable: true
|
|
2587
2630
|
});
|
|
2588
|
-
else obj[key] = value;
|
|
2631
|
+
else obj[key] = value;
|
|
2589
2632
|
return obj;
|
|
2590
2633
|
}
|
|
2591
2634
|
const DYE_COLORS = {
|
|
2592
|
-
green: (s) =>
|
|
2593
|
-
red: (s) =>
|
|
2594
|
-
cyan: (s) =>
|
|
2595
|
-
yellow: (s) =>
|
|
2596
|
-
bold: (s) =>
|
|
2597
|
-
dim: (s) =>
|
|
2598
|
-
underline: (s) =>
|
|
2635
|
+
green: (s) => `[32m${s}[39m`,
|
|
2636
|
+
red: (s) => `[31m${s}[39m`,
|
|
2637
|
+
cyan: (s) => `[36m${s}[39m`,
|
|
2638
|
+
yellow: (s) => `[33m${s}[39m`,
|
|
2639
|
+
bold: (s) => `[1m${s}[22m`,
|
|
2640
|
+
dim: (s) => `[2m${s}[22m`,
|
|
2641
|
+
underline: (s) => `[4m${s}[24m`
|
|
2599
2642
|
};
|
|
2600
2643
|
const BANNER = DYE_COLORS.cyan(`
|
|
2601
2644
|
|
|
@@ -2623,7 +2666,7 @@ const PLAN_HEADER = [
|
|
|
2623
2666
|
DYE_COLORS.bold("╚══════════════════════════════════════╝"),
|
|
2624
2667
|
""
|
|
2625
2668
|
];
|
|
2626
|
-
function planFlags(plan) {
|
|
2669
|
+
/** Plan-level aggregates over the per-entry SyncEntry getters. */ function planFlags(plan) {
|
|
2627
2670
|
return {
|
|
2628
2671
|
destructive: plan.entries.some((e) => e.destructive),
|
|
2629
2672
|
hasChanges: plan.entries.some((e) => e.hasChanges),
|
|
@@ -2690,7 +2733,7 @@ var DbSyncPrinter = class {
|
|
|
2690
2733
|
errors: e.errors
|
|
2691
2734
|
}))
|
|
2692
2735
|
};
|
|
2693
|
-
return `${JSON.stringify(doc,
|
|
2736
|
+
return `${JSON.stringify(doc, void 0, 2)}\n`;
|
|
2694
2737
|
}
|
|
2695
2738
|
/** Renders the plan as a Markdown document (e.g. for PR comments). */ renderMarkdown(plan) {
|
|
2696
2739
|
const { destructive } = planFlags(plan);
|
|
@@ -2739,13 +2782,13 @@ function _define_property(obj, key, value) {
|
|
|
2739
2782
|
configurable: true,
|
|
2740
2783
|
writable: true
|
|
2741
2784
|
});
|
|
2742
|
-
else obj[key] = value;
|
|
2785
|
+
else obj[key] = value;
|
|
2743
2786
|
return obj;
|
|
2744
2787
|
}
|
|
2745
2788
|
function _ts_decorate(decorators, target, key, desc) {
|
|
2746
2789
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
2747
2790
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
2748
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2791
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
2749
2792
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
2750
2793
|
}
|
|
2751
2794
|
function _ts_metadata(k, v) {
|
|
@@ -2762,15 +2805,14 @@ var DbSyncController = class {
|
|
|
2762
2805
|
}
|
|
2763
2806
|
async dbSync(configFile, dryRun, yes, force, safe, check, format, out) {
|
|
2764
2807
|
if (format && format !== "json" && format !== "markdown") {
|
|
2765
|
-
this.logger.error(
|
|
2808
|
+
this.logger.error(`[31mUnknown --format "${format}". Use "json" or "markdown".[39m`);
|
|
2766
2809
|
process.exit(1);
|
|
2767
2810
|
}
|
|
2768
2811
|
this.quiet = Boolean(format) && !out;
|
|
2769
2812
|
this.printer.muted = this.quiet;
|
|
2770
|
-
const
|
|
2771
|
-
const config = await getConfig(configFile, cfgLogger);
|
|
2813
|
+
const config = await getConfig(configFile, this.quiet ? Object.create(this.logger, { log: { value: () => {} } }) : this.logger);
|
|
2772
2814
|
if (!config.db) {
|
|
2773
|
-
this.logger.error(
|
|
2815
|
+
this.logger.error("\x1B[31mNo \"db\" field in atscript config. Add a db configuration to use schema sync.\x1B[39m");
|
|
2774
2816
|
process.exit(1);
|
|
2775
2817
|
}
|
|
2776
2818
|
const [dbSpace, dbTypes] = await Promise.all([this.resolveDbSpace(config.db), this.compileAndLoadTypes(config)]);
|
|
@@ -2795,7 +2837,7 @@ var DbSyncController = class {
|
|
|
2795
2837
|
} else process.stdout.write(doc);
|
|
2796
2838
|
}
|
|
2797
2839
|
if (plan.status === "up-to-date") this.printer.planUpToDate(plan);
|
|
2798
|
-
else {
|
|
2840
|
+
else {
|
|
2799
2841
|
this.printer.plan(plan);
|
|
2800
2842
|
if (hasErrors) {
|
|
2801
2843
|
this.logger.error(`Schema has errors. Fix the issues above before syncing.`);
|
|
@@ -2823,8 +2865,7 @@ else {
|
|
|
2823
2865
|
}
|
|
2824
2866
|
if (hasDestructive) {
|
|
2825
2867
|
if (!yes) {
|
|
2826
|
-
|
|
2827
|
-
if (!confirmed) {
|
|
2868
|
+
if (!await this.confirm("Apply these changes? (includes destructive operations)")) {
|
|
2828
2869
|
this.logger.log("Aborted.");
|
|
2829
2870
|
return;
|
|
2830
2871
|
}
|
|
@@ -2845,9 +2886,7 @@ else {
|
|
|
2845
2886
|
}
|
|
2846
2887
|
buildConfig.format = "js";
|
|
2847
2888
|
this.info(`Compiling .as files...`);
|
|
2848
|
-
const
|
|
2849
|
-
const outputs = await builder.generate(buildConfig);
|
|
2850
|
-
const jsOutputs = outputs.filter((o) => o.fileName.endsWith(".js"));
|
|
2889
|
+
const jsOutputs = (await (await (0, _atscript_core.build)(buildConfig)).generate(buildConfig)).filter((o) => o.fileName.endsWith(".js"));
|
|
2851
2890
|
const tmpDir = path.default.join(process.cwd(), `.atscript-db-sync-${Date.now()}`);
|
|
2852
2891
|
const writtenFiles = [];
|
|
2853
2892
|
for (const o of jsOutputs) {
|
|
@@ -2883,24 +2922,23 @@ else {
|
|
|
2883
2922
|
return await dbConfig();
|
|
2884
2923
|
}
|
|
2885
2924
|
const { adapter, connection, options } = dbConfig;
|
|
2886
|
-
this.info(`Using adapter: ${
|
|
2925
|
+
this.info(`Using adapter: [36m${adapter}[39m`);
|
|
2887
2926
|
let mod;
|
|
2888
2927
|
try {
|
|
2889
2928
|
mod = await this.importFromCwd(adapter);
|
|
2890
2929
|
} catch {
|
|
2891
|
-
this.logger.error(
|
|
2930
|
+
this.logger.error(`[31mCould not import adapter package "${adapter}". Is it installed?[39m`);
|
|
2892
2931
|
process.exit(1);
|
|
2893
2932
|
}
|
|
2894
2933
|
if (typeof mod.createAdapter !== "function") {
|
|
2895
|
-
this.logger.error(
|
|
2934
|
+
this.logger.error(`[31mAdapter package "${adapter}" does not export a createAdapter function.[39m`);
|
|
2896
2935
|
process.exit(1);
|
|
2897
2936
|
}
|
|
2898
2937
|
const resolvedConnection = typeof connection === "function" ? await connection() : connection;
|
|
2899
2938
|
return mod.createAdapter(resolvedConnection, options);
|
|
2900
2939
|
}
|
|
2901
2940
|
async importFromCwd(specifier, preferEsm = false) {
|
|
2902
|
-
|
|
2903
|
-
let resolved = require$1.resolve(specifier);
|
|
2941
|
+
let resolved = (0, node_module.createRequire)(path.default.join(process.cwd(), "__synthetic.cjs")).resolve(specifier);
|
|
2904
2942
|
if (preferEsm) {
|
|
2905
2943
|
const mjsPath = resolved.replace(/\.cjs$/, ".mjs");
|
|
2906
2944
|
if ((0, fs.existsSync)(mjsPath)) resolved = mjsPath;
|
|
@@ -2932,38 +2970,38 @@ else {
|
|
|
2932
2970
|
}
|
|
2933
2971
|
};
|
|
2934
2972
|
_ts_decorate([
|
|
2935
|
-
(0,
|
|
2973
|
+
(0, _moostjs_event_cli.Cli)("db sync"),
|
|
2936
2974
|
(0, moost.Description)("Synchronize database schema with .as type definitions"),
|
|
2937
|
-
(0,
|
|
2938
|
-
(0,
|
|
2939
|
-
(0,
|
|
2940
|
-
(0,
|
|
2941
|
-
(0,
|
|
2942
|
-
(0,
|
|
2943
|
-
(0,
|
|
2944
|
-
(0,
|
|
2945
|
-
_ts_param(0, (0,
|
|
2975
|
+
(0, _moostjs_event_cli.CliExample)("db sync", "Interactive sync — shows plan, prompts, then applies"),
|
|
2976
|
+
(0, _moostjs_event_cli.CliExample)("db sync --dry-run", "Show what would change without applying"),
|
|
2977
|
+
(0, _moostjs_event_cli.CliExample)("db sync --yes", "Skip confirmation prompt (CI mode)"),
|
|
2978
|
+
(0, _moostjs_event_cli.CliExample)("db sync --force", "Re-sync even if schema hash matches"),
|
|
2979
|
+
(0, _moostjs_event_cli.CliExample)("db sync --safe", "Skip destructive operations (column/table drops)"),
|
|
2980
|
+
(0, _moostjs_event_cli.CliExample)("db sync --check", "Exit 1 when changes are needed, 2 when destructive (CI gate)"),
|
|
2981
|
+
(0, _moostjs_event_cli.CliExample)("db sync --format json", "Emit the plan as JSON to stdout, do not apply"),
|
|
2982
|
+
(0, _moostjs_event_cli.CliExample)("db sync --format markdown --out plan.md", "Write the plan as Markdown to a file"),
|
|
2983
|
+
_ts_param(0, (0, _moostjs_event_cli.CliOption)("c", "config")),
|
|
2946
2984
|
_ts_param(0, (0, moost.Optional)()),
|
|
2947
2985
|
_ts_param(0, (0, moost.Description)("Path to config file")),
|
|
2948
|
-
_ts_param(1, (0,
|
|
2986
|
+
_ts_param(1, (0, _moostjs_event_cli.CliOption)("dry-run")),
|
|
2949
2987
|
_ts_param(1, (0, moost.Optional)()),
|
|
2950
2988
|
_ts_param(1, (0, moost.Description)("Show plan only, do not apply changes")),
|
|
2951
|
-
_ts_param(2, (0,
|
|
2989
|
+
_ts_param(2, (0, _moostjs_event_cli.CliOption)("yes")),
|
|
2952
2990
|
_ts_param(2, (0, moost.Optional)()),
|
|
2953
2991
|
_ts_param(2, (0, moost.Description)("Skip confirmation prompt (CI mode)")),
|
|
2954
|
-
_ts_param(3, (0,
|
|
2992
|
+
_ts_param(3, (0, _moostjs_event_cli.CliOption)("force")),
|
|
2955
2993
|
_ts_param(3, (0, moost.Optional)()),
|
|
2956
2994
|
_ts_param(3, (0, moost.Description)("Ignore schema hash, re-sync even if up-to-date")),
|
|
2957
|
-
_ts_param(4, (0,
|
|
2995
|
+
_ts_param(4, (0, _moostjs_event_cli.CliOption)("safe")),
|
|
2958
2996
|
_ts_param(4, (0, moost.Optional)()),
|
|
2959
2997
|
_ts_param(4, (0, moost.Description)("Skip destructive operations (column/table drops)")),
|
|
2960
|
-
_ts_param(5, (0,
|
|
2998
|
+
_ts_param(5, (0, _moostjs_event_cli.CliOption)("check")),
|
|
2961
2999
|
_ts_param(5, (0, moost.Optional)()),
|
|
2962
3000
|
_ts_param(5, (0, moost.Description)("Plan only; exit 1 when changes are needed, 2 when destructive changes are present")),
|
|
2963
|
-
_ts_param(6, (0,
|
|
3001
|
+
_ts_param(6, (0, _moostjs_event_cli.CliOption)("f", "format")),
|
|
2964
3002
|
_ts_param(6, (0, moost.Optional)()),
|
|
2965
3003
|
_ts_param(6, (0, moost.Description)("Emit the plan as \"json\" or \"markdown\" instead of applying (plan-only mode)")),
|
|
2966
|
-
_ts_param(7, (0,
|
|
3004
|
+
_ts_param(7, (0, _moostjs_event_cli.CliOption)("out")),
|
|
2967
3005
|
_ts_param(7, (0, moost.Optional)()),
|
|
2968
3006
|
_ts_param(7, (0, moost.Description)("Write --format output to a file instead of stdout")),
|
|
2969
3007
|
_ts_metadata("design:type", Function),
|
|
@@ -2991,7 +3029,7 @@ function patchAsImports(content) {
|
|
|
2991
3029
|
|
|
2992
3030
|
//#endregion
|
|
2993
3031
|
//#region packages/typescript/src/cli/cli.ts
|
|
2994
|
-
new
|
|
3032
|
+
new _moostjs_event_cli.CliApp().controllers(Commands, DbSyncController).useHelp({ name: "asc" }).useOptions([{
|
|
2995
3033
|
keys: ["help"],
|
|
2996
3034
|
description: "Display instructions for the command."
|
|
2997
3035
|
}]).start();
|