@atscript/typescript 0.1.33 → 0.1.34
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 +57 -15
- package/dist/index.cjs +57 -15
- package/dist/index.mjs +57 -15
- package/dist/utils.cjs +86 -21
- package/dist/utils.d.ts +17 -3
- package/dist/utils.mjs +86 -21
- package/package.json +2 -2
package/dist/cli.cjs
CHANGED
|
@@ -1058,7 +1058,8 @@ function createAnnotatedTypeNode(type, metadata, opts) {
|
|
|
1058
1058
|
metadata,
|
|
1059
1059
|
validator: validatorMethod,
|
|
1060
1060
|
id: opts?.id,
|
|
1061
|
-
optional: opts?.optional
|
|
1061
|
+
optional: opts?.optional,
|
|
1062
|
+
ref: opts?.ref
|
|
1062
1063
|
};
|
|
1063
1064
|
}
|
|
1064
1065
|
function isAnnotatedType(type) {
|
|
@@ -1135,18 +1136,57 @@ function defineAnnotatedType(_kind, base) {
|
|
|
1135
1136
|
return this;
|
|
1136
1137
|
},
|
|
1137
1138
|
refTo(type$1, chain) {
|
|
1138
|
-
if (
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1139
|
+
if (isAnnotatedType(type$1)) {
|
|
1140
|
+
let newBase = type$1;
|
|
1141
|
+
const typeName = type$1.name || "Unknown";
|
|
1142
|
+
if (chain) for (let i = 0; i < chain.length; i++) {
|
|
1143
|
+
const c = chain[i];
|
|
1144
|
+
if (newBase.type.kind === "object" && newBase.type.props.has(c)) newBase = newBase.type.props.get(c);
|
|
1144
1145
|
else {
|
|
1145
|
-
|
|
1146
|
-
|
|
1146
|
+
const keys = chain.slice(0, i + 1).map((k) => `["${k}"]`).join("");
|
|
1147
|
+
throw new Error(`Can't find prop ${typeName}${keys}`);
|
|
1148
|
+
}
|
|
1147
1149
|
}
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
+
this.$type = createAnnotatedTypeNode(newBase.type, metadata, {
|
|
1151
|
+
id: newBase.id,
|
|
1152
|
+
ref: chain && chain.length > 0 ? {
|
|
1153
|
+
type: () => type$1,
|
|
1154
|
+
field: chain.join(".")
|
|
1155
|
+
} : undefined
|
|
1156
|
+
});
|
|
1157
|
+
} else if (typeof type$1 === "function") {
|
|
1158
|
+
const lazyType = type$1;
|
|
1159
|
+
this.$type = createAnnotatedTypeNode({ kind: "" }, metadata, { ref: {
|
|
1160
|
+
type: lazyType,
|
|
1161
|
+
field: chain ? chain.join(".") : ""
|
|
1162
|
+
} });
|
|
1163
|
+
const node = this.$type;
|
|
1164
|
+
const placeholder = node.type;
|
|
1165
|
+
Object.defineProperty(node, "type", {
|
|
1166
|
+
get() {
|
|
1167
|
+
const t = lazyType();
|
|
1168
|
+
if (!isAnnotatedType(t)) {
|
|
1169
|
+
Object.defineProperty(node, "type", {
|
|
1170
|
+
value: placeholder,
|
|
1171
|
+
writable: false,
|
|
1172
|
+
configurable: true
|
|
1173
|
+
});
|
|
1174
|
+
return placeholder;
|
|
1175
|
+
}
|
|
1176
|
+
let target = t;
|
|
1177
|
+
if (chain) for (const c of chain) if (target.type.kind === "object" && target.type.props.has(c)) target = target.type.props.get(c);
|
|
1178
|
+
else return t.type;
|
|
1179
|
+
node.id = target.id || t.id;
|
|
1180
|
+
Object.defineProperty(node, "type", {
|
|
1181
|
+
value: target.type,
|
|
1182
|
+
writable: false,
|
|
1183
|
+
configurable: true
|
|
1184
|
+
});
|
|
1185
|
+
return target.type;
|
|
1186
|
+
},
|
|
1187
|
+
configurable: true
|
|
1188
|
+
});
|
|
1189
|
+
} else throw new Error(`${type$1} is not annotated type`);
|
|
1150
1190
|
return this;
|
|
1151
1191
|
},
|
|
1152
1192
|
annotate(key, value, asArray) {
|
|
@@ -1631,8 +1671,8 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1631
1671
|
const ref = node;
|
|
1632
1672
|
const decl = this.doc.unwindType(ref.id, ref.chain)?.def;
|
|
1633
1673
|
if ((0, __atscript_core.isPrimitive)(decl)) {
|
|
1634
|
-
const ownerDecl = this.doc.getDeclarationOwnerNode(ref.id);
|
|
1635
|
-
if (!ownerDecl?.node || ownerDecl.node.entity !== "type" && ownerDecl.node.entity !== "interface") {
|
|
1674
|
+
const ownerDecl$1 = this.doc.getDeclarationOwnerNode(ref.id);
|
|
1675
|
+
if (!ownerDecl$1?.node || ownerDecl$1.node.entity !== "type" && ownerDecl$1.node.entity !== "interface") {
|
|
1636
1676
|
this.annotateType(decl, name);
|
|
1637
1677
|
return this;
|
|
1638
1678
|
}
|
|
@@ -1646,9 +1686,11 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1646
1686
|
}
|
|
1647
1687
|
}
|
|
1648
1688
|
const chain = ref.hasChain ? `, [${ref.chain.map((c) => `"${escapeQuotes(c.text)}"`).join(", ")}]` : "";
|
|
1649
|
-
|
|
1689
|
+
const ownerDecl = this.doc.getDeclarationOwnerNode(ref.id);
|
|
1690
|
+
const isImported = ownerDecl ? ownerDecl.doc !== this.doc : false;
|
|
1691
|
+
const refExpr = isImported ? `() => ${ref.id}` : ref.id;
|
|
1692
|
+
this.writeln(`$(${name ? `"", ${name}` : ""})`).indent().writeln(`.refTo(${refExpr}${chain})`);
|
|
1650
1693
|
if (!ref.hasChain) {
|
|
1651
|
-
const ownerDecl = this.doc.getDeclarationOwnerNode(ref.id);
|
|
1652
1694
|
if (ownerDecl?.node) {
|
|
1653
1695
|
const typeAnnotations = ownerDecl.doc.evalAnnotationsForNode(ownerDecl.node);
|
|
1654
1696
|
typeAnnotations?.forEach((an) => {
|
package/dist/index.cjs
CHANGED
|
@@ -1056,7 +1056,8 @@ function createAnnotatedTypeNode(type, metadata, opts) {
|
|
|
1056
1056
|
metadata,
|
|
1057
1057
|
validator: validatorMethod,
|
|
1058
1058
|
id: opts?.id,
|
|
1059
|
-
optional: opts?.optional
|
|
1059
|
+
optional: opts?.optional,
|
|
1060
|
+
ref: opts?.ref
|
|
1060
1061
|
};
|
|
1061
1062
|
}
|
|
1062
1063
|
function isAnnotatedType(type) {
|
|
@@ -1133,18 +1134,57 @@ function defineAnnotatedType(_kind, base) {
|
|
|
1133
1134
|
return this;
|
|
1134
1135
|
},
|
|
1135
1136
|
refTo(type$1, chain) {
|
|
1136
|
-
if (
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1137
|
+
if (isAnnotatedType(type$1)) {
|
|
1138
|
+
let newBase = type$1;
|
|
1139
|
+
const typeName = type$1.name || "Unknown";
|
|
1140
|
+
if (chain) for (let i = 0; i < chain.length; i++) {
|
|
1141
|
+
const c = chain[i];
|
|
1142
|
+
if (newBase.type.kind === "object" && newBase.type.props.has(c)) newBase = newBase.type.props.get(c);
|
|
1142
1143
|
else {
|
|
1143
|
-
|
|
1144
|
-
|
|
1144
|
+
const keys = chain.slice(0, i + 1).map((k) => `["${k}"]`).join("");
|
|
1145
|
+
throw new Error(`Can't find prop ${typeName}${keys}`);
|
|
1146
|
+
}
|
|
1145
1147
|
}
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
+
this.$type = createAnnotatedTypeNode(newBase.type, metadata, {
|
|
1149
|
+
id: newBase.id,
|
|
1150
|
+
ref: chain && chain.length > 0 ? {
|
|
1151
|
+
type: () => type$1,
|
|
1152
|
+
field: chain.join(".")
|
|
1153
|
+
} : undefined
|
|
1154
|
+
});
|
|
1155
|
+
} else if (typeof type$1 === "function") {
|
|
1156
|
+
const lazyType = type$1;
|
|
1157
|
+
this.$type = createAnnotatedTypeNode({ kind: "" }, metadata, { ref: {
|
|
1158
|
+
type: lazyType,
|
|
1159
|
+
field: chain ? chain.join(".") : ""
|
|
1160
|
+
} });
|
|
1161
|
+
const node = this.$type;
|
|
1162
|
+
const placeholder = node.type;
|
|
1163
|
+
Object.defineProperty(node, "type", {
|
|
1164
|
+
get() {
|
|
1165
|
+
const t = lazyType();
|
|
1166
|
+
if (!isAnnotatedType(t)) {
|
|
1167
|
+
Object.defineProperty(node, "type", {
|
|
1168
|
+
value: placeholder,
|
|
1169
|
+
writable: false,
|
|
1170
|
+
configurable: true
|
|
1171
|
+
});
|
|
1172
|
+
return placeholder;
|
|
1173
|
+
}
|
|
1174
|
+
let target = t;
|
|
1175
|
+
if (chain) for (const c of chain) if (target.type.kind === "object" && target.type.props.has(c)) target = target.type.props.get(c);
|
|
1176
|
+
else return t.type;
|
|
1177
|
+
node.id = target.id || t.id;
|
|
1178
|
+
Object.defineProperty(node, "type", {
|
|
1179
|
+
value: target.type,
|
|
1180
|
+
writable: false,
|
|
1181
|
+
configurable: true
|
|
1182
|
+
});
|
|
1183
|
+
return target.type;
|
|
1184
|
+
},
|
|
1185
|
+
configurable: true
|
|
1186
|
+
});
|
|
1187
|
+
} else throw new Error(`${type$1} is not annotated type`);
|
|
1148
1188
|
return this;
|
|
1149
1189
|
},
|
|
1150
1190
|
annotate(key, value, asArray) {
|
|
@@ -1629,8 +1669,8 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1629
1669
|
const ref = node;
|
|
1630
1670
|
const decl = this.doc.unwindType(ref.id, ref.chain)?.def;
|
|
1631
1671
|
if ((0, __atscript_core.isPrimitive)(decl)) {
|
|
1632
|
-
const ownerDecl = this.doc.getDeclarationOwnerNode(ref.id);
|
|
1633
|
-
if (!ownerDecl?.node || ownerDecl.node.entity !== "type" && ownerDecl.node.entity !== "interface") {
|
|
1672
|
+
const ownerDecl$1 = this.doc.getDeclarationOwnerNode(ref.id);
|
|
1673
|
+
if (!ownerDecl$1?.node || ownerDecl$1.node.entity !== "type" && ownerDecl$1.node.entity !== "interface") {
|
|
1634
1674
|
this.annotateType(decl, name);
|
|
1635
1675
|
return this;
|
|
1636
1676
|
}
|
|
@@ -1644,9 +1684,11 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1644
1684
|
}
|
|
1645
1685
|
}
|
|
1646
1686
|
const chain = ref.hasChain ? `, [${ref.chain.map((c) => `"${escapeQuotes(c.text)}"`).join(", ")}]` : "";
|
|
1647
|
-
|
|
1687
|
+
const ownerDecl = this.doc.getDeclarationOwnerNode(ref.id);
|
|
1688
|
+
const isImported = ownerDecl ? ownerDecl.doc !== this.doc : false;
|
|
1689
|
+
const refExpr = isImported ? `() => ${ref.id}` : ref.id;
|
|
1690
|
+
this.writeln(`$(${name ? `"", ${name}` : ""})`).indent().writeln(`.refTo(${refExpr}${chain})`);
|
|
1648
1691
|
if (!ref.hasChain) {
|
|
1649
|
-
const ownerDecl = this.doc.getDeclarationOwnerNode(ref.id);
|
|
1650
1692
|
if (ownerDecl?.node) {
|
|
1651
1693
|
const typeAnnotations = ownerDecl.doc.evalAnnotationsForNode(ownerDecl.node);
|
|
1652
1694
|
typeAnnotations?.forEach((an) => {
|
package/dist/index.mjs
CHANGED
|
@@ -1031,7 +1031,8 @@ function createAnnotatedTypeNode(type, metadata, opts) {
|
|
|
1031
1031
|
metadata,
|
|
1032
1032
|
validator: validatorMethod,
|
|
1033
1033
|
id: opts?.id,
|
|
1034
|
-
optional: opts?.optional
|
|
1034
|
+
optional: opts?.optional,
|
|
1035
|
+
ref: opts?.ref
|
|
1035
1036
|
};
|
|
1036
1037
|
}
|
|
1037
1038
|
function isAnnotatedType(type) {
|
|
@@ -1108,18 +1109,57 @@ function defineAnnotatedType(_kind, base) {
|
|
|
1108
1109
|
return this;
|
|
1109
1110
|
},
|
|
1110
1111
|
refTo(type$1, chain) {
|
|
1111
|
-
if (
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1112
|
+
if (isAnnotatedType(type$1)) {
|
|
1113
|
+
let newBase = type$1;
|
|
1114
|
+
const typeName = type$1.name || "Unknown";
|
|
1115
|
+
if (chain) for (let i = 0; i < chain.length; i++) {
|
|
1116
|
+
const c = chain[i];
|
|
1117
|
+
if (newBase.type.kind === "object" && newBase.type.props.has(c)) newBase = newBase.type.props.get(c);
|
|
1117
1118
|
else {
|
|
1118
|
-
|
|
1119
|
-
|
|
1119
|
+
const keys = chain.slice(0, i + 1).map((k) => `["${k}"]`).join("");
|
|
1120
|
+
throw new Error(`Can't find prop ${typeName}${keys}`);
|
|
1121
|
+
}
|
|
1120
1122
|
}
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
+
this.$type = createAnnotatedTypeNode(newBase.type, metadata, {
|
|
1124
|
+
id: newBase.id,
|
|
1125
|
+
ref: chain && chain.length > 0 ? {
|
|
1126
|
+
type: () => type$1,
|
|
1127
|
+
field: chain.join(".")
|
|
1128
|
+
} : undefined
|
|
1129
|
+
});
|
|
1130
|
+
} else if (typeof type$1 === "function") {
|
|
1131
|
+
const lazyType = type$1;
|
|
1132
|
+
this.$type = createAnnotatedTypeNode({ kind: "" }, metadata, { ref: {
|
|
1133
|
+
type: lazyType,
|
|
1134
|
+
field: chain ? chain.join(".") : ""
|
|
1135
|
+
} });
|
|
1136
|
+
const node = this.$type;
|
|
1137
|
+
const placeholder = node.type;
|
|
1138
|
+
Object.defineProperty(node, "type", {
|
|
1139
|
+
get() {
|
|
1140
|
+
const t = lazyType();
|
|
1141
|
+
if (!isAnnotatedType(t)) {
|
|
1142
|
+
Object.defineProperty(node, "type", {
|
|
1143
|
+
value: placeholder,
|
|
1144
|
+
writable: false,
|
|
1145
|
+
configurable: true
|
|
1146
|
+
});
|
|
1147
|
+
return placeholder;
|
|
1148
|
+
}
|
|
1149
|
+
let target = t;
|
|
1150
|
+
if (chain) for (const c of chain) if (target.type.kind === "object" && target.type.props.has(c)) target = target.type.props.get(c);
|
|
1151
|
+
else return t.type;
|
|
1152
|
+
node.id = target.id || t.id;
|
|
1153
|
+
Object.defineProperty(node, "type", {
|
|
1154
|
+
value: target.type,
|
|
1155
|
+
writable: false,
|
|
1156
|
+
configurable: true
|
|
1157
|
+
});
|
|
1158
|
+
return target.type;
|
|
1159
|
+
},
|
|
1160
|
+
configurable: true
|
|
1161
|
+
});
|
|
1162
|
+
} else throw new Error(`${type$1} is not annotated type`);
|
|
1123
1163
|
return this;
|
|
1124
1164
|
},
|
|
1125
1165
|
annotate(key, value, asArray) {
|
|
@@ -1604,8 +1644,8 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1604
1644
|
const ref = node;
|
|
1605
1645
|
const decl = this.doc.unwindType(ref.id, ref.chain)?.def;
|
|
1606
1646
|
if (isPrimitive(decl)) {
|
|
1607
|
-
const ownerDecl = this.doc.getDeclarationOwnerNode(ref.id);
|
|
1608
|
-
if (!ownerDecl?.node || ownerDecl.node.entity !== "type" && ownerDecl.node.entity !== "interface") {
|
|
1647
|
+
const ownerDecl$1 = this.doc.getDeclarationOwnerNode(ref.id);
|
|
1648
|
+
if (!ownerDecl$1?.node || ownerDecl$1.node.entity !== "type" && ownerDecl$1.node.entity !== "interface") {
|
|
1609
1649
|
this.annotateType(decl, name);
|
|
1610
1650
|
return this;
|
|
1611
1651
|
}
|
|
@@ -1619,9 +1659,11 @@ else handle.prop(prop.id, propHandle.$type);
|
|
|
1619
1659
|
}
|
|
1620
1660
|
}
|
|
1621
1661
|
const chain = ref.hasChain ? `, [${ref.chain.map((c) => `"${escapeQuotes(c.text)}"`).join(", ")}]` : "";
|
|
1622
|
-
|
|
1662
|
+
const ownerDecl = this.doc.getDeclarationOwnerNode(ref.id);
|
|
1663
|
+
const isImported = ownerDecl ? ownerDecl.doc !== this.doc : false;
|
|
1664
|
+
const refExpr = isImported ? `() => ${ref.id}` : ref.id;
|
|
1665
|
+
this.writeln(`$(${name ? `"", ${name}` : ""})`).indent().writeln(`.refTo(${refExpr}${chain})`);
|
|
1623
1666
|
if (!ref.hasChain) {
|
|
1624
|
-
const ownerDecl = this.doc.getDeclarationOwnerNode(ref.id);
|
|
1625
1667
|
if (ownerDecl?.node) {
|
|
1626
1668
|
const typeAnnotations = ownerDecl.doc.evalAnnotationsForNode(ownerDecl.node);
|
|
1627
1669
|
typeAnnotations?.forEach((an) => {
|
package/dist/utils.cjs
CHANGED
|
@@ -452,7 +452,8 @@ function createAnnotatedTypeNode(type, metadata, opts) {
|
|
|
452
452
|
metadata,
|
|
453
453
|
validator: validatorMethod,
|
|
454
454
|
id: opts?.id,
|
|
455
|
-
optional: opts?.optional
|
|
455
|
+
optional: opts?.optional,
|
|
456
|
+
ref: opts?.ref
|
|
456
457
|
};
|
|
457
458
|
}
|
|
458
459
|
function isAnnotatedType(type) {
|
|
@@ -576,18 +577,57 @@ function defineAnnotatedType(_kind, base) {
|
|
|
576
577
|
return this;
|
|
577
578
|
},
|
|
578
579
|
refTo(type$1, chain) {
|
|
579
|
-
if (
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
580
|
+
if (isAnnotatedType(type$1)) {
|
|
581
|
+
let newBase = type$1;
|
|
582
|
+
const typeName = type$1.name || "Unknown";
|
|
583
|
+
if (chain) for (let i = 0; i < chain.length; i++) {
|
|
584
|
+
const c = chain[i];
|
|
585
|
+
if (newBase.type.kind === "object" && newBase.type.props.has(c)) newBase = newBase.type.props.get(c);
|
|
585
586
|
else {
|
|
586
|
-
|
|
587
|
-
|
|
587
|
+
const keys = chain.slice(0, i + 1).map((k) => `["${k}"]`).join("");
|
|
588
|
+
throw new Error(`Can't find prop ${typeName}${keys}`);
|
|
589
|
+
}
|
|
588
590
|
}
|
|
589
|
-
|
|
590
|
-
|
|
591
|
+
this.$type = createAnnotatedTypeNode(newBase.type, metadata, {
|
|
592
|
+
id: newBase.id,
|
|
593
|
+
ref: chain && chain.length > 0 ? {
|
|
594
|
+
type: () => type$1,
|
|
595
|
+
field: chain.join(".")
|
|
596
|
+
} : undefined
|
|
597
|
+
});
|
|
598
|
+
} else if (typeof type$1 === "function") {
|
|
599
|
+
const lazyType = type$1;
|
|
600
|
+
this.$type = createAnnotatedTypeNode({ kind: "" }, metadata, { ref: {
|
|
601
|
+
type: lazyType,
|
|
602
|
+
field: chain ? chain.join(".") : ""
|
|
603
|
+
} });
|
|
604
|
+
const node = this.$type;
|
|
605
|
+
const placeholder = node.type;
|
|
606
|
+
Object.defineProperty(node, "type", {
|
|
607
|
+
get() {
|
|
608
|
+
const t = lazyType();
|
|
609
|
+
if (!isAnnotatedType(t)) {
|
|
610
|
+
Object.defineProperty(node, "type", {
|
|
611
|
+
value: placeholder,
|
|
612
|
+
writable: false,
|
|
613
|
+
configurable: true
|
|
614
|
+
});
|
|
615
|
+
return placeholder;
|
|
616
|
+
}
|
|
617
|
+
let target = t;
|
|
618
|
+
if (chain) for (const c of chain) if (target.type.kind === "object" && target.type.props.has(c)) target = target.type.props.get(c);
|
|
619
|
+
else return t.type;
|
|
620
|
+
node.id = target.id || t.id;
|
|
621
|
+
Object.defineProperty(node, "type", {
|
|
622
|
+
value: target.type,
|
|
623
|
+
writable: false,
|
|
624
|
+
configurable: true
|
|
625
|
+
});
|
|
626
|
+
return target.type;
|
|
627
|
+
},
|
|
628
|
+
configurable: true
|
|
629
|
+
});
|
|
630
|
+
} else throw new Error(`${type$1} is not annotated type`);
|
|
591
631
|
return this;
|
|
592
632
|
},
|
|
593
633
|
annotate(key, value, asArray) {
|
|
@@ -1020,6 +1060,7 @@ function throwFeatureDisabled(feature, option, annotation) {
|
|
|
1020
1060
|
function flattenAnnotatedType(type, options) {
|
|
1021
1061
|
const flatMap = new Map();
|
|
1022
1062
|
const skipPhantom = !!options?.excludePhantomTypes;
|
|
1063
|
+
const visitedIds = new Set();
|
|
1023
1064
|
function addFieldToFlatMap(name, def) {
|
|
1024
1065
|
const existing = flatMap.get(name);
|
|
1025
1066
|
if (existing) {
|
|
@@ -1056,6 +1097,13 @@ else flatUnion.item(existing);
|
|
|
1056
1097
|
}
|
|
1057
1098
|
}
|
|
1058
1099
|
function flattenType(def, prefix = "", inComplexTypeOrArray = false) {
|
|
1100
|
+
const typeId = def.id;
|
|
1101
|
+
if (typeId && visitedIds.has(typeId)) {
|
|
1102
|
+
addFieldToFlatMap(prefix || "", def);
|
|
1103
|
+
if (prefix) options?.onField?.(prefix, def, def.metadata);
|
|
1104
|
+
return;
|
|
1105
|
+
}
|
|
1106
|
+
if (typeId) visitedIds.add(typeId);
|
|
1059
1107
|
switch (def.type.kind) {
|
|
1060
1108
|
case "object": {
|
|
1061
1109
|
addFieldToFlatMap(prefix || "", def);
|
|
@@ -1102,20 +1150,31 @@ else flatUnion.item(existing);
|
|
|
1102
1150
|
//#region packages/typescript/src/serialize.ts
|
|
1103
1151
|
const SERIALIZE_VERSION = 1;
|
|
1104
1152
|
function serializeAnnotatedType(type, options) {
|
|
1105
|
-
const
|
|
1153
|
+
const visited = new Set();
|
|
1154
|
+
const result = serializeNode(type, [], options, visited);
|
|
1106
1155
|
result.$v = SERIALIZE_VERSION;
|
|
1107
1156
|
return result;
|
|
1108
1157
|
}
|
|
1109
|
-
function serializeNode(def, path, options) {
|
|
1158
|
+
function serializeNode(def, path, options, visited) {
|
|
1159
|
+
if (def.id && visited.has(def.id)) return {
|
|
1160
|
+
type: {
|
|
1161
|
+
kind: "$ref",
|
|
1162
|
+
id: def.id
|
|
1163
|
+
},
|
|
1164
|
+
metadata: {},
|
|
1165
|
+
...def.optional ? { optional: true } : {},
|
|
1166
|
+
id: def.id
|
|
1167
|
+
};
|
|
1168
|
+
if (def.id) visited.add(def.id);
|
|
1110
1169
|
const result = {
|
|
1111
|
-
type: serializeTypeDef(def, path, options),
|
|
1170
|
+
type: serializeTypeDef(def, path, options, visited),
|
|
1112
1171
|
metadata: serializeMetadata(def.metadata, path, def.type.kind, options)
|
|
1113
1172
|
};
|
|
1114
1173
|
if (def.optional) result.optional = true;
|
|
1115
1174
|
if (def.id) result.id = def.id;
|
|
1116
1175
|
return result;
|
|
1117
1176
|
}
|
|
1118
|
-
function serializeTypeDef(def, path, options) {
|
|
1177
|
+
function serializeTypeDef(def, path, options, visited) {
|
|
1119
1178
|
return forAnnotatedType(def, {
|
|
1120
1179
|
phantom(d) {
|
|
1121
1180
|
return {
|
|
@@ -1135,13 +1194,13 @@ function serializeTypeDef(def, path, options) {
|
|
|
1135
1194
|
},
|
|
1136
1195
|
object(d) {
|
|
1137
1196
|
const props = {};
|
|
1138
|
-
for (const [key, val] of d.type.props.entries()) props[key] = serializeNode(val, [...path, key], options);
|
|
1197
|
+
for (const [key, val] of d.type.props.entries()) props[key] = serializeNode(val, [...path, key], options, visited);
|
|
1139
1198
|
const propsPatterns = d.type.propsPatterns.map((pp) => ({
|
|
1140
1199
|
pattern: {
|
|
1141
1200
|
source: pp.pattern.source,
|
|
1142
1201
|
flags: pp.pattern.flags
|
|
1143
1202
|
},
|
|
1144
|
-
def: serializeNode(pp.def, path, options)
|
|
1203
|
+
def: serializeNode(pp.def, path, options, visited)
|
|
1145
1204
|
}));
|
|
1146
1205
|
return {
|
|
1147
1206
|
kind: "object",
|
|
@@ -1153,28 +1212,28 @@ function serializeTypeDef(def, path, options) {
|
|
|
1153
1212
|
array(d) {
|
|
1154
1213
|
return {
|
|
1155
1214
|
kind: "array",
|
|
1156
|
-
of: serializeNode(d.type.of, path, options),
|
|
1215
|
+
of: serializeNode(d.type.of, path, options, visited),
|
|
1157
1216
|
tags: Array.from(d.type.tags)
|
|
1158
1217
|
};
|
|
1159
1218
|
},
|
|
1160
1219
|
union(d) {
|
|
1161
1220
|
return {
|
|
1162
1221
|
kind: "union",
|
|
1163
|
-
items: d.type.items.map((item) => serializeNode(item, path, options)),
|
|
1222
|
+
items: d.type.items.map((item) => serializeNode(item, path, options, visited)),
|
|
1164
1223
|
tags: Array.from(d.type.tags)
|
|
1165
1224
|
};
|
|
1166
1225
|
},
|
|
1167
1226
|
intersection(d) {
|
|
1168
1227
|
return {
|
|
1169
1228
|
kind: "intersection",
|
|
1170
|
-
items: d.type.items.map((item) => serializeNode(item, path, options)),
|
|
1229
|
+
items: d.type.items.map((item) => serializeNode(item, path, options, visited)),
|
|
1171
1230
|
tags: Array.from(d.type.tags)
|
|
1172
1231
|
};
|
|
1173
1232
|
},
|
|
1174
1233
|
tuple(d) {
|
|
1175
1234
|
return {
|
|
1176
1235
|
kind: "tuple",
|
|
1177
|
-
items: d.type.items.map((item) => serializeNode(item, path, options)),
|
|
1236
|
+
items: d.type.items.map((item) => serializeNode(item, path, options, visited)),
|
|
1178
1237
|
tags: Array.from(d.type.tags)
|
|
1179
1238
|
};
|
|
1180
1239
|
}
|
|
@@ -1251,6 +1310,12 @@ function deserializeTypeDef(t) {
|
|
|
1251
1310
|
items: t.items.map((item) => deserializeNode(item)),
|
|
1252
1311
|
tags
|
|
1253
1312
|
};
|
|
1313
|
+
case "$ref": return {
|
|
1314
|
+
kind: "object",
|
|
1315
|
+
props: new Map(),
|
|
1316
|
+
propsPatterns: [],
|
|
1317
|
+
tags
|
|
1318
|
+
};
|
|
1254
1319
|
default: throw new Error(`Unknown serialized type kind "${t.kind}"`);
|
|
1255
1320
|
}
|
|
1256
1321
|
}
|
package/dist/utils.d.ts
CHANGED
|
@@ -103,6 +103,10 @@ declare class ValidatorError extends Error {
|
|
|
103
103
|
declare function createAnnotatedTypeNode(type: TAtscriptTypeDef, metadata: TMetadataMap<AtscriptMetadata>, opts?: {
|
|
104
104
|
id?: string;
|
|
105
105
|
optional?: boolean;
|
|
106
|
+
ref?: {
|
|
107
|
+
type: () => TAtscriptAnnotatedType;
|
|
108
|
+
field: string;
|
|
109
|
+
};
|
|
106
110
|
}): TAtscriptAnnotatedType;
|
|
107
111
|
/** Type definition for union, intersection, or tuple types. */
|
|
108
112
|
interface TAtscriptTypeComplex<DataType = unknown> {
|
|
@@ -191,6 +195,10 @@ interface TAtscriptAnnotatedType<T extends TAtscriptTypeDef = TAtscriptTypeDef,
|
|
|
191
195
|
metadata: TMetadataMap<AtscriptMetadata>;
|
|
192
196
|
optional?: boolean;
|
|
193
197
|
id?: string;
|
|
198
|
+
ref?: {
|
|
199
|
+
type: () => TAtscriptAnnotatedType;
|
|
200
|
+
field: string;
|
|
201
|
+
};
|
|
194
202
|
}
|
|
195
203
|
/** An annotated type that is also a class constructor (i.e. a generated interface class). */
|
|
196
204
|
type TAtscriptAnnotatedTypeConstructor = TAtscriptAnnotatedType & (new (...args: any[]) => any);
|
|
@@ -252,9 +260,11 @@ interface TAnnotatedTypeHandle {
|
|
|
252
260
|
propPattern(pattern: RegExp, value: TAtscriptAnnotatedType): TAnnotatedTypeHandle;
|
|
253
261
|
optional(value?: boolean): TAnnotatedTypeHandle;
|
|
254
262
|
copyMetadata(fromMetadata: TMetadataMap<AtscriptMetadata>): TAnnotatedTypeHandle;
|
|
255
|
-
refTo(type: TAtscriptAnnotatedType & {
|
|
263
|
+
refTo(type: (TAtscriptAnnotatedType & {
|
|
256
264
|
name?: string;
|
|
257
|
-
}
|
|
265
|
+
}) | (() => TAtscriptAnnotatedType & {
|
|
266
|
+
name?: string;
|
|
267
|
+
}), chain?: string[]): TAnnotatedTypeHandle;
|
|
258
268
|
annotate(key: keyof AtscriptMetadata, value: any, asArray?: boolean): TAnnotatedTypeHandle;
|
|
259
269
|
id(value: string): TAnnotatedTypeHandle;
|
|
260
270
|
}
|
|
@@ -478,7 +488,11 @@ interface TSerializedTypeComplex {
|
|
|
478
488
|
items: TSerializedAnnotatedTypeInner[];
|
|
479
489
|
tags: string[];
|
|
480
490
|
}
|
|
481
|
-
|
|
491
|
+
interface TSerializedTypeRef {
|
|
492
|
+
kind: '$ref';
|
|
493
|
+
id: string;
|
|
494
|
+
}
|
|
495
|
+
type TSerializedTypeDef = TSerializedTypeFinal | TSerializedTypeObject | TSerializedTypeArray | TSerializedTypeComplex | TSerializedTypeRef;
|
|
482
496
|
/** Context passed to {@link TSerializeOptions.processAnnotation} for each annotation entry. */
|
|
483
497
|
interface TProcessAnnotationContext {
|
|
484
498
|
/** Annotation key, e.g. "meta.label" */
|
package/dist/utils.mjs
CHANGED
|
@@ -451,7 +451,8 @@ function createAnnotatedTypeNode(type, metadata, opts) {
|
|
|
451
451
|
metadata,
|
|
452
452
|
validator: validatorMethod,
|
|
453
453
|
id: opts?.id,
|
|
454
|
-
optional: opts?.optional
|
|
454
|
+
optional: opts?.optional,
|
|
455
|
+
ref: opts?.ref
|
|
455
456
|
};
|
|
456
457
|
}
|
|
457
458
|
function isAnnotatedType(type) {
|
|
@@ -575,18 +576,57 @@ function defineAnnotatedType(_kind, base) {
|
|
|
575
576
|
return this;
|
|
576
577
|
},
|
|
577
578
|
refTo(type$1, chain) {
|
|
578
|
-
if (
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
579
|
+
if (isAnnotatedType(type$1)) {
|
|
580
|
+
let newBase = type$1;
|
|
581
|
+
const typeName = type$1.name || "Unknown";
|
|
582
|
+
if (chain) for (let i = 0; i < chain.length; i++) {
|
|
583
|
+
const c = chain[i];
|
|
584
|
+
if (newBase.type.kind === "object" && newBase.type.props.has(c)) newBase = newBase.type.props.get(c);
|
|
584
585
|
else {
|
|
585
|
-
|
|
586
|
-
|
|
586
|
+
const keys = chain.slice(0, i + 1).map((k) => `["${k}"]`).join("");
|
|
587
|
+
throw new Error(`Can't find prop ${typeName}${keys}`);
|
|
588
|
+
}
|
|
587
589
|
}
|
|
588
|
-
|
|
589
|
-
|
|
590
|
+
this.$type = createAnnotatedTypeNode(newBase.type, metadata, {
|
|
591
|
+
id: newBase.id,
|
|
592
|
+
ref: chain && chain.length > 0 ? {
|
|
593
|
+
type: () => type$1,
|
|
594
|
+
field: chain.join(".")
|
|
595
|
+
} : undefined
|
|
596
|
+
});
|
|
597
|
+
} else if (typeof type$1 === "function") {
|
|
598
|
+
const lazyType = type$1;
|
|
599
|
+
this.$type = createAnnotatedTypeNode({ kind: "" }, metadata, { ref: {
|
|
600
|
+
type: lazyType,
|
|
601
|
+
field: chain ? chain.join(".") : ""
|
|
602
|
+
} });
|
|
603
|
+
const node = this.$type;
|
|
604
|
+
const placeholder = node.type;
|
|
605
|
+
Object.defineProperty(node, "type", {
|
|
606
|
+
get() {
|
|
607
|
+
const t = lazyType();
|
|
608
|
+
if (!isAnnotatedType(t)) {
|
|
609
|
+
Object.defineProperty(node, "type", {
|
|
610
|
+
value: placeholder,
|
|
611
|
+
writable: false,
|
|
612
|
+
configurable: true
|
|
613
|
+
});
|
|
614
|
+
return placeholder;
|
|
615
|
+
}
|
|
616
|
+
let target = t;
|
|
617
|
+
if (chain) for (const c of chain) if (target.type.kind === "object" && target.type.props.has(c)) target = target.type.props.get(c);
|
|
618
|
+
else return t.type;
|
|
619
|
+
node.id = target.id || t.id;
|
|
620
|
+
Object.defineProperty(node, "type", {
|
|
621
|
+
value: target.type,
|
|
622
|
+
writable: false,
|
|
623
|
+
configurable: true
|
|
624
|
+
});
|
|
625
|
+
return target.type;
|
|
626
|
+
},
|
|
627
|
+
configurable: true
|
|
628
|
+
});
|
|
629
|
+
} else throw new Error(`${type$1} is not annotated type`);
|
|
590
630
|
return this;
|
|
591
631
|
},
|
|
592
632
|
annotate(key, value, asArray) {
|
|
@@ -1019,6 +1059,7 @@ function throwFeatureDisabled(feature, option, annotation) {
|
|
|
1019
1059
|
function flattenAnnotatedType(type, options) {
|
|
1020
1060
|
const flatMap = new Map();
|
|
1021
1061
|
const skipPhantom = !!options?.excludePhantomTypes;
|
|
1062
|
+
const visitedIds = new Set();
|
|
1022
1063
|
function addFieldToFlatMap(name, def) {
|
|
1023
1064
|
const existing = flatMap.get(name);
|
|
1024
1065
|
if (existing) {
|
|
@@ -1055,6 +1096,13 @@ else flatUnion.item(existing);
|
|
|
1055
1096
|
}
|
|
1056
1097
|
}
|
|
1057
1098
|
function flattenType(def, prefix = "", inComplexTypeOrArray = false) {
|
|
1099
|
+
const typeId = def.id;
|
|
1100
|
+
if (typeId && visitedIds.has(typeId)) {
|
|
1101
|
+
addFieldToFlatMap(prefix || "", def);
|
|
1102
|
+
if (prefix) options?.onField?.(prefix, def, def.metadata);
|
|
1103
|
+
return;
|
|
1104
|
+
}
|
|
1105
|
+
if (typeId) visitedIds.add(typeId);
|
|
1058
1106
|
switch (def.type.kind) {
|
|
1059
1107
|
case "object": {
|
|
1060
1108
|
addFieldToFlatMap(prefix || "", def);
|
|
@@ -1101,20 +1149,31 @@ else flatUnion.item(existing);
|
|
|
1101
1149
|
//#region packages/typescript/src/serialize.ts
|
|
1102
1150
|
const SERIALIZE_VERSION = 1;
|
|
1103
1151
|
function serializeAnnotatedType(type, options) {
|
|
1104
|
-
const
|
|
1152
|
+
const visited = new Set();
|
|
1153
|
+
const result = serializeNode(type, [], options, visited);
|
|
1105
1154
|
result.$v = SERIALIZE_VERSION;
|
|
1106
1155
|
return result;
|
|
1107
1156
|
}
|
|
1108
|
-
function serializeNode(def, path, options) {
|
|
1157
|
+
function serializeNode(def, path, options, visited) {
|
|
1158
|
+
if (def.id && visited.has(def.id)) return {
|
|
1159
|
+
type: {
|
|
1160
|
+
kind: "$ref",
|
|
1161
|
+
id: def.id
|
|
1162
|
+
},
|
|
1163
|
+
metadata: {},
|
|
1164
|
+
...def.optional ? { optional: true } : {},
|
|
1165
|
+
id: def.id
|
|
1166
|
+
};
|
|
1167
|
+
if (def.id) visited.add(def.id);
|
|
1109
1168
|
const result = {
|
|
1110
|
-
type: serializeTypeDef(def, path, options),
|
|
1169
|
+
type: serializeTypeDef(def, path, options, visited),
|
|
1111
1170
|
metadata: serializeMetadata(def.metadata, path, def.type.kind, options)
|
|
1112
1171
|
};
|
|
1113
1172
|
if (def.optional) result.optional = true;
|
|
1114
1173
|
if (def.id) result.id = def.id;
|
|
1115
1174
|
return result;
|
|
1116
1175
|
}
|
|
1117
|
-
function serializeTypeDef(def, path, options) {
|
|
1176
|
+
function serializeTypeDef(def, path, options, visited) {
|
|
1118
1177
|
return forAnnotatedType(def, {
|
|
1119
1178
|
phantom(d) {
|
|
1120
1179
|
return {
|
|
@@ -1134,13 +1193,13 @@ function serializeTypeDef(def, path, options) {
|
|
|
1134
1193
|
},
|
|
1135
1194
|
object(d) {
|
|
1136
1195
|
const props = {};
|
|
1137
|
-
for (const [key, val] of d.type.props.entries()) props[key] = serializeNode(val, [...path, key], options);
|
|
1196
|
+
for (const [key, val] of d.type.props.entries()) props[key] = serializeNode(val, [...path, key], options, visited);
|
|
1138
1197
|
const propsPatterns = d.type.propsPatterns.map((pp) => ({
|
|
1139
1198
|
pattern: {
|
|
1140
1199
|
source: pp.pattern.source,
|
|
1141
1200
|
flags: pp.pattern.flags
|
|
1142
1201
|
},
|
|
1143
|
-
def: serializeNode(pp.def, path, options)
|
|
1202
|
+
def: serializeNode(pp.def, path, options, visited)
|
|
1144
1203
|
}));
|
|
1145
1204
|
return {
|
|
1146
1205
|
kind: "object",
|
|
@@ -1152,28 +1211,28 @@ function serializeTypeDef(def, path, options) {
|
|
|
1152
1211
|
array(d) {
|
|
1153
1212
|
return {
|
|
1154
1213
|
kind: "array",
|
|
1155
|
-
of: serializeNode(d.type.of, path, options),
|
|
1214
|
+
of: serializeNode(d.type.of, path, options, visited),
|
|
1156
1215
|
tags: Array.from(d.type.tags)
|
|
1157
1216
|
};
|
|
1158
1217
|
},
|
|
1159
1218
|
union(d) {
|
|
1160
1219
|
return {
|
|
1161
1220
|
kind: "union",
|
|
1162
|
-
items: d.type.items.map((item) => serializeNode(item, path, options)),
|
|
1221
|
+
items: d.type.items.map((item) => serializeNode(item, path, options, visited)),
|
|
1163
1222
|
tags: Array.from(d.type.tags)
|
|
1164
1223
|
};
|
|
1165
1224
|
},
|
|
1166
1225
|
intersection(d) {
|
|
1167
1226
|
return {
|
|
1168
1227
|
kind: "intersection",
|
|
1169
|
-
items: d.type.items.map((item) => serializeNode(item, path, options)),
|
|
1228
|
+
items: d.type.items.map((item) => serializeNode(item, path, options, visited)),
|
|
1170
1229
|
tags: Array.from(d.type.tags)
|
|
1171
1230
|
};
|
|
1172
1231
|
},
|
|
1173
1232
|
tuple(d) {
|
|
1174
1233
|
return {
|
|
1175
1234
|
kind: "tuple",
|
|
1176
|
-
items: d.type.items.map((item) => serializeNode(item, path, options)),
|
|
1235
|
+
items: d.type.items.map((item) => serializeNode(item, path, options, visited)),
|
|
1177
1236
|
tags: Array.from(d.type.tags)
|
|
1178
1237
|
};
|
|
1179
1238
|
}
|
|
@@ -1250,6 +1309,12 @@ function deserializeTypeDef(t) {
|
|
|
1250
1309
|
items: t.items.map((item) => deserializeNode(item)),
|
|
1251
1310
|
tags
|
|
1252
1311
|
};
|
|
1312
|
+
case "$ref": return {
|
|
1313
|
+
kind: "object",
|
|
1314
|
+
props: new Map(),
|
|
1315
|
+
propsPatterns: [],
|
|
1316
|
+
tags
|
|
1317
|
+
};
|
|
1253
1318
|
default: throw new Error(`Unknown serialized type kind "${t.kind}"`);
|
|
1254
1319
|
}
|
|
1255
1320
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atscript/typescript",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.34",
|
|
4
4
|
"description": "Atscript: typescript-gen support.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"annotations",
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"vitest": "3.2.4"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
|
-
"@atscript/core": "^0.1.
|
|
67
|
+
"@atscript/core": "^0.1.34"
|
|
68
68
|
},
|
|
69
69
|
"build": [
|
|
70
70
|
{},
|