@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/cli.cjs
CHANGED
|
@@ -23,10 +23,10 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
23
23
|
|
|
24
24
|
//#endregion
|
|
25
25
|
const __moostjs_event_cli = __toESM(require("@moostjs/event-cli"));
|
|
26
|
-
const
|
|
26
|
+
const fs = __toESM(require("fs"));
|
|
27
27
|
const path = __toESM(require("path"));
|
|
28
28
|
const __atscript_core = __toESM(require("@atscript/core"));
|
|
29
|
-
const
|
|
29
|
+
const moost = __toESM(require("moost"));
|
|
30
30
|
|
|
31
31
|
//#region packages/typescript/src/codegen/code-printer.ts
|
|
32
32
|
function _define_property$5(obj, key, value) {
|
|
@@ -111,7 +111,7 @@ else if (this.currentLine.length > 0) this.lines.push(this.currentLine);
|
|
|
111
111
|
return this;
|
|
112
112
|
}
|
|
113
113
|
doPop(withNewLine) {
|
|
114
|
-
if (
|
|
114
|
+
if (this.blockStack.length === 0) throw new Error("No block to pop (stack is empty).");
|
|
115
115
|
const closing = this.blockStack.pop();
|
|
116
116
|
this.unindent();
|
|
117
117
|
if (withNewLine) this.writeln(closing);
|
|
@@ -310,7 +310,7 @@ var TypeRenderer = class TypeRenderer extends BaseRenderer {
|
|
|
310
310
|
propsDefs.add(renderedDef);
|
|
311
311
|
renderedDef.split("\n").forEach((l) => this.writeln(l));
|
|
312
312
|
}
|
|
313
|
-
if (patterns.length) {
|
|
313
|
+
if (patterns.length > 0) {
|
|
314
314
|
this.write(`[key: string]: `);
|
|
315
315
|
if (patterns.length > 0) {
|
|
316
316
|
for (const prop of patterns) propsDefs.add(this.renderTypeDefString(prop.getDefinition()));
|
|
@@ -588,7 +588,7 @@ var Validator = class {
|
|
|
588
588
|
}
|
|
589
589
|
let i = 0;
|
|
590
590
|
for (const item of def.type.items) {
|
|
591
|
-
this.push(
|
|
591
|
+
this.push(String(i));
|
|
592
592
|
if (!this.validateSafe(item, value[i])) {
|
|
593
593
|
this.pop(true);
|
|
594
594
|
return false;
|
|
@@ -624,7 +624,7 @@ var Validator = class {
|
|
|
624
624
|
let i = 0;
|
|
625
625
|
let passed = true;
|
|
626
626
|
for (const item of value) {
|
|
627
|
-
this.push(
|
|
627
|
+
this.push(String(i));
|
|
628
628
|
if (!this.validateSafe(def.type.of, item)) {
|
|
629
629
|
passed = false;
|
|
630
630
|
this.pop(true);
|
|
@@ -676,7 +676,7 @@ else {
|
|
|
676
676
|
pattern,
|
|
677
677
|
def: propDef
|
|
678
678
|
});
|
|
679
|
-
if (matched.length) {
|
|
679
|
+
if (matched.length > 0) {
|
|
680
680
|
let keyPassed = false;
|
|
681
681
|
for (const { def: def$1 } of matched) if (this.validateSafe(def$1, value[key])) {
|
|
682
682
|
this.pop(false);
|
|
@@ -703,7 +703,7 @@ else {
|
|
|
703
703
|
return passed;
|
|
704
704
|
}
|
|
705
705
|
validatePrimitive(def, value) {
|
|
706
|
-
if (
|
|
706
|
+
if (def.type.value !== undefined) {
|
|
707
707
|
if (value !== def.type.value) {
|
|
708
708
|
this.error(`Expected ${def.type.value}, got ${value}`);
|
|
709
709
|
return false;
|
|
@@ -712,40 +712,46 @@ else {
|
|
|
712
712
|
}
|
|
713
713
|
const typeOfValue = Array.isArray(value) ? "array" : typeof value;
|
|
714
714
|
switch (def.type.designType) {
|
|
715
|
-
case "never":
|
|
715
|
+
case "never": {
|
|
716
716
|
this.error(`This type is impossible, must be an internal problem`);
|
|
717
717
|
return false;
|
|
718
|
+
}
|
|
718
719
|
case "any": return true;
|
|
719
|
-
case "string":
|
|
720
|
+
case "string": {
|
|
720
721
|
if (typeOfValue !== def.type.designType) {
|
|
721
722
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
722
723
|
return false;
|
|
723
724
|
}
|
|
724
725
|
return this.validateString(def, value);
|
|
725
|
-
|
|
726
|
+
}
|
|
727
|
+
case "number": {
|
|
726
728
|
if (typeOfValue !== def.type.designType) {
|
|
727
729
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
728
730
|
return false;
|
|
729
731
|
}
|
|
730
732
|
return this.validateNumber(def, value);
|
|
731
|
-
|
|
733
|
+
}
|
|
734
|
+
case "boolean": {
|
|
732
735
|
if (typeOfValue !== def.type.designType) {
|
|
733
736
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
734
737
|
return false;
|
|
735
738
|
}
|
|
736
739
|
return this.validateBoolean(def, value);
|
|
737
|
-
|
|
740
|
+
}
|
|
741
|
+
case "undefined": {
|
|
738
742
|
if (value !== undefined) {
|
|
739
743
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
740
744
|
return false;
|
|
741
745
|
}
|
|
742
746
|
return true;
|
|
743
|
-
|
|
747
|
+
}
|
|
748
|
+
case "null": {
|
|
744
749
|
if (value !== null) {
|
|
745
750
|
this.error(`Expected ${def.type.designType}, got ${typeOfValue}`);
|
|
746
751
|
return false;
|
|
747
752
|
}
|
|
748
753
|
return true;
|
|
754
|
+
}
|
|
749
755
|
default: throw new Error(`Unknown type "${def.type.designType}"`);
|
|
750
756
|
}
|
|
751
757
|
}
|
|
@@ -1000,7 +1006,7 @@ function buildJsonSchema(type) {
|
|
|
1000
1006
|
type: "object",
|
|
1001
1007
|
properties
|
|
1002
1008
|
};
|
|
1003
|
-
if (required.length) schema.required = required;
|
|
1009
|
+
if (required.length > 0) schema.required = required;
|
|
1004
1010
|
return schema;
|
|
1005
1011
|
},
|
|
1006
1012
|
array(d) {
|
|
@@ -1263,34 +1269,39 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1263
1269
|
annotations?.forEach((a) => {
|
|
1264
1270
|
switch (a.name) {
|
|
1265
1271
|
case "expect.minLength":
|
|
1266
|
-
case "expect.maxLength":
|
|
1272
|
+
case "expect.maxLength": {
|
|
1267
1273
|
if (a.args[0]) handle.annotate(a.name, {
|
|
1268
1274
|
length: Number(a.args[0].text),
|
|
1269
1275
|
message: a.args[1]?.text
|
|
1270
1276
|
});
|
|
1271
1277
|
break;
|
|
1272
|
-
|
|
1278
|
+
}
|
|
1279
|
+
case "expect.min": {
|
|
1273
1280
|
if (a.args[0]) handle.annotate(a.name, {
|
|
1274
1281
|
minValue: Number(a.args[0].text),
|
|
1275
1282
|
message: a.args[1]?.text
|
|
1276
1283
|
});
|
|
1277
1284
|
break;
|
|
1278
|
-
|
|
1285
|
+
}
|
|
1286
|
+
case "expect.max": {
|
|
1279
1287
|
if (a.args[0]) handle.annotate(a.name, {
|
|
1280
1288
|
maxValue: Number(a.args[0].text),
|
|
1281
1289
|
message: a.args[1]?.text
|
|
1282
1290
|
});
|
|
1283
1291
|
break;
|
|
1284
|
-
|
|
1292
|
+
}
|
|
1293
|
+
case "expect.pattern": {
|
|
1285
1294
|
handle.annotate(a.name, {
|
|
1286
1295
|
pattern: a.args[0]?.text || "",
|
|
1287
1296
|
flags: a.args[1]?.text,
|
|
1288
1297
|
message: a.args[2]?.text
|
|
1289
1298
|
}, true);
|
|
1290
1299
|
break;
|
|
1291
|
-
|
|
1300
|
+
}
|
|
1301
|
+
case "expect.int": {
|
|
1292
1302
|
handle.annotate(a.name, true);
|
|
1293
1303
|
break;
|
|
1304
|
+
}
|
|
1294
1305
|
default:
|
|
1295
1306
|
}
|
|
1296
1307
|
});
|
|
@@ -1305,8 +1316,11 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1305
1316
|
const ref = node;
|
|
1306
1317
|
const decl = this.doc.unwindType(ref.id, ref.chain)?.def;
|
|
1307
1318
|
if ((0, __atscript_core.isPrimitive)(decl)) {
|
|
1308
|
-
this.
|
|
1309
|
-
|
|
1319
|
+
const ownerDecl = this.doc.getDeclarationOwnerNode(ref.id);
|
|
1320
|
+
if (!ownerDecl?.node || ownerDecl.node.entity !== "type" && ownerDecl.node.entity !== "interface") {
|
|
1321
|
+
this.annotateType(decl, name);
|
|
1322
|
+
return this;
|
|
1323
|
+
}
|
|
1310
1324
|
}
|
|
1311
1325
|
const chain = ref.hasChain ? `, [${ref.chain.map((c) => `"${escapeQuotes(c.text)}"`).join(", ")}]` : "";
|
|
1312
1326
|
this.writeln(`$(${name ? `"", ${name}` : ""})`).indent().writeln(`.refTo(${ref.id}${chain})`);
|
|
@@ -1348,7 +1362,7 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1348
1362
|
return this;
|
|
1349
1363
|
}
|
|
1350
1364
|
default: {
|
|
1351
|
-
console.log("!!!!!!! UNKNOWN
|
|
1365
|
+
console.log("!!!!!!! UNKNOWN", node.entity);
|
|
1352
1366
|
return this;
|
|
1353
1367
|
}
|
|
1354
1368
|
}
|
|
@@ -1373,7 +1387,7 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1373
1387
|
case "final": return this.writeln(`$(${d()}).designType("${def.value === "void" ? "undefined" : def.value}")`);
|
|
1374
1388
|
case "union":
|
|
1375
1389
|
case "intersection":
|
|
1376
|
-
case "tuple":
|
|
1390
|
+
case "tuple": {
|
|
1377
1391
|
this.writeln(`$(${d(def.kind)})`);
|
|
1378
1392
|
this.indent();
|
|
1379
1393
|
for (const itemDef of def.items) {
|
|
@@ -1386,7 +1400,8 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1386
1400
|
}
|
|
1387
1401
|
this.unindent();
|
|
1388
1402
|
return;
|
|
1389
|
-
|
|
1403
|
+
}
|
|
1404
|
+
case "array": {
|
|
1390
1405
|
this.writeln(`$(${d("array")})`);
|
|
1391
1406
|
this.indent();
|
|
1392
1407
|
this.write(".of(");
|
|
@@ -1397,7 +1412,8 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1397
1412
|
this.writeln(`)`);
|
|
1398
1413
|
this.unindent();
|
|
1399
1414
|
return;
|
|
1400
|
-
|
|
1415
|
+
}
|
|
1416
|
+
case "object": {
|
|
1401
1417
|
this.writeln(`$(${d("object")})`);
|
|
1402
1418
|
this.indent();
|
|
1403
1419
|
for (const [key, propDef] of Object.entries(def.props)) {
|
|
@@ -1424,6 +1440,7 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1424
1440
|
}
|
|
1425
1441
|
this.unindent();
|
|
1426
1442
|
return;
|
|
1443
|
+
}
|
|
1427
1444
|
default: return this.writeln(`$(${d()}).designType("any")`);
|
|
1428
1445
|
}
|
|
1429
1446
|
}
|
|
@@ -1470,6 +1487,10 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1470
1487
|
if (!refNode.hasChain) {
|
|
1471
1488
|
const resolved = this.doc.unwindType(refNode.id, refNode.chain)?.def;
|
|
1472
1489
|
if (resolved && !(0, __atscript_core.isPrimitive)(resolved)) annotations = node.annotations ?? [];
|
|
1490
|
+
else if (resolved && (0, __atscript_core.isPrimitive)(resolved)) {
|
|
1491
|
+
const ownerDecl = this.doc.getDeclarationOwnerNode(refNode.id);
|
|
1492
|
+
if (ownerDecl?.node && (ownerDecl.node.entity === "type" || ownerDecl.node.entity === "interface")) annotations = node.annotations ?? [];
|
|
1493
|
+
}
|
|
1473
1494
|
}
|
|
1474
1495
|
}
|
|
1475
1496
|
if (annotations === undefined) annotations = this.doc.evalAnnotationsForNode(node);
|
|
@@ -1523,7 +1544,7 @@ else targetValue = "true";
|
|
|
1523
1544
|
}
|
|
1524
1545
|
} else {
|
|
1525
1546
|
multiple = node.countAnnotations(an.name) > 1 || an.args.length > 1;
|
|
1526
|
-
if (an.args.length) targetValue = an.args[0].type === "text" ? `"${escapeQuotes(an.args[0].text)}"` : an.args[0].text;
|
|
1547
|
+
if (an.args.length > 0) targetValue = an.args[0].type === "text" ? `"${escapeQuotes(an.args[0].text)}"` : an.args[0].text;
|
|
1527
1548
|
}
|
|
1528
1549
|
return {
|
|
1529
1550
|
value: targetValue,
|
|
@@ -1585,7 +1606,7 @@ else targetValue = "true";
|
|
|
1585
1606
|
* Returns multiple paths when a property appears in multiple union branches.
|
|
1586
1607
|
*/ buildMutatingAccessors(targetName, targetDef, parts) {
|
|
1587
1608
|
let accessors = [{
|
|
1588
|
-
prefix: targetName
|
|
1609
|
+
prefix: `${targetName}.type`,
|
|
1589
1610
|
def: targetDef
|
|
1590
1611
|
}];
|
|
1591
1612
|
for (let i = 0; i < parts.length; i++) {
|
|
@@ -1593,17 +1614,17 @@ else targetValue = "true";
|
|
|
1593
1614
|
for (const { prefix, def } of accessors) {
|
|
1594
1615
|
const results = this.buildPropPaths(def, parts[i]);
|
|
1595
1616
|
if (results.length > 0) for (const result of results) if (i < parts.length - 1) nextAccessors.push({
|
|
1596
|
-
prefix: prefix
|
|
1617
|
+
prefix: `${prefix}${result.path}?.type`,
|
|
1597
1618
|
def: result.propDef
|
|
1598
1619
|
});
|
|
1599
1620
|
else nextAccessors.push({
|
|
1600
|
-
prefix: prefix
|
|
1621
|
+
prefix: `${prefix}${result.path}?`,
|
|
1601
1622
|
def: result.propDef
|
|
1602
1623
|
});
|
|
1603
1624
|
else {
|
|
1604
|
-
const suffix = `.props.get("${escapeQuotes(parts[i])}")
|
|
1625
|
+
const suffix = `.props.get("${escapeQuotes(parts[i])}")${i < parts.length - 1 ? "?.type" : "?"}`;
|
|
1605
1626
|
nextAccessors.push({
|
|
1606
|
-
prefix: prefix
|
|
1627
|
+
prefix: `${prefix}${suffix}`,
|
|
1607
1628
|
def: undefined
|
|
1608
1629
|
});
|
|
1609
1630
|
}
|
|
@@ -1658,9 +1679,9 @@ function resolveJsonSchemaMode(opts) {
|
|
|
1658
1679
|
}
|
|
1659
1680
|
const tsPlugin = (opts) => {
|
|
1660
1681
|
return {
|
|
1661
|
-
name: "
|
|
1682
|
+
name: "typescript",
|
|
1662
1683
|
render(doc, format) {
|
|
1663
|
-
if (format === "dts") return [{
|
|
1684
|
+
if (format === "dts" || format === __atscript_core.DEFAULT_FORMAT) return [{
|
|
1664
1685
|
fileName: `${doc.name}.d.ts`,
|
|
1665
1686
|
content: new TypeRenderer(doc, opts).render()
|
|
1666
1687
|
}];
|
|
@@ -1670,19 +1691,19 @@ const tsPlugin = (opts) => {
|
|
|
1670
1691
|
}];
|
|
1671
1692
|
},
|
|
1672
1693
|
async buildEnd(output, format, repo) {
|
|
1673
|
-
if (format === "dts") {
|
|
1694
|
+
if (format === "dts" || format === __atscript_core.DEFAULT_FORMAT) {
|
|
1674
1695
|
const annotations = await repo.getUsedAnnotations();
|
|
1675
1696
|
const tags = await repo.getPrimitivesTags() || new Set();
|
|
1676
|
-
|
|
1697
|
+
const rendered = [];
|
|
1677
1698
|
for (const [key, val] of Object.entries(annotations)) {
|
|
1678
1699
|
const multiple = val.multiple;
|
|
1679
|
-
|
|
1700
|
+
const typeLine = Array.from(val.types).map((t) => {
|
|
1680
1701
|
if (t.type === "object") return `{ ${Object.entries(t.props).map(([k, v]) => `${wrapProp(k)}${v.optional ? "?" : ""}: ${v.type}`).join(", ")} }`;
|
|
1681
1702
|
else return t.optional ? `${t.type} | true` : t.type;
|
|
1682
1703
|
}).join(" | ");
|
|
1683
1704
|
rendered.push(`${wrapProp(key)}: ${multiple ? "(" : ""}${typeLine}${multiple ? ")[]" : ""}`);
|
|
1684
1705
|
}
|
|
1685
|
-
|
|
1706
|
+
const renderedTags = Array.from(tags).map((f) => `"${escapeQuotes(f)}"`).join(" | ");
|
|
1686
1707
|
output.push({
|
|
1687
1708
|
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",
|
|
1688
1709
|
fileName: "atscript.d.ts",
|
|
@@ -1723,7 +1744,7 @@ function _ts_param(paramIndex, decorator) {
|
|
|
1723
1744
|
var Commands = class {
|
|
1724
1745
|
async default(configFile, format, noEmit, skipDiag) {
|
|
1725
1746
|
const config = await this.getConfig(configFile);
|
|
1726
|
-
|
|
1747
|
+
config.format = format || __atscript_core.DEFAULT_FORMAT;
|
|
1727
1748
|
this.logger.log(`Format: ${"\x1B[36m"}${config.format}${"\x1B[39m"}`);
|
|
1728
1749
|
const builder = await (0, __atscript_core.build)(config);
|
|
1729
1750
|
let errorCount = 0;
|
|
@@ -1769,7 +1790,7 @@ else if (m.severity === 2) warningCount++;
|
|
|
1769
1790
|
}
|
|
1770
1791
|
this.logger.log(`No atscript config file found`);
|
|
1771
1792
|
return {
|
|
1772
|
-
format:
|
|
1793
|
+
format: __atscript_core.DEFAULT_FORMAT,
|
|
1773
1794
|
plugins: [tsPlugin()]
|
|
1774
1795
|
};
|
|
1775
1796
|
}
|
|
@@ -1791,7 +1812,7 @@ _ts_decorate([
|
|
|
1791
1812
|
_ts_param(0, (0, moost.Description)("Path to config file")),
|
|
1792
1813
|
_ts_param(1, (0, __moostjs_event_cli.CliOption)("f", "format")),
|
|
1793
1814
|
_ts_param(1, (0, moost.Optional)()),
|
|
1794
|
-
_ts_param(1, (0, moost.Description)("Output format (js
|
|
1815
|
+
_ts_param(1, (0, moost.Description)("Output format (e.g. js, dts). Omit to run all plugins with their default output.")),
|
|
1795
1816
|
_ts_param(2, (0, __moostjs_event_cli.CliOption)("noEmit")),
|
|
1796
1817
|
_ts_param(2, (0, moost.Optional)()),
|
|
1797
1818
|
_ts_param(2, (0, moost.Description)("Only run diagnostics without emitting files")),
|
|
@@ -1811,7 +1832,7 @@ Commands = _ts_decorate([
|
|
|
1811
1832
|
(0, moost.Controller)(),
|
|
1812
1833
|
_ts_param(0, (0, moost.InjectMoostLogger)("asc")),
|
|
1813
1834
|
_ts_metadata("design:type", Function),
|
|
1814
|
-
_ts_metadata("design:paramtypes", [typeof
|
|
1835
|
+
_ts_metadata("design:paramtypes", [typeof TConsoleBase === "undefined" ? Object : TConsoleBase])
|
|
1815
1836
|
], Commands);
|
|
1816
1837
|
|
|
1817
1838
|
//#endregion
|
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);
|
|
@@ -700,7 +700,7 @@ else {
|
|
|
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
|
}
|
|
@@ -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",
|