@atscript/typescript 0.1.17 → 0.1.19
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 +67 -46
- package/dist/index.cjs +62 -41
- package/dist/index.mjs +62 -41
- package/dist/utils.cjs +39 -20
- package/dist/utils.d.ts +6 -6
- package/dist/utils.mjs +39 -20
- package/package.json +42 -42
package/dist/index.cjs
CHANGED
|
@@ -22,8 +22,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
22
22
|
}) : target, mod));
|
|
23
23
|
|
|
24
24
|
//#endregion
|
|
25
|
-
const __atscript_core = __toESM(require("@atscript/core"));
|
|
26
25
|
const path = __toESM(require("path"));
|
|
26
|
+
const __atscript_core = __toESM(require("@atscript/core"));
|
|
27
27
|
|
|
28
28
|
//#region packages/typescript/src/codegen/code-printer.ts
|
|
29
29
|
function _define_property$4(obj, key, value) {
|
|
@@ -108,7 +108,7 @@ else if (this.currentLine.length > 0) this.lines.push(this.currentLine);
|
|
|
108
108
|
return this;
|
|
109
109
|
}
|
|
110
110
|
doPop(withNewLine) {
|
|
111
|
-
if (
|
|
111
|
+
if (this.blockStack.length === 0) throw new Error("No block to pop (stack is empty).");
|
|
112
112
|
const closing = this.blockStack.pop();
|
|
113
113
|
this.unindent();
|
|
114
114
|
if (withNewLine) this.writeln(closing);
|
|
@@ -307,7 +307,7 @@ var TypeRenderer = class TypeRenderer extends BaseRenderer {
|
|
|
307
307
|
propsDefs.add(renderedDef);
|
|
308
308
|
renderedDef.split("\n").forEach((l) => this.writeln(l));
|
|
309
309
|
}
|
|
310
|
-
if (patterns.length) {
|
|
310
|
+
if (patterns.length > 0) {
|
|
311
311
|
this.write(`[key: string]: `);
|
|
312
312
|
if (patterns.length > 0) {
|
|
313
313
|
for (const prop of patterns) propsDefs.add(this.renderTypeDefString(prop.getDefinition()));
|
|
@@ -585,7 +585,7 @@ var Validator = class {
|
|
|
585
585
|
}
|
|
586
586
|
let i = 0;
|
|
587
587
|
for (const item of def.type.items) {
|
|
588
|
-
this.push(
|
|
588
|
+
this.push(String(i));
|
|
589
589
|
if (!this.validateSafe(item, value[i])) {
|
|
590
590
|
this.pop(true);
|
|
591
591
|
return false;
|
|
@@ -621,7 +621,7 @@ var Validator = class {
|
|
|
621
621
|
let i = 0;
|
|
622
622
|
let passed = true;
|
|
623
623
|
for (const item of value) {
|
|
624
|
-
this.push(
|
|
624
|
+
this.push(String(i));
|
|
625
625
|
if (!this.validateSafe(def.type.of, item)) {
|
|
626
626
|
passed = false;
|
|
627
627
|
this.pop(true);
|
|
@@ -673,7 +673,7 @@ else {
|
|
|
673
673
|
pattern,
|
|
674
674
|
def: propDef
|
|
675
675
|
});
|
|
676
|
-
if (matched.length) {
|
|
676
|
+
if (matched.length > 0) {
|
|
677
677
|
let keyPassed = false;
|
|
678
678
|
for (const { def: def$1 } of matched) if (this.validateSafe(def$1, value[key])) {
|
|
679
679
|
this.pop(false);
|
|
@@ -687,20 +687,20 @@ else {
|
|
|
687
687
|
passed = false;
|
|
688
688
|
if (this.isLimitExceeded()) return false;
|
|
689
689
|
}
|
|
690
|
-
} else if (this.opts.
|
|
691
|
-
if (this.opts.
|
|
690
|
+
} else if (this.opts.unknownProps !== "ignore") {
|
|
691
|
+
if (this.opts.unknownProps === "error") {
|
|
692
692
|
this.push(key);
|
|
693
693
|
this.error(`Unexpected property`);
|
|
694
694
|
this.pop(true);
|
|
695
695
|
if (this.isLimitExceeded()) return false;
|
|
696
696
|
passed = false;
|
|
697
|
-
} else if (this.opts.
|
|
697
|
+
} else if (this.opts.unknownProps === "strip") delete value[key];
|
|
698
698
|
}
|
|
699
699
|
}
|
|
700
700
|
return passed;
|
|
701
701
|
}
|
|
702
702
|
validatePrimitive(def, value) {
|
|
703
|
-
if (
|
|
703
|
+
if (def.type.value !== undefined) {
|
|
704
704
|
if (value !== def.type.value) {
|
|
705
705
|
this.error(`Expected ${def.type.value}, got ${value}`);
|
|
706
706
|
return false;
|
|
@@ -709,40 +709,46 @@ else {
|
|
|
709
709
|
}
|
|
710
710
|
const typeOfValue = Array.isArray(value) ? "array" : typeof value;
|
|
711
711
|
switch (def.type.designType) {
|
|
712
|
-
case "never":
|
|
712
|
+
case "never": {
|
|
713
713
|
this.error(`This type is impossible, must be an internal problem`);
|
|
714
714
|
return false;
|
|
715
|
+
}
|
|
715
716
|
case "any": return true;
|
|
716
|
-
case "string":
|
|
717
|
+
case "string": {
|
|
717
718
|
if (typeOfValue !== def.type.designType) {
|
|
718
719
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
719
720
|
return false;
|
|
720
721
|
}
|
|
721
722
|
return this.validateString(def, value);
|
|
722
|
-
|
|
723
|
+
}
|
|
724
|
+
case "number": {
|
|
723
725
|
if (typeOfValue !== def.type.designType) {
|
|
724
726
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
725
727
|
return false;
|
|
726
728
|
}
|
|
727
729
|
return this.validateNumber(def, value);
|
|
728
|
-
|
|
730
|
+
}
|
|
731
|
+
case "boolean": {
|
|
729
732
|
if (typeOfValue !== def.type.designType) {
|
|
730
733
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
731
734
|
return false;
|
|
732
735
|
}
|
|
733
736
|
return this.validateBoolean(def, value);
|
|
734
|
-
|
|
737
|
+
}
|
|
738
|
+
case "undefined": {
|
|
735
739
|
if (value !== undefined) {
|
|
736
740
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
737
741
|
return false;
|
|
738
742
|
}
|
|
739
743
|
return true;
|
|
740
|
-
|
|
744
|
+
}
|
|
745
|
+
case "null": {
|
|
741
746
|
if (value !== null) {
|
|
742
747
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
743
748
|
return false;
|
|
744
749
|
}
|
|
745
750
|
return true;
|
|
751
|
+
}
|
|
746
752
|
default: throw new Error(`Unknown type "${def.type.designType}"`);
|
|
747
753
|
}
|
|
748
754
|
}
|
|
@@ -840,7 +846,7 @@ else {
|
|
|
840
846
|
this.stackPath = [];
|
|
841
847
|
this.opts = {
|
|
842
848
|
partial: false,
|
|
843
|
-
|
|
849
|
+
unknownProps: "error",
|
|
844
850
|
errorLimit: 10,
|
|
845
851
|
...opts,
|
|
846
852
|
plugins: opts?.plugins || []
|
|
@@ -997,7 +1003,7 @@ function buildJsonSchema(type) {
|
|
|
997
1003
|
type: "object",
|
|
998
1004
|
properties
|
|
999
1005
|
};
|
|
1000
|
-
if (required.length) schema.required = required;
|
|
1006
|
+
if (required.length > 0) schema.required = required;
|
|
1001
1007
|
return schema;
|
|
1002
1008
|
},
|
|
1003
1009
|
array(d) {
|
|
@@ -1260,34 +1266,39 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1260
1266
|
annotations?.forEach((a) => {
|
|
1261
1267
|
switch (a.name) {
|
|
1262
1268
|
case "expect.minLength":
|
|
1263
|
-
case "expect.maxLength":
|
|
1269
|
+
case "expect.maxLength": {
|
|
1264
1270
|
if (a.args[0]) handle.annotate(a.name, {
|
|
1265
1271
|
length: Number(a.args[0].text),
|
|
1266
1272
|
message: a.args[1]?.text
|
|
1267
1273
|
});
|
|
1268
1274
|
break;
|
|
1269
|
-
|
|
1275
|
+
}
|
|
1276
|
+
case "expect.min": {
|
|
1270
1277
|
if (a.args[0]) handle.annotate(a.name, {
|
|
1271
1278
|
minValue: Number(a.args[0].text),
|
|
1272
1279
|
message: a.args[1]?.text
|
|
1273
1280
|
});
|
|
1274
1281
|
break;
|
|
1275
|
-
|
|
1282
|
+
}
|
|
1283
|
+
case "expect.max": {
|
|
1276
1284
|
if (a.args[0]) handle.annotate(a.name, {
|
|
1277
1285
|
maxValue: Number(a.args[0].text),
|
|
1278
1286
|
message: a.args[1]?.text
|
|
1279
1287
|
});
|
|
1280
1288
|
break;
|
|
1281
|
-
|
|
1289
|
+
}
|
|
1290
|
+
case "expect.pattern": {
|
|
1282
1291
|
handle.annotate(a.name, {
|
|
1283
1292
|
pattern: a.args[0]?.text || "",
|
|
1284
1293
|
flags: a.args[1]?.text,
|
|
1285
1294
|
message: a.args[2]?.text
|
|
1286
1295
|
}, true);
|
|
1287
1296
|
break;
|
|
1288
|
-
|
|
1297
|
+
}
|
|
1298
|
+
case "expect.int": {
|
|
1289
1299
|
handle.annotate(a.name, true);
|
|
1290
1300
|
break;
|
|
1301
|
+
}
|
|
1291
1302
|
default:
|
|
1292
1303
|
}
|
|
1293
1304
|
});
|
|
@@ -1302,8 +1313,11 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1302
1313
|
const ref = node;
|
|
1303
1314
|
const decl = this.doc.unwindType(ref.id, ref.chain)?.def;
|
|
1304
1315
|
if ((0, __atscript_core.isPrimitive)(decl)) {
|
|
1305
|
-
this.
|
|
1306
|
-
|
|
1316
|
+
const ownerDecl = this.doc.getDeclarationOwnerNode(ref.id);
|
|
1317
|
+
if (!ownerDecl?.node || ownerDecl.node.entity !== "type" && ownerDecl.node.entity !== "interface") {
|
|
1318
|
+
this.annotateType(decl, name);
|
|
1319
|
+
return this;
|
|
1320
|
+
}
|
|
1307
1321
|
}
|
|
1308
1322
|
const chain = ref.hasChain ? `, [${ref.chain.map((c) => `"${escapeQuotes(c.text)}"`).join(", ")}]` : "";
|
|
1309
1323
|
this.writeln(`$(${name ? `"", ${name}` : ""})`).indent().writeln(`.refTo(${ref.id}${chain})`);
|
|
@@ -1345,7 +1359,7 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1345
1359
|
return this;
|
|
1346
1360
|
}
|
|
1347
1361
|
default: {
|
|
1348
|
-
console.log("!!!!!!! UNKNOWN
|
|
1362
|
+
console.log("!!!!!!! UNKNOWN", node.entity);
|
|
1349
1363
|
return this;
|
|
1350
1364
|
}
|
|
1351
1365
|
}
|
|
@@ -1370,7 +1384,7 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1370
1384
|
case "final": return this.writeln(`$(${d()}).designType("${def.value === "void" ? "undefined" : def.value}")`);
|
|
1371
1385
|
case "union":
|
|
1372
1386
|
case "intersection":
|
|
1373
|
-
case "tuple":
|
|
1387
|
+
case "tuple": {
|
|
1374
1388
|
this.writeln(`$(${d(def.kind)})`);
|
|
1375
1389
|
this.indent();
|
|
1376
1390
|
for (const itemDef of def.items) {
|
|
@@ -1383,7 +1397,8 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1383
1397
|
}
|
|
1384
1398
|
this.unindent();
|
|
1385
1399
|
return;
|
|
1386
|
-
|
|
1400
|
+
}
|
|
1401
|
+
case "array": {
|
|
1387
1402
|
this.writeln(`$(${d("array")})`);
|
|
1388
1403
|
this.indent();
|
|
1389
1404
|
this.write(".of(");
|
|
@@ -1394,7 +1409,8 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1394
1409
|
this.writeln(`)`);
|
|
1395
1410
|
this.unindent();
|
|
1396
1411
|
return;
|
|
1397
|
-
|
|
1412
|
+
}
|
|
1413
|
+
case "object": {
|
|
1398
1414
|
this.writeln(`$(${d("object")})`);
|
|
1399
1415
|
this.indent();
|
|
1400
1416
|
for (const [key, propDef] of Object.entries(def.props)) {
|
|
@@ -1421,6 +1437,7 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1421
1437
|
}
|
|
1422
1438
|
this.unindent();
|
|
1423
1439
|
return;
|
|
1440
|
+
}
|
|
1424
1441
|
default: return this.writeln(`$(${d()}).designType("any")`);
|
|
1425
1442
|
}
|
|
1426
1443
|
}
|
|
@@ -1467,6 +1484,10 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1467
1484
|
if (!refNode.hasChain) {
|
|
1468
1485
|
const resolved = this.doc.unwindType(refNode.id, refNode.chain)?.def;
|
|
1469
1486
|
if (resolved && !(0, __atscript_core.isPrimitive)(resolved)) annotations = node.annotations ?? [];
|
|
1487
|
+
else if (resolved && (0, __atscript_core.isPrimitive)(resolved)) {
|
|
1488
|
+
const ownerDecl = this.doc.getDeclarationOwnerNode(refNode.id);
|
|
1489
|
+
if (ownerDecl?.node && (ownerDecl.node.entity === "type" || ownerDecl.node.entity === "interface")) annotations = node.annotations ?? [];
|
|
1490
|
+
}
|
|
1470
1491
|
}
|
|
1471
1492
|
}
|
|
1472
1493
|
if (annotations === undefined) annotations = this.doc.evalAnnotationsForNode(node);
|
|
@@ -1520,7 +1541,7 @@ else targetValue = "true";
|
|
|
1520
1541
|
}
|
|
1521
1542
|
} else {
|
|
1522
1543
|
multiple = node.countAnnotations(an.name) > 1 || an.args.length > 1;
|
|
1523
|
-
if (an.args.length) targetValue = an.args[0].type === "text" ? `"${escapeQuotes(an.args[0].text)}"` : an.args[0].text;
|
|
1544
|
+
if (an.args.length > 0) targetValue = an.args[0].type === "text" ? `"${escapeQuotes(an.args[0].text)}"` : an.args[0].text;
|
|
1524
1545
|
}
|
|
1525
1546
|
return {
|
|
1526
1547
|
value: targetValue,
|
|
@@ -1582,7 +1603,7 @@ else targetValue = "true";
|
|
|
1582
1603
|
* Returns multiple paths when a property appears in multiple union branches.
|
|
1583
1604
|
*/ buildMutatingAccessors(targetName, targetDef, parts) {
|
|
1584
1605
|
let accessors = [{
|
|
1585
|
-
prefix: targetName
|
|
1606
|
+
prefix: `${targetName}.type`,
|
|
1586
1607
|
def: targetDef
|
|
1587
1608
|
}];
|
|
1588
1609
|
for (let i = 0; i < parts.length; i++) {
|
|
@@ -1590,17 +1611,17 @@ else targetValue = "true";
|
|
|
1590
1611
|
for (const { prefix, def } of accessors) {
|
|
1591
1612
|
const results = this.buildPropPaths(def, parts[i]);
|
|
1592
1613
|
if (results.length > 0) for (const result of results) if (i < parts.length - 1) nextAccessors.push({
|
|
1593
|
-
prefix: prefix
|
|
1614
|
+
prefix: `${prefix}${result.path}?.type`,
|
|
1594
1615
|
def: result.propDef
|
|
1595
1616
|
});
|
|
1596
1617
|
else nextAccessors.push({
|
|
1597
|
-
prefix: prefix
|
|
1618
|
+
prefix: `${prefix}${result.path}?`,
|
|
1598
1619
|
def: result.propDef
|
|
1599
1620
|
});
|
|
1600
1621
|
else {
|
|
1601
|
-
const suffix = `.props.get("${escapeQuotes(parts[i])}")
|
|
1622
|
+
const suffix = `.props.get("${escapeQuotes(parts[i])}")${i < parts.length - 1 ? "?.type" : "?"}`;
|
|
1602
1623
|
nextAccessors.push({
|
|
1603
|
-
prefix: prefix
|
|
1624
|
+
prefix: `${prefix}${suffix}`,
|
|
1604
1625
|
def: undefined
|
|
1605
1626
|
});
|
|
1606
1627
|
}
|
|
@@ -1655,9 +1676,9 @@ function resolveJsonSchemaMode(opts) {
|
|
|
1655
1676
|
}
|
|
1656
1677
|
const tsPlugin = (opts) => {
|
|
1657
1678
|
return {
|
|
1658
|
-
name: "
|
|
1679
|
+
name: "typescript",
|
|
1659
1680
|
render(doc, format) {
|
|
1660
|
-
if (format === "dts") return [{
|
|
1681
|
+
if (format === "dts" || format === __atscript_core.DEFAULT_FORMAT) return [{
|
|
1661
1682
|
fileName: `${doc.name}.d.ts`,
|
|
1662
1683
|
content: new TypeRenderer(doc, opts).render()
|
|
1663
1684
|
}];
|
|
@@ -1667,19 +1688,19 @@ const tsPlugin = (opts) => {
|
|
|
1667
1688
|
}];
|
|
1668
1689
|
},
|
|
1669
1690
|
async buildEnd(output, format, repo) {
|
|
1670
|
-
if (format === "dts") {
|
|
1691
|
+
if (format === "dts" || format === __atscript_core.DEFAULT_FORMAT) {
|
|
1671
1692
|
const annotations = await repo.getUsedAnnotations();
|
|
1672
1693
|
const tags = await repo.getPrimitivesTags() || new Set();
|
|
1673
|
-
|
|
1694
|
+
const rendered = [];
|
|
1674
1695
|
for (const [key, val] of Object.entries(annotations)) {
|
|
1675
1696
|
const multiple = val.multiple;
|
|
1676
|
-
|
|
1697
|
+
const typeLine = Array.from(val.types).map((t) => {
|
|
1677
1698
|
if (t.type === "object") return `{ ${Object.entries(t.props).map(([k, v]) => `${wrapProp(k)}${v.optional ? "?" : ""}: ${v.type}`).join(", ")} }`;
|
|
1678
1699
|
else return t.optional ? `${t.type} | true` : t.type;
|
|
1679
1700
|
}).join(" | ");
|
|
1680
1701
|
rendered.push(`${wrapProp(key)}: ${multiple ? "(" : ""}${typeLine}${multiple ? ")[]" : ""}`);
|
|
1681
1702
|
}
|
|
1682
|
-
|
|
1703
|
+
const renderedTags = Array.from(tags).map((f) => `"${escapeQuotes(f)}"`).join(" | ");
|
|
1683
1704
|
output.push({
|
|
1684
1705
|
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",
|
|
1685
1706
|
fileName: "atscript.d.ts",
|
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);
|
|
@@ -663,20 +663,20 @@ else {
|
|
|
663
663
|
passed = false;
|
|
664
664
|
if (this.isLimitExceeded()) return false;
|
|
665
665
|
}
|
|
666
|
-
} else if (this.opts.
|
|
667
|
-
if (this.opts.
|
|
666
|
+
} else if (this.opts.unknownProps !== "ignore") {
|
|
667
|
+
if (this.opts.unknownProps === "error") {
|
|
668
668
|
this.push(key);
|
|
669
669
|
this.error(`Unexpected property`);
|
|
670
670
|
this.pop(true);
|
|
671
671
|
if (this.isLimitExceeded()) return false;
|
|
672
672
|
passed = false;
|
|
673
|
-
} else if (this.opts.
|
|
673
|
+
} else if (this.opts.unknownProps === "strip") delete value[key];
|
|
674
674
|
}
|
|
675
675
|
}
|
|
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
|
}
|
|
@@ -816,7 +822,7 @@ else {
|
|
|
816
822
|
this.stackPath = [];
|
|
817
823
|
this.opts = {
|
|
818
824
|
partial: false,
|
|
819
|
-
|
|
825
|
+
unknownProps: "error",
|
|
820
826
|
errorLimit: 10,
|
|
821
827
|
...opts,
|
|
822
828
|
plugins: opts?.plugins || []
|
|
@@ -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",
|