@atscript/typescript 0.1.17 → 0.1.18
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 +63 -42
- package/dist/index.cjs +58 -37
- package/dist/index.mjs +58 -37
- package/dist/utils.cjs +35 -16
- package/dist/utils.d.ts +5 -5
- package/dist/utils.mjs +35 -16
- package/package.json +42 -42
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { isArray, isConst, isGroup, isInterface, isPrimitive, isRef, isStructure } from "@atscript/core";
|
|
2
1
|
import path from "path";
|
|
2
|
+
import { DEFAULT_FORMAT, isArray, isConst, isGroup, isInterface, isPrimitive, isRef, isStructure } from "@atscript/core";
|
|
3
3
|
|
|
4
4
|
//#region packages/typescript/src/codegen/code-printer.ts
|
|
5
5
|
function _define_property$4(obj, key, value) {
|
|
@@ -84,7 +84,7 @@ else if (this.currentLine.length > 0) this.lines.push(this.currentLine);
|
|
|
84
84
|
return this;
|
|
85
85
|
}
|
|
86
86
|
doPop(withNewLine) {
|
|
87
|
-
if (
|
|
87
|
+
if (this.blockStack.length === 0) throw new Error("No block to pop (stack is empty).");
|
|
88
88
|
const closing = this.blockStack.pop();
|
|
89
89
|
this.unindent();
|
|
90
90
|
if (withNewLine) this.writeln(closing);
|
|
@@ -283,7 +283,7 @@ var TypeRenderer = class TypeRenderer extends BaseRenderer {
|
|
|
283
283
|
propsDefs.add(renderedDef);
|
|
284
284
|
renderedDef.split("\n").forEach((l) => this.writeln(l));
|
|
285
285
|
}
|
|
286
|
-
if (patterns.length) {
|
|
286
|
+
if (patterns.length > 0) {
|
|
287
287
|
this.write(`[key: string]: `);
|
|
288
288
|
if (patterns.length > 0) {
|
|
289
289
|
for (const prop of patterns) propsDefs.add(this.renderTypeDefString(prop.getDefinition()));
|
|
@@ -561,7 +561,7 @@ var Validator = class {
|
|
|
561
561
|
}
|
|
562
562
|
let i = 0;
|
|
563
563
|
for (const item of def.type.items) {
|
|
564
|
-
this.push(
|
|
564
|
+
this.push(String(i));
|
|
565
565
|
if (!this.validateSafe(item, value[i])) {
|
|
566
566
|
this.pop(true);
|
|
567
567
|
return false;
|
|
@@ -597,7 +597,7 @@ var Validator = class {
|
|
|
597
597
|
let i = 0;
|
|
598
598
|
let passed = true;
|
|
599
599
|
for (const item of value) {
|
|
600
|
-
this.push(
|
|
600
|
+
this.push(String(i));
|
|
601
601
|
if (!this.validateSafe(def.type.of, item)) {
|
|
602
602
|
passed = false;
|
|
603
603
|
this.pop(true);
|
|
@@ -649,7 +649,7 @@ else {
|
|
|
649
649
|
pattern,
|
|
650
650
|
def: propDef
|
|
651
651
|
});
|
|
652
|
-
if (matched.length) {
|
|
652
|
+
if (matched.length > 0) {
|
|
653
653
|
let keyPassed = false;
|
|
654
654
|
for (const { def: def$1 } of matched) if (this.validateSafe(def$1, value[key])) {
|
|
655
655
|
this.pop(false);
|
|
@@ -676,7 +676,7 @@ else {
|
|
|
676
676
|
return passed;
|
|
677
677
|
}
|
|
678
678
|
validatePrimitive(def, value) {
|
|
679
|
-
if (
|
|
679
|
+
if (def.type.value !== undefined) {
|
|
680
680
|
if (value !== def.type.value) {
|
|
681
681
|
this.error(`Expected ${def.type.value}, got ${value}`);
|
|
682
682
|
return false;
|
|
@@ -685,40 +685,46 @@ else {
|
|
|
685
685
|
}
|
|
686
686
|
const typeOfValue = Array.isArray(value) ? "array" : typeof value;
|
|
687
687
|
switch (def.type.designType) {
|
|
688
|
-
case "never":
|
|
688
|
+
case "never": {
|
|
689
689
|
this.error(`This type is impossible, must be an internal problem`);
|
|
690
690
|
return false;
|
|
691
|
+
}
|
|
691
692
|
case "any": return true;
|
|
692
|
-
case "string":
|
|
693
|
+
case "string": {
|
|
693
694
|
if (typeOfValue !== def.type.designType) {
|
|
694
695
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
695
696
|
return false;
|
|
696
697
|
}
|
|
697
698
|
return this.validateString(def, value);
|
|
698
|
-
|
|
699
|
+
}
|
|
700
|
+
case "number": {
|
|
699
701
|
if (typeOfValue !== def.type.designType) {
|
|
700
702
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
701
703
|
return false;
|
|
702
704
|
}
|
|
703
705
|
return this.validateNumber(def, value);
|
|
704
|
-
|
|
706
|
+
}
|
|
707
|
+
case "boolean": {
|
|
705
708
|
if (typeOfValue !== def.type.designType) {
|
|
706
709
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
707
710
|
return false;
|
|
708
711
|
}
|
|
709
712
|
return this.validateBoolean(def, value);
|
|
710
|
-
|
|
713
|
+
}
|
|
714
|
+
case "undefined": {
|
|
711
715
|
if (value !== undefined) {
|
|
712
716
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
713
717
|
return false;
|
|
714
718
|
}
|
|
715
719
|
return true;
|
|
716
|
-
|
|
720
|
+
}
|
|
721
|
+
case "null": {
|
|
717
722
|
if (value !== null) {
|
|
718
723
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
719
724
|
return false;
|
|
720
725
|
}
|
|
721
726
|
return true;
|
|
727
|
+
}
|
|
722
728
|
default: throw new Error(`Unknown type "${def.type.designType}"`);
|
|
723
729
|
}
|
|
724
730
|
}
|
|
@@ -973,7 +979,7 @@ function buildJsonSchema(type) {
|
|
|
973
979
|
type: "object",
|
|
974
980
|
properties
|
|
975
981
|
};
|
|
976
|
-
if (required.length) schema.required = required;
|
|
982
|
+
if (required.length > 0) schema.required = required;
|
|
977
983
|
return schema;
|
|
978
984
|
},
|
|
979
985
|
array(d) {
|
|
@@ -1236,34 +1242,39 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1236
1242
|
annotations?.forEach((a) => {
|
|
1237
1243
|
switch (a.name) {
|
|
1238
1244
|
case "expect.minLength":
|
|
1239
|
-
case "expect.maxLength":
|
|
1245
|
+
case "expect.maxLength": {
|
|
1240
1246
|
if (a.args[0]) handle.annotate(a.name, {
|
|
1241
1247
|
length: Number(a.args[0].text),
|
|
1242
1248
|
message: a.args[1]?.text
|
|
1243
1249
|
});
|
|
1244
1250
|
break;
|
|
1245
|
-
|
|
1251
|
+
}
|
|
1252
|
+
case "expect.min": {
|
|
1246
1253
|
if (a.args[0]) handle.annotate(a.name, {
|
|
1247
1254
|
minValue: Number(a.args[0].text),
|
|
1248
1255
|
message: a.args[1]?.text
|
|
1249
1256
|
});
|
|
1250
1257
|
break;
|
|
1251
|
-
|
|
1258
|
+
}
|
|
1259
|
+
case "expect.max": {
|
|
1252
1260
|
if (a.args[0]) handle.annotate(a.name, {
|
|
1253
1261
|
maxValue: Number(a.args[0].text),
|
|
1254
1262
|
message: a.args[1]?.text
|
|
1255
1263
|
});
|
|
1256
1264
|
break;
|
|
1257
|
-
|
|
1265
|
+
}
|
|
1266
|
+
case "expect.pattern": {
|
|
1258
1267
|
handle.annotate(a.name, {
|
|
1259
1268
|
pattern: a.args[0]?.text || "",
|
|
1260
1269
|
flags: a.args[1]?.text,
|
|
1261
1270
|
message: a.args[2]?.text
|
|
1262
1271
|
}, true);
|
|
1263
1272
|
break;
|
|
1264
|
-
|
|
1273
|
+
}
|
|
1274
|
+
case "expect.int": {
|
|
1265
1275
|
handle.annotate(a.name, true);
|
|
1266
1276
|
break;
|
|
1277
|
+
}
|
|
1267
1278
|
default:
|
|
1268
1279
|
}
|
|
1269
1280
|
});
|
|
@@ -1278,8 +1289,11 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1278
1289
|
const ref = node;
|
|
1279
1290
|
const decl = this.doc.unwindType(ref.id, ref.chain)?.def;
|
|
1280
1291
|
if (isPrimitive(decl)) {
|
|
1281
|
-
this.
|
|
1282
|
-
|
|
1292
|
+
const ownerDecl = this.doc.getDeclarationOwnerNode(ref.id);
|
|
1293
|
+
if (!ownerDecl?.node || ownerDecl.node.entity !== "type" && ownerDecl.node.entity !== "interface") {
|
|
1294
|
+
this.annotateType(decl, name);
|
|
1295
|
+
return this;
|
|
1296
|
+
}
|
|
1283
1297
|
}
|
|
1284
1298
|
const chain = ref.hasChain ? `, [${ref.chain.map((c) => `"${escapeQuotes(c.text)}"`).join(", ")}]` : "";
|
|
1285
1299
|
this.writeln(`$(${name ? `"", ${name}` : ""})`).indent().writeln(`.refTo(${ref.id}${chain})`);
|
|
@@ -1321,7 +1335,7 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1321
1335
|
return this;
|
|
1322
1336
|
}
|
|
1323
1337
|
default: {
|
|
1324
|
-
console.log("!!!!!!! UNKNOWN
|
|
1338
|
+
console.log("!!!!!!! UNKNOWN", node.entity);
|
|
1325
1339
|
return this;
|
|
1326
1340
|
}
|
|
1327
1341
|
}
|
|
@@ -1346,7 +1360,7 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1346
1360
|
case "final": return this.writeln(`$(${d()}).designType("${def.value === "void" ? "undefined" : def.value}")`);
|
|
1347
1361
|
case "union":
|
|
1348
1362
|
case "intersection":
|
|
1349
|
-
case "tuple":
|
|
1363
|
+
case "tuple": {
|
|
1350
1364
|
this.writeln(`$(${d(def.kind)})`);
|
|
1351
1365
|
this.indent();
|
|
1352
1366
|
for (const itemDef of def.items) {
|
|
@@ -1359,7 +1373,8 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1359
1373
|
}
|
|
1360
1374
|
this.unindent();
|
|
1361
1375
|
return;
|
|
1362
|
-
|
|
1376
|
+
}
|
|
1377
|
+
case "array": {
|
|
1363
1378
|
this.writeln(`$(${d("array")})`);
|
|
1364
1379
|
this.indent();
|
|
1365
1380
|
this.write(".of(");
|
|
@@ -1370,7 +1385,8 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1370
1385
|
this.writeln(`)`);
|
|
1371
1386
|
this.unindent();
|
|
1372
1387
|
return;
|
|
1373
|
-
|
|
1388
|
+
}
|
|
1389
|
+
case "object": {
|
|
1374
1390
|
this.writeln(`$(${d("object")})`);
|
|
1375
1391
|
this.indent();
|
|
1376
1392
|
for (const [key, propDef] of Object.entries(def.props)) {
|
|
@@ -1397,6 +1413,7 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1397
1413
|
}
|
|
1398
1414
|
this.unindent();
|
|
1399
1415
|
return;
|
|
1416
|
+
}
|
|
1400
1417
|
default: return this.writeln(`$(${d()}).designType("any")`);
|
|
1401
1418
|
}
|
|
1402
1419
|
}
|
|
@@ -1443,6 +1460,10 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1443
1460
|
if (!refNode.hasChain) {
|
|
1444
1461
|
const resolved = this.doc.unwindType(refNode.id, refNode.chain)?.def;
|
|
1445
1462
|
if (resolved && !isPrimitive(resolved)) annotations = node.annotations ?? [];
|
|
1463
|
+
else if (resolved && isPrimitive(resolved)) {
|
|
1464
|
+
const ownerDecl = this.doc.getDeclarationOwnerNode(refNode.id);
|
|
1465
|
+
if (ownerDecl?.node && (ownerDecl.node.entity === "type" || ownerDecl.node.entity === "interface")) annotations = node.annotations ?? [];
|
|
1466
|
+
}
|
|
1446
1467
|
}
|
|
1447
1468
|
}
|
|
1448
1469
|
if (annotations === undefined) annotations = this.doc.evalAnnotationsForNode(node);
|
|
@@ -1496,7 +1517,7 @@ else targetValue = "true";
|
|
|
1496
1517
|
}
|
|
1497
1518
|
} else {
|
|
1498
1519
|
multiple = node.countAnnotations(an.name) > 1 || an.args.length > 1;
|
|
1499
|
-
if (an.args.length) targetValue = an.args[0].type === "text" ? `"${escapeQuotes(an.args[0].text)}"` : an.args[0].text;
|
|
1520
|
+
if (an.args.length > 0) targetValue = an.args[0].type === "text" ? `"${escapeQuotes(an.args[0].text)}"` : an.args[0].text;
|
|
1500
1521
|
}
|
|
1501
1522
|
return {
|
|
1502
1523
|
value: targetValue,
|
|
@@ -1558,7 +1579,7 @@ else targetValue = "true";
|
|
|
1558
1579
|
* Returns multiple paths when a property appears in multiple union branches.
|
|
1559
1580
|
*/ buildMutatingAccessors(targetName, targetDef, parts) {
|
|
1560
1581
|
let accessors = [{
|
|
1561
|
-
prefix: targetName
|
|
1582
|
+
prefix: `${targetName}.type`,
|
|
1562
1583
|
def: targetDef
|
|
1563
1584
|
}];
|
|
1564
1585
|
for (let i = 0; i < parts.length; i++) {
|
|
@@ -1566,17 +1587,17 @@ else targetValue = "true";
|
|
|
1566
1587
|
for (const { prefix, def } of accessors) {
|
|
1567
1588
|
const results = this.buildPropPaths(def, parts[i]);
|
|
1568
1589
|
if (results.length > 0) for (const result of results) if (i < parts.length - 1) nextAccessors.push({
|
|
1569
|
-
prefix: prefix
|
|
1590
|
+
prefix: `${prefix}${result.path}?.type`,
|
|
1570
1591
|
def: result.propDef
|
|
1571
1592
|
});
|
|
1572
1593
|
else nextAccessors.push({
|
|
1573
|
-
prefix: prefix
|
|
1594
|
+
prefix: `${prefix}${result.path}?`,
|
|
1574
1595
|
def: result.propDef
|
|
1575
1596
|
});
|
|
1576
1597
|
else {
|
|
1577
|
-
const suffix = `.props.get("${escapeQuotes(parts[i])}")
|
|
1598
|
+
const suffix = `.props.get("${escapeQuotes(parts[i])}")${i < parts.length - 1 ? "?.type" : "?"}`;
|
|
1578
1599
|
nextAccessors.push({
|
|
1579
|
-
prefix: prefix
|
|
1600
|
+
prefix: `${prefix}${suffix}`,
|
|
1580
1601
|
def: undefined
|
|
1581
1602
|
});
|
|
1582
1603
|
}
|
|
@@ -1631,9 +1652,9 @@ function resolveJsonSchemaMode(opts) {
|
|
|
1631
1652
|
}
|
|
1632
1653
|
const tsPlugin = (opts) => {
|
|
1633
1654
|
return {
|
|
1634
|
-
name: "
|
|
1655
|
+
name: "typescript",
|
|
1635
1656
|
render(doc, format) {
|
|
1636
|
-
if (format === "dts") return [{
|
|
1657
|
+
if (format === "dts" || format === DEFAULT_FORMAT) return [{
|
|
1637
1658
|
fileName: `${doc.name}.d.ts`,
|
|
1638
1659
|
content: new TypeRenderer(doc, opts).render()
|
|
1639
1660
|
}];
|
|
@@ -1643,19 +1664,19 @@ const tsPlugin = (opts) => {
|
|
|
1643
1664
|
}];
|
|
1644
1665
|
},
|
|
1645
1666
|
async buildEnd(output, format, repo) {
|
|
1646
|
-
if (format === "dts") {
|
|
1667
|
+
if (format === "dts" || format === DEFAULT_FORMAT) {
|
|
1647
1668
|
const annotations = await repo.getUsedAnnotations();
|
|
1648
1669
|
const tags = await repo.getPrimitivesTags() || new Set();
|
|
1649
|
-
|
|
1670
|
+
const rendered = [];
|
|
1650
1671
|
for (const [key, val] of Object.entries(annotations)) {
|
|
1651
1672
|
const multiple = val.multiple;
|
|
1652
|
-
|
|
1673
|
+
const typeLine = Array.from(val.types).map((t) => {
|
|
1653
1674
|
if (t.type === "object") return `{ ${Object.entries(t.props).map(([k, v]) => `${wrapProp(k)}${v.optional ? "?" : ""}: ${v.type}`).join(", ")} }`;
|
|
1654
1675
|
else return t.optional ? `${t.type} | true` : t.type;
|
|
1655
1676
|
}).join(" | ");
|
|
1656
1677
|
rendered.push(`${wrapProp(key)}: ${multiple ? "(" : ""}${typeLine}${multiple ? ")[]" : ""}`);
|
|
1657
1678
|
}
|
|
1658
|
-
|
|
1679
|
+
const renderedTags = Array.from(tags).map((f) => `"${escapeQuotes(f)}"`).join(" | ");
|
|
1659
1680
|
output.push({
|
|
1660
1681
|
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",
|
|
1661
1682
|
fileName: "atscript.d.ts",
|
package/dist/utils.cjs
CHANGED
|
@@ -140,7 +140,7 @@ var Validator = class {
|
|
|
140
140
|
}
|
|
141
141
|
let i = 0;
|
|
142
142
|
for (const item of def.type.items) {
|
|
143
|
-
this.push(
|
|
143
|
+
this.push(String(i));
|
|
144
144
|
if (!this.validateSafe(item, value[i])) {
|
|
145
145
|
this.pop(true);
|
|
146
146
|
return false;
|
|
@@ -176,7 +176,7 @@ var Validator = class {
|
|
|
176
176
|
let i = 0;
|
|
177
177
|
let passed = true;
|
|
178
178
|
for (const item of value) {
|
|
179
|
-
this.push(
|
|
179
|
+
this.push(String(i));
|
|
180
180
|
if (!this.validateSafe(def.type.of, item)) {
|
|
181
181
|
passed = false;
|
|
182
182
|
this.pop(true);
|
|
@@ -228,7 +228,7 @@ else {
|
|
|
228
228
|
pattern,
|
|
229
229
|
def: propDef
|
|
230
230
|
});
|
|
231
|
-
if (matched.length) {
|
|
231
|
+
if (matched.length > 0) {
|
|
232
232
|
let keyPassed = false;
|
|
233
233
|
for (const { def: def$1 } of matched) if (this.validateSafe(def$1, value[key])) {
|
|
234
234
|
this.pop(false);
|
|
@@ -255,7 +255,7 @@ else {
|
|
|
255
255
|
return passed;
|
|
256
256
|
}
|
|
257
257
|
validatePrimitive(def, value) {
|
|
258
|
-
if (
|
|
258
|
+
if (def.type.value !== undefined) {
|
|
259
259
|
if (value !== def.type.value) {
|
|
260
260
|
this.error(`Expected ${def.type.value}, got ${value}`);
|
|
261
261
|
return false;
|
|
@@ -264,40 +264,46 @@ else {
|
|
|
264
264
|
}
|
|
265
265
|
const typeOfValue = Array.isArray(value) ? "array" : typeof value;
|
|
266
266
|
switch (def.type.designType) {
|
|
267
|
-
case "never":
|
|
267
|
+
case "never": {
|
|
268
268
|
this.error(`This type is impossible, must be an internal problem`);
|
|
269
269
|
return false;
|
|
270
|
+
}
|
|
270
271
|
case "any": return true;
|
|
271
|
-
case "string":
|
|
272
|
+
case "string": {
|
|
272
273
|
if (typeOfValue !== def.type.designType) {
|
|
273
274
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
274
275
|
return false;
|
|
275
276
|
}
|
|
276
277
|
return this.validateString(def, value);
|
|
277
|
-
|
|
278
|
+
}
|
|
279
|
+
case "number": {
|
|
278
280
|
if (typeOfValue !== def.type.designType) {
|
|
279
281
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
280
282
|
return false;
|
|
281
283
|
}
|
|
282
284
|
return this.validateNumber(def, value);
|
|
283
|
-
|
|
285
|
+
}
|
|
286
|
+
case "boolean": {
|
|
284
287
|
if (typeOfValue !== def.type.designType) {
|
|
285
288
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
286
289
|
return false;
|
|
287
290
|
}
|
|
288
291
|
return this.validateBoolean(def, value);
|
|
289
|
-
|
|
292
|
+
}
|
|
293
|
+
case "undefined": {
|
|
290
294
|
if (value !== undefined) {
|
|
291
295
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
292
296
|
return false;
|
|
293
297
|
}
|
|
294
298
|
return true;
|
|
295
|
-
|
|
299
|
+
}
|
|
300
|
+
case "null": {
|
|
296
301
|
if (value !== null) {
|
|
297
302
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
298
303
|
return false;
|
|
299
304
|
}
|
|
300
305
|
return true;
|
|
306
|
+
}
|
|
301
307
|
default: throw new Error(`Unknown type "${def.type.designType}"`);
|
|
302
308
|
}
|
|
303
309
|
}
|
|
@@ -565,7 +571,7 @@ function buildJsonSchema(type) {
|
|
|
565
571
|
type: "object",
|
|
566
572
|
properties
|
|
567
573
|
};
|
|
568
|
-
if (required.length) schema.required = required;
|
|
574
|
+
if (required.length > 0) schema.required = required;
|
|
569
575
|
return schema;
|
|
570
576
|
},
|
|
571
577
|
array(d) {
|
|
@@ -742,28 +748,32 @@ else flatUnion.item(existing);
|
|
|
742
748
|
}
|
|
743
749
|
case "union":
|
|
744
750
|
case "intersection":
|
|
745
|
-
case "tuple":
|
|
751
|
+
case "tuple": {
|
|
746
752
|
for (const item of def.type.items) flattenArray(item, name);
|
|
747
753
|
break;
|
|
748
|
-
|
|
754
|
+
}
|
|
755
|
+
case "array": {
|
|
749
756
|
flattenArray(def.type.of, name);
|
|
750
757
|
break;
|
|
758
|
+
}
|
|
751
759
|
default:
|
|
752
760
|
}
|
|
753
761
|
}
|
|
754
762
|
function flattenType(def, prefix = "", inComplexTypeOrArray = false) {
|
|
755
763
|
switch (def.type.kind) {
|
|
756
|
-
case "object":
|
|
764
|
+
case "object": {
|
|
757
765
|
addFieldToFlatMap(prefix || "", def);
|
|
758
766
|
for (const [key, value] of def.type.props.entries()) {
|
|
759
767
|
if (skipPhantom && isPhantomType(value)) continue;
|
|
760
768
|
flattenType(value, prefix ? `${prefix}.${key}` : key, inComplexTypeOrArray);
|
|
761
769
|
}
|
|
762
770
|
break;
|
|
771
|
+
}
|
|
763
772
|
case "array": {
|
|
764
773
|
let typeArray = def;
|
|
765
774
|
if (!inComplexTypeOrArray) {
|
|
766
775
|
typeArray = defineAnnotatedType().refTo(def).copyMetadata(def.metadata).$type;
|
|
776
|
+
if (def.optional) typeArray.optional = def.optional;
|
|
767
777
|
if (options?.topLevelArrayTag) typeArray.metadata.set(options.topLevelArrayTag, true);
|
|
768
778
|
}
|
|
769
779
|
addFieldToFlatMap(prefix || "", typeArray);
|
|
@@ -772,10 +782,19 @@ else flatUnion.item(existing);
|
|
|
772
782
|
}
|
|
773
783
|
case "intersection":
|
|
774
784
|
case "tuple":
|
|
775
|
-
case "union":
|
|
776
|
-
|
|
785
|
+
case "union": {
|
|
786
|
+
for (const item of def.type.items) flattenType(item, prefix, true);
|
|
777
787
|
addFieldToFlatMap(prefix || "", def);
|
|
788
|
+
if (def.optional) {
|
|
789
|
+
const entry = flatMap.get(prefix || "");
|
|
790
|
+
if (entry) entry.optional = def.optional;
|
|
791
|
+
}
|
|
778
792
|
break;
|
|
793
|
+
}
|
|
794
|
+
default: {
|
|
795
|
+
addFieldToFlatMap(prefix || "", def);
|
|
796
|
+
break;
|
|
797
|
+
}
|
|
779
798
|
}
|
|
780
799
|
if (prefix) options?.onField?.(prefix, def, def.metadata);
|
|
781
800
|
}
|
package/dist/utils.d.ts
CHANGED
|
@@ -119,10 +119,10 @@ interface TAtscriptTypeArray<DataType = unknown[]> {
|
|
|
119
119
|
interface TAtscriptTypeObject<K extends string = string, DataType = Record<K, unknown>> {
|
|
120
120
|
kind: 'object';
|
|
121
121
|
props: Map<K, TAtscriptAnnotatedType>;
|
|
122
|
-
propsPatterns: {
|
|
122
|
+
propsPatterns: Array<{
|
|
123
123
|
pattern: RegExp;
|
|
124
124
|
def: TAtscriptAnnotatedType;
|
|
125
|
-
}
|
|
125
|
+
}>;
|
|
126
126
|
tags: Set<AtscriptPrimitiveTags>;
|
|
127
127
|
/** @internal phantom — carries the DataType at the type level, never set at runtime */
|
|
128
128
|
__dataType?: DataType;
|
|
@@ -176,7 +176,7 @@ declare function isAnnotatedType(type: any): type is TAtscriptAnnotatedType;
|
|
|
176
176
|
* Standalone annotate function that handles both replace and append (array) strategies.
|
|
177
177
|
* Used by the handle's .annotate() method and by generated mutation statements.
|
|
178
178
|
*/
|
|
179
|
-
declare function annotate<K extends keyof AtscriptMetadata>(metadata: TMetadataMap<AtscriptMetadata> | undefined, key: K, value: AtscriptMetadata[K] extends
|
|
179
|
+
declare function annotate<K extends keyof AtscriptMetadata>(metadata: TMetadataMap<AtscriptMetadata> | undefined, key: K, value: AtscriptMetadata[K] extends Array<infer E> ? E : AtscriptMetadata[K], asArray?: boolean): void;
|
|
180
180
|
type TKind = '' | 'array' | 'object' | 'union' | 'intersection' | 'tuple';
|
|
181
181
|
/**
|
|
182
182
|
* Creates a builder handle for constructing a {@link TAtscriptAnnotatedType} at runtime.
|
|
@@ -368,13 +368,13 @@ interface TSerializedTypeFinal {
|
|
|
368
368
|
interface TSerializedTypeObject {
|
|
369
369
|
kind: 'object';
|
|
370
370
|
props: Record<string, TSerializedAnnotatedTypeInner>;
|
|
371
|
-
propsPatterns: {
|
|
371
|
+
propsPatterns: Array<{
|
|
372
372
|
pattern: {
|
|
373
373
|
source: string;
|
|
374
374
|
flags: string;
|
|
375
375
|
};
|
|
376
376
|
def: TSerializedAnnotatedTypeInner;
|
|
377
|
-
}
|
|
377
|
+
}>;
|
|
378
378
|
tags: string[];
|
|
379
379
|
}
|
|
380
380
|
interface TSerializedTypeArray {
|
package/dist/utils.mjs
CHANGED
|
@@ -139,7 +139,7 @@ var Validator = class {
|
|
|
139
139
|
}
|
|
140
140
|
let i = 0;
|
|
141
141
|
for (const item of def.type.items) {
|
|
142
|
-
this.push(
|
|
142
|
+
this.push(String(i));
|
|
143
143
|
if (!this.validateSafe(item, value[i])) {
|
|
144
144
|
this.pop(true);
|
|
145
145
|
return false;
|
|
@@ -175,7 +175,7 @@ var Validator = class {
|
|
|
175
175
|
let i = 0;
|
|
176
176
|
let passed = true;
|
|
177
177
|
for (const item of value) {
|
|
178
|
-
this.push(
|
|
178
|
+
this.push(String(i));
|
|
179
179
|
if (!this.validateSafe(def.type.of, item)) {
|
|
180
180
|
passed = false;
|
|
181
181
|
this.pop(true);
|
|
@@ -227,7 +227,7 @@ else {
|
|
|
227
227
|
pattern,
|
|
228
228
|
def: propDef
|
|
229
229
|
});
|
|
230
|
-
if (matched.length) {
|
|
230
|
+
if (matched.length > 0) {
|
|
231
231
|
let keyPassed = false;
|
|
232
232
|
for (const { def: def$1 } of matched) if (this.validateSafe(def$1, value[key])) {
|
|
233
233
|
this.pop(false);
|
|
@@ -254,7 +254,7 @@ else {
|
|
|
254
254
|
return passed;
|
|
255
255
|
}
|
|
256
256
|
validatePrimitive(def, value) {
|
|
257
|
-
if (
|
|
257
|
+
if (def.type.value !== undefined) {
|
|
258
258
|
if (value !== def.type.value) {
|
|
259
259
|
this.error(`Expected ${def.type.value}, got ${value}`);
|
|
260
260
|
return false;
|
|
@@ -263,40 +263,46 @@ else {
|
|
|
263
263
|
}
|
|
264
264
|
const typeOfValue = Array.isArray(value) ? "array" : typeof value;
|
|
265
265
|
switch (def.type.designType) {
|
|
266
|
-
case "never":
|
|
266
|
+
case "never": {
|
|
267
267
|
this.error(`This type is impossible, must be an internal problem`);
|
|
268
268
|
return false;
|
|
269
|
+
}
|
|
269
270
|
case "any": return true;
|
|
270
|
-
case "string":
|
|
271
|
+
case "string": {
|
|
271
272
|
if (typeOfValue !== def.type.designType) {
|
|
272
273
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
273
274
|
return false;
|
|
274
275
|
}
|
|
275
276
|
return this.validateString(def, value);
|
|
276
|
-
|
|
277
|
+
}
|
|
278
|
+
case "number": {
|
|
277
279
|
if (typeOfValue !== def.type.designType) {
|
|
278
280
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
279
281
|
return false;
|
|
280
282
|
}
|
|
281
283
|
return this.validateNumber(def, value);
|
|
282
|
-
|
|
284
|
+
}
|
|
285
|
+
case "boolean": {
|
|
283
286
|
if (typeOfValue !== def.type.designType) {
|
|
284
287
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
285
288
|
return false;
|
|
286
289
|
}
|
|
287
290
|
return this.validateBoolean(def, value);
|
|
288
|
-
|
|
291
|
+
}
|
|
292
|
+
case "undefined": {
|
|
289
293
|
if (value !== undefined) {
|
|
290
294
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
291
295
|
return false;
|
|
292
296
|
}
|
|
293
297
|
return true;
|
|
294
|
-
|
|
298
|
+
}
|
|
299
|
+
case "null": {
|
|
295
300
|
if (value !== null) {
|
|
296
301
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
297
302
|
return false;
|
|
298
303
|
}
|
|
299
304
|
return true;
|
|
305
|
+
}
|
|
300
306
|
default: throw new Error(`Unknown type "${def.type.designType}"`);
|
|
301
307
|
}
|
|
302
308
|
}
|
|
@@ -564,7 +570,7 @@ function buildJsonSchema(type) {
|
|
|
564
570
|
type: "object",
|
|
565
571
|
properties
|
|
566
572
|
};
|
|
567
|
-
if (required.length) schema.required = required;
|
|
573
|
+
if (required.length > 0) schema.required = required;
|
|
568
574
|
return schema;
|
|
569
575
|
},
|
|
570
576
|
array(d) {
|
|
@@ -741,28 +747,32 @@ else flatUnion.item(existing);
|
|
|
741
747
|
}
|
|
742
748
|
case "union":
|
|
743
749
|
case "intersection":
|
|
744
|
-
case "tuple":
|
|
750
|
+
case "tuple": {
|
|
745
751
|
for (const item of def.type.items) flattenArray(item, name);
|
|
746
752
|
break;
|
|
747
|
-
|
|
753
|
+
}
|
|
754
|
+
case "array": {
|
|
748
755
|
flattenArray(def.type.of, name);
|
|
749
756
|
break;
|
|
757
|
+
}
|
|
750
758
|
default:
|
|
751
759
|
}
|
|
752
760
|
}
|
|
753
761
|
function flattenType(def, prefix = "", inComplexTypeOrArray = false) {
|
|
754
762
|
switch (def.type.kind) {
|
|
755
|
-
case "object":
|
|
763
|
+
case "object": {
|
|
756
764
|
addFieldToFlatMap(prefix || "", def);
|
|
757
765
|
for (const [key, value] of def.type.props.entries()) {
|
|
758
766
|
if (skipPhantom && isPhantomType(value)) continue;
|
|
759
767
|
flattenType(value, prefix ? `${prefix}.${key}` : key, inComplexTypeOrArray);
|
|
760
768
|
}
|
|
761
769
|
break;
|
|
770
|
+
}
|
|
762
771
|
case "array": {
|
|
763
772
|
let typeArray = def;
|
|
764
773
|
if (!inComplexTypeOrArray) {
|
|
765
774
|
typeArray = defineAnnotatedType().refTo(def).copyMetadata(def.metadata).$type;
|
|
775
|
+
if (def.optional) typeArray.optional = def.optional;
|
|
766
776
|
if (options?.topLevelArrayTag) typeArray.metadata.set(options.topLevelArrayTag, true);
|
|
767
777
|
}
|
|
768
778
|
addFieldToFlatMap(prefix || "", typeArray);
|
|
@@ -771,10 +781,19 @@ else flatUnion.item(existing);
|
|
|
771
781
|
}
|
|
772
782
|
case "intersection":
|
|
773
783
|
case "tuple":
|
|
774
|
-
case "union":
|
|
775
|
-
|
|
784
|
+
case "union": {
|
|
785
|
+
for (const item of def.type.items) flattenType(item, prefix, true);
|
|
776
786
|
addFieldToFlatMap(prefix || "", def);
|
|
787
|
+
if (def.optional) {
|
|
788
|
+
const entry = flatMap.get(prefix || "");
|
|
789
|
+
if (entry) entry.optional = def.optional;
|
|
790
|
+
}
|
|
777
791
|
break;
|
|
792
|
+
}
|
|
793
|
+
default: {
|
|
794
|
+
addFieldToFlatMap(prefix || "", def);
|
|
795
|
+
break;
|
|
796
|
+
}
|
|
778
797
|
}
|
|
779
798
|
if (prefix) options?.onField?.(prefix, def, def.metadata);
|
|
780
799
|
}
|