@player-tools/xlr-converters 0.2.1-next.4 → 0.2.2--canary.17.363
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/index.cjs.js +64 -17
- package/dist/index.esm.js +64 -17
- package/package.json +3 -3
- package/src/ts-to-xlr.ts +67 -9
- package/src/xlr-to-ts.ts +31 -11
package/dist/index.cjs.js
CHANGED
|
@@ -103,7 +103,8 @@ class TsConverter {
|
|
|
103
103
|
}
|
|
104
104
|
convertTsTypeNode(node) {
|
|
105
105
|
if (this.context.cache.convertedNodes.has(node)) {
|
|
106
|
-
|
|
106
|
+
const cachedType = this.context.cache.convertedNodes.get(node);
|
|
107
|
+
return JSON.parse(JSON.stringify(cachedType));
|
|
107
108
|
}
|
|
108
109
|
const convertedNode = this.tsNodeToType(node);
|
|
109
110
|
this.context.cache.convertedNodes.set(node, convertedNode);
|
|
@@ -265,14 +266,47 @@ class TsConverter {
|
|
|
265
266
|
if (ts__default["default"].isTypeReferenceNode(node.objectType) && ts__default["default"].isLiteralTypeNode(node.indexType)) {
|
|
266
267
|
const baseObject = this.convertTsTypeNode(node.objectType);
|
|
267
268
|
const accessor = node.indexType.literal.getText().replace(/["']/g, "");
|
|
268
|
-
if (
|
|
269
|
-
|
|
269
|
+
if (!baseObject) {
|
|
270
|
+
this.context.throwError(`Error: Couldn't resolve index access on property ${accessor} on type ${node.objectType.typeName.getText()}`);
|
|
271
|
+
} else if (baseObject.type === "object") {
|
|
272
|
+
if (Object.keys((_d = baseObject.properties) != null ? _d : {}).includes(accessor)) {
|
|
273
|
+
return baseObject.properties[accessor].node;
|
|
274
|
+
}
|
|
275
|
+
if (baseObject.additionalProperties) {
|
|
276
|
+
return baseObject.additionalProperties;
|
|
277
|
+
}
|
|
278
|
+
} else if (baseObject.type === "ref") {
|
|
279
|
+
return __spreadProps(__spreadValues$1({}, baseObject), { property: accessor });
|
|
280
|
+
} else {
|
|
281
|
+
this.context.throwError(`Error: Index access on non object/ref type ${baseObject.type}`);
|
|
270
282
|
}
|
|
271
|
-
|
|
272
|
-
|
|
283
|
+
}
|
|
284
|
+
if (ts__default["default"].isTypeQueryNode(node.objectType)) {
|
|
285
|
+
const effectiveType = this.context.typeChecker.getTypeAtLocation(node);
|
|
286
|
+
if (ts__default["default"].TypeFlags.Union & effectiveType.flags) {
|
|
287
|
+
return {
|
|
288
|
+
type: "or",
|
|
289
|
+
or: effectiveType.types.map((type) => {
|
|
290
|
+
if (ts__default["default"].TypeFlags.StringLiteral & type.flags) {
|
|
291
|
+
return {
|
|
292
|
+
type: "string",
|
|
293
|
+
const: type.value
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
if (ts__default["default"].TypeFlags.NumberLiteral & type.flags) {
|
|
297
|
+
return {
|
|
298
|
+
type: "number",
|
|
299
|
+
const: type.value
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
return {
|
|
303
|
+
type: "unknown"
|
|
304
|
+
};
|
|
305
|
+
})
|
|
306
|
+
};
|
|
273
307
|
}
|
|
274
308
|
}
|
|
275
|
-
|
|
309
|
+
this.context.throwError(`Error: could not solve IndexedAccessType ${node.getFullText()}`);
|
|
276
310
|
} else {
|
|
277
311
|
this.context.throwError(`Unimplemented type ${ts__default["default"].SyntaxKind[node.kind]}`);
|
|
278
312
|
}
|
|
@@ -352,6 +386,9 @@ class TsConverter {
|
|
|
352
386
|
return;
|
|
353
387
|
}
|
|
354
388
|
typeToApply = this.convertDeclaration(parentInterface);
|
|
389
|
+
if (typeToApply.extends) {
|
|
390
|
+
extendsType = typeToApply.extends;
|
|
391
|
+
}
|
|
355
392
|
if (parentInterface.typeParameters && parent.typeArguments) {
|
|
356
393
|
typeToApply = this.solveGenerics(typeToApply, parentInterface.typeParameters, parent.typeArguments);
|
|
357
394
|
} else if (xlrUtils.isGenericNodeType(baseObject)) {
|
|
@@ -540,7 +577,8 @@ var __spreadValues = (a, b) => {
|
|
|
540
577
|
}
|
|
541
578
|
return a;
|
|
542
579
|
};
|
|
543
|
-
const
|
|
580
|
+
const templateTokenize = /(?=true\|false|\.\*|\[0-9]\*)/gm;
|
|
581
|
+
const tokenSplit = /(?<=true\|false|\.\*|\[0-9]\*)/gm;
|
|
544
582
|
class TSWriter {
|
|
545
583
|
constructor(factory) {
|
|
546
584
|
this.context = {
|
|
@@ -571,9 +609,18 @@ class TSWriter {
|
|
|
571
609
|
if (xlrUtils.isGenericNamedType(type)) {
|
|
572
610
|
generics = this.createTypeParameters(type);
|
|
573
611
|
}
|
|
612
|
+
let customPrimitiveHeritageClass;
|
|
613
|
+
if (type.type === "object" && type.extends) {
|
|
614
|
+
const refName = type.extends.ref.split("<")[0];
|
|
615
|
+
customPrimitiveHeritageClass = [
|
|
616
|
+
this.context.factory.createHeritageClause(ts__default["default"].SyntaxKind.ExtendsKeyword, [
|
|
617
|
+
this.context.factory.createExpressionWithTypeArguments(this.context.factory.createIdentifier(refName), type.extends.genericArguments ? type.extends.genericArguments.map((node) => this.convertTypeNode(node)) : void 0)
|
|
618
|
+
])
|
|
619
|
+
];
|
|
620
|
+
}
|
|
574
621
|
let finalNode;
|
|
575
622
|
if (ts__default["default"].isTypeLiteralNode(tsNode)) {
|
|
576
|
-
finalNode = this.makeInterfaceDeclaration(typeName, tsNode.members, generics);
|
|
623
|
+
finalNode = this.makeInterfaceDeclaration(typeName, tsNode.members, generics, customPrimitiveHeritageClass);
|
|
577
624
|
} else {
|
|
578
625
|
finalNode = this.makeTypeDeclaration(typeName, tsNode, generics);
|
|
579
626
|
}
|
|
@@ -677,7 +724,7 @@ class TSWriter {
|
|
|
677
724
|
return xlrNode.const ? this.context.factory.createNumericLiteral(xlrNode.const) : this.context.throwError("Can't make literal type out of non constant number");
|
|
678
725
|
}
|
|
679
726
|
if (xlrNode.type === "string") {
|
|
680
|
-
return xlrNode.const ? this.context.factory.createStringLiteral(xlrNode.const) : this.context.throwError("Can't make literal type out of non constant string");
|
|
727
|
+
return xlrNode.const ? this.context.factory.createStringLiteral(xlrNode.const, true) : this.context.throwError("Can't make literal type out of non constant string");
|
|
681
728
|
}
|
|
682
729
|
if (xlrNode.type === "null") {
|
|
683
730
|
return this.context.factory.createNull();
|
|
@@ -689,7 +736,7 @@ class TSWriter {
|
|
|
689
736
|
}
|
|
690
737
|
createFunctionDeclarationNode(xlrNode) {
|
|
691
738
|
return this.context.factory.createFunctionTypeNode(void 0, xlrNode.parameters.map((e) => {
|
|
692
|
-
return this.context.factory.createParameterDeclaration(void 0, void 0,
|
|
739
|
+
return this.context.factory.createParameterDeclaration(void 0, void 0, e.name, e.optional ? this.context.factory.createToken(ts__default["default"].SyntaxKind.QuestionToken) : void 0, this.convertTypeNode(e.type), e.default ? this.createLiteralTypeNode(e.default) : void 0);
|
|
693
740
|
}), xlrNode.returnType ? this.convertTypeNode(xlrNode.returnType) : this.context.factory.createToken(ts__default["default"].SyntaxKind.VoidKeyword));
|
|
694
741
|
}
|
|
695
742
|
createRecordNode(xlrNode) {
|
|
@@ -710,23 +757,23 @@ class TSWriter {
|
|
|
710
757
|
...Object.keys(properties).map((name) => __spreadValues({ name }, properties[name])).map(({ name, node, required }) => this.makeAnnotations(this.context.factory.createPropertySignature(void 0, name, required ? void 0 : this.context.factory.createToken(ts__default["default"].SyntaxKind.QuestionToken), this.convertTypeNode(node)), node))
|
|
711
758
|
];
|
|
712
759
|
if (additionalProperties) {
|
|
713
|
-
propertyNodes.push(this.context.factory.createIndexSignature(void 0,
|
|
714
|
-
this.context.factory.createParameterDeclaration(void 0, void 0,
|
|
760
|
+
propertyNodes.push(this.context.factory.createIndexSignature(void 0, [
|
|
761
|
+
this.context.factory.createParameterDeclaration(void 0, void 0, "key", void 0, this.context.factory.createKeywordTypeNode(ts__default["default"].SyntaxKind.StringKeyword))
|
|
715
762
|
], this.convertTypeNode(additionalProperties)));
|
|
716
763
|
}
|
|
717
764
|
return this.context.factory.createTypeLiteralNode(propertyNodes);
|
|
718
765
|
}
|
|
719
766
|
createTemplateLiteral(xlrNode) {
|
|
720
|
-
const templateSegments = xlrNode.format.split(
|
|
767
|
+
const templateSegments = xlrNode.format.split(templateTokenize);
|
|
721
768
|
let templateHead;
|
|
722
|
-
if (templateSegments.length % 2) {
|
|
769
|
+
if (templateSegments.length % 2 === 0) {
|
|
723
770
|
templateHead = this.context.factory.createTemplateHead(templateSegments[0]);
|
|
724
771
|
templateSegments.splice(0, 1);
|
|
725
772
|
} else {
|
|
726
773
|
templateHead = this.context.factory.createTemplateHead("");
|
|
727
774
|
}
|
|
728
775
|
return this.context.factory.createTemplateLiteralType(templateHead, templateSegments.map((segments, i) => {
|
|
729
|
-
const [regexSegment, stringSegment] = segments.split(
|
|
776
|
+
const [regexSegment, stringSegment = ""] = segments.split(tokenSplit);
|
|
730
777
|
let regexTemplateType;
|
|
731
778
|
if (regexSegment === ".*") {
|
|
732
779
|
regexTemplateType = ts__default["default"].SyntaxKind.StringKeyword;
|
|
@@ -776,8 +823,8 @@ ${comment.split("\n").map((s) => ` * ${s}`).join("\n")}
|
|
|
776
823
|
return this.context.factory.createTypeParameterDeclaration(void 0, generic.symbol, this.createGenericArgumentNode(generic.constraints), this.createGenericArgumentNode(generic.default));
|
|
777
824
|
});
|
|
778
825
|
}
|
|
779
|
-
makeInterfaceDeclaration(name, node, generics) {
|
|
780
|
-
return this.context.factory.createInterfaceDeclaration(this.context.factory.createModifiersFromModifierFlags(ts__default["default"].ModifierFlags.Export), this.context.factory.createIdentifier(name), generics,
|
|
826
|
+
makeInterfaceDeclaration(name, node, generics, heritageClass) {
|
|
827
|
+
return this.context.factory.createInterfaceDeclaration(this.context.factory.createModifiersFromModifierFlags(ts__default["default"].ModifierFlags.Export), this.context.factory.createIdentifier(name), generics, heritageClass, node);
|
|
781
828
|
}
|
|
782
829
|
makeTypeDeclaration(name, node, generics) {
|
|
783
830
|
return this.context.factory.createTypeAliasDeclaration(this.context.factory.createModifiersFromModifierFlags(ts__default["default"].ModifierFlags.Export), this.context.factory.createIdentifier(name), generics, node);
|
package/dist/index.esm.js
CHANGED
|
@@ -95,7 +95,8 @@ class TsConverter {
|
|
|
95
95
|
}
|
|
96
96
|
convertTsTypeNode(node) {
|
|
97
97
|
if (this.context.cache.convertedNodes.has(node)) {
|
|
98
|
-
|
|
98
|
+
const cachedType = this.context.cache.convertedNodes.get(node);
|
|
99
|
+
return JSON.parse(JSON.stringify(cachedType));
|
|
99
100
|
}
|
|
100
101
|
const convertedNode = this.tsNodeToType(node);
|
|
101
102
|
this.context.cache.convertedNodes.set(node, convertedNode);
|
|
@@ -257,14 +258,47 @@ class TsConverter {
|
|
|
257
258
|
if (ts.isTypeReferenceNode(node.objectType) && ts.isLiteralTypeNode(node.indexType)) {
|
|
258
259
|
const baseObject = this.convertTsTypeNode(node.objectType);
|
|
259
260
|
const accessor = node.indexType.literal.getText().replace(/["']/g, "");
|
|
260
|
-
if (
|
|
261
|
-
|
|
261
|
+
if (!baseObject) {
|
|
262
|
+
this.context.throwError(`Error: Couldn't resolve index access on property ${accessor} on type ${node.objectType.typeName.getText()}`);
|
|
263
|
+
} else if (baseObject.type === "object") {
|
|
264
|
+
if (Object.keys((_d = baseObject.properties) != null ? _d : {}).includes(accessor)) {
|
|
265
|
+
return baseObject.properties[accessor].node;
|
|
266
|
+
}
|
|
267
|
+
if (baseObject.additionalProperties) {
|
|
268
|
+
return baseObject.additionalProperties;
|
|
269
|
+
}
|
|
270
|
+
} else if (baseObject.type === "ref") {
|
|
271
|
+
return __spreadProps(__spreadValues$1({}, baseObject), { property: accessor });
|
|
272
|
+
} else {
|
|
273
|
+
this.context.throwError(`Error: Index access on non object/ref type ${baseObject.type}`);
|
|
262
274
|
}
|
|
263
|
-
|
|
264
|
-
|
|
275
|
+
}
|
|
276
|
+
if (ts.isTypeQueryNode(node.objectType)) {
|
|
277
|
+
const effectiveType = this.context.typeChecker.getTypeAtLocation(node);
|
|
278
|
+
if (ts.TypeFlags.Union & effectiveType.flags) {
|
|
279
|
+
return {
|
|
280
|
+
type: "or",
|
|
281
|
+
or: effectiveType.types.map((type) => {
|
|
282
|
+
if (ts.TypeFlags.StringLiteral & type.flags) {
|
|
283
|
+
return {
|
|
284
|
+
type: "string",
|
|
285
|
+
const: type.value
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
if (ts.TypeFlags.NumberLiteral & type.flags) {
|
|
289
|
+
return {
|
|
290
|
+
type: "number",
|
|
291
|
+
const: type.value
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
return {
|
|
295
|
+
type: "unknown"
|
|
296
|
+
};
|
|
297
|
+
})
|
|
298
|
+
};
|
|
265
299
|
}
|
|
266
300
|
}
|
|
267
|
-
|
|
301
|
+
this.context.throwError(`Error: could not solve IndexedAccessType ${node.getFullText()}`);
|
|
268
302
|
} else {
|
|
269
303
|
this.context.throwError(`Unimplemented type ${ts.SyntaxKind[node.kind]}`);
|
|
270
304
|
}
|
|
@@ -344,6 +378,9 @@ class TsConverter {
|
|
|
344
378
|
return;
|
|
345
379
|
}
|
|
346
380
|
typeToApply = this.convertDeclaration(parentInterface);
|
|
381
|
+
if (typeToApply.extends) {
|
|
382
|
+
extendsType = typeToApply.extends;
|
|
383
|
+
}
|
|
347
384
|
if (parentInterface.typeParameters && parent.typeArguments) {
|
|
348
385
|
typeToApply = this.solveGenerics(typeToApply, parentInterface.typeParameters, parent.typeArguments);
|
|
349
386
|
} else if (isGenericNodeType(baseObject)) {
|
|
@@ -532,7 +569,8 @@ var __spreadValues = (a, b) => {
|
|
|
532
569
|
}
|
|
533
570
|
return a;
|
|
534
571
|
};
|
|
535
|
-
const
|
|
572
|
+
const templateTokenize = /(?=true\|false|\.\*|\[0-9]\*)/gm;
|
|
573
|
+
const tokenSplit = /(?<=true\|false|\.\*|\[0-9]\*)/gm;
|
|
536
574
|
class TSWriter {
|
|
537
575
|
constructor(factory) {
|
|
538
576
|
this.context = {
|
|
@@ -563,9 +601,18 @@ class TSWriter {
|
|
|
563
601
|
if (isGenericNamedType(type)) {
|
|
564
602
|
generics = this.createTypeParameters(type);
|
|
565
603
|
}
|
|
604
|
+
let customPrimitiveHeritageClass;
|
|
605
|
+
if (type.type === "object" && type.extends) {
|
|
606
|
+
const refName = type.extends.ref.split("<")[0];
|
|
607
|
+
customPrimitiveHeritageClass = [
|
|
608
|
+
this.context.factory.createHeritageClause(ts.SyntaxKind.ExtendsKeyword, [
|
|
609
|
+
this.context.factory.createExpressionWithTypeArguments(this.context.factory.createIdentifier(refName), type.extends.genericArguments ? type.extends.genericArguments.map((node) => this.convertTypeNode(node)) : void 0)
|
|
610
|
+
])
|
|
611
|
+
];
|
|
612
|
+
}
|
|
566
613
|
let finalNode;
|
|
567
614
|
if (ts.isTypeLiteralNode(tsNode)) {
|
|
568
|
-
finalNode = this.makeInterfaceDeclaration(typeName, tsNode.members, generics);
|
|
615
|
+
finalNode = this.makeInterfaceDeclaration(typeName, tsNode.members, generics, customPrimitiveHeritageClass);
|
|
569
616
|
} else {
|
|
570
617
|
finalNode = this.makeTypeDeclaration(typeName, tsNode, generics);
|
|
571
618
|
}
|
|
@@ -669,7 +716,7 @@ class TSWriter {
|
|
|
669
716
|
return xlrNode.const ? this.context.factory.createNumericLiteral(xlrNode.const) : this.context.throwError("Can't make literal type out of non constant number");
|
|
670
717
|
}
|
|
671
718
|
if (xlrNode.type === "string") {
|
|
672
|
-
return xlrNode.const ? this.context.factory.createStringLiteral(xlrNode.const) : this.context.throwError("Can't make literal type out of non constant string");
|
|
719
|
+
return xlrNode.const ? this.context.factory.createStringLiteral(xlrNode.const, true) : this.context.throwError("Can't make literal type out of non constant string");
|
|
673
720
|
}
|
|
674
721
|
if (xlrNode.type === "null") {
|
|
675
722
|
return this.context.factory.createNull();
|
|
@@ -681,7 +728,7 @@ class TSWriter {
|
|
|
681
728
|
}
|
|
682
729
|
createFunctionDeclarationNode(xlrNode) {
|
|
683
730
|
return this.context.factory.createFunctionTypeNode(void 0, xlrNode.parameters.map((e) => {
|
|
684
|
-
return this.context.factory.createParameterDeclaration(void 0, void 0,
|
|
731
|
+
return this.context.factory.createParameterDeclaration(void 0, void 0, e.name, e.optional ? this.context.factory.createToken(ts.SyntaxKind.QuestionToken) : void 0, this.convertTypeNode(e.type), e.default ? this.createLiteralTypeNode(e.default) : void 0);
|
|
685
732
|
}), xlrNode.returnType ? this.convertTypeNode(xlrNode.returnType) : this.context.factory.createToken(ts.SyntaxKind.VoidKeyword));
|
|
686
733
|
}
|
|
687
734
|
createRecordNode(xlrNode) {
|
|
@@ -702,23 +749,23 @@ class TSWriter {
|
|
|
702
749
|
...Object.keys(properties).map((name) => __spreadValues({ name }, properties[name])).map(({ name, node, required }) => this.makeAnnotations(this.context.factory.createPropertySignature(void 0, name, required ? void 0 : this.context.factory.createToken(ts.SyntaxKind.QuestionToken), this.convertTypeNode(node)), node))
|
|
703
750
|
];
|
|
704
751
|
if (additionalProperties) {
|
|
705
|
-
propertyNodes.push(this.context.factory.createIndexSignature(void 0,
|
|
706
|
-
this.context.factory.createParameterDeclaration(void 0, void 0,
|
|
752
|
+
propertyNodes.push(this.context.factory.createIndexSignature(void 0, [
|
|
753
|
+
this.context.factory.createParameterDeclaration(void 0, void 0, "key", void 0, this.context.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword))
|
|
707
754
|
], this.convertTypeNode(additionalProperties)));
|
|
708
755
|
}
|
|
709
756
|
return this.context.factory.createTypeLiteralNode(propertyNodes);
|
|
710
757
|
}
|
|
711
758
|
createTemplateLiteral(xlrNode) {
|
|
712
|
-
const templateSegments = xlrNode.format.split(
|
|
759
|
+
const templateSegments = xlrNode.format.split(templateTokenize);
|
|
713
760
|
let templateHead;
|
|
714
|
-
if (templateSegments.length % 2) {
|
|
761
|
+
if (templateSegments.length % 2 === 0) {
|
|
715
762
|
templateHead = this.context.factory.createTemplateHead(templateSegments[0]);
|
|
716
763
|
templateSegments.splice(0, 1);
|
|
717
764
|
} else {
|
|
718
765
|
templateHead = this.context.factory.createTemplateHead("");
|
|
719
766
|
}
|
|
720
767
|
return this.context.factory.createTemplateLiteralType(templateHead, templateSegments.map((segments, i) => {
|
|
721
|
-
const [regexSegment, stringSegment] = segments.split(
|
|
768
|
+
const [regexSegment, stringSegment = ""] = segments.split(tokenSplit);
|
|
722
769
|
let regexTemplateType;
|
|
723
770
|
if (regexSegment === ".*") {
|
|
724
771
|
regexTemplateType = ts.SyntaxKind.StringKeyword;
|
|
@@ -768,8 +815,8 @@ ${comment.split("\n").map((s) => ` * ${s}`).join("\n")}
|
|
|
768
815
|
return this.context.factory.createTypeParameterDeclaration(void 0, generic.symbol, this.createGenericArgumentNode(generic.constraints), this.createGenericArgumentNode(generic.default));
|
|
769
816
|
});
|
|
770
817
|
}
|
|
771
|
-
makeInterfaceDeclaration(name, node, generics) {
|
|
772
|
-
return this.context.factory.createInterfaceDeclaration(this.context.factory.createModifiersFromModifierFlags(ts.ModifierFlags.Export), this.context.factory.createIdentifier(name), generics,
|
|
818
|
+
makeInterfaceDeclaration(name, node, generics, heritageClass) {
|
|
819
|
+
return this.context.factory.createInterfaceDeclaration(this.context.factory.createModifiersFromModifierFlags(ts.ModifierFlags.Export), this.context.factory.createIdentifier(name), generics, heritageClass, node);
|
|
773
820
|
}
|
|
774
821
|
makeTypeDeclaration(name, node, generics) {
|
|
775
822
|
return this.context.factory.createTypeAliasDeclaration(this.context.factory.createModifiersFromModifierFlags(ts.ModifierFlags.Export), this.context.factory.createIdentifier(name), generics, node);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@player-tools/xlr-converters",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2--canary.17.363",
|
|
4
4
|
"private": false,
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org"
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
"typescript": "4.8.4"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@player-tools/xlr": "0.2.
|
|
13
|
-
"@player-tools/xlr-utils": "0.2.
|
|
12
|
+
"@player-tools/xlr": "0.2.2--canary.17.363",
|
|
13
|
+
"@player-tools/xlr-utils": "0.2.2--canary.17.363",
|
|
14
14
|
"@babel/runtime": "7.15.4"
|
|
15
15
|
},
|
|
16
16
|
"main": "dist/index.cjs.js",
|
package/src/ts-to-xlr.ts
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
NumberLiteralType,
|
|
3
|
+
StringLiteralType,
|
|
4
|
+
UnionType,
|
|
5
|
+
} from 'typescript';
|
|
1
6
|
import ts from 'typescript';
|
|
2
7
|
import type {
|
|
3
8
|
NodeType,
|
|
@@ -12,6 +17,7 @@ import type {
|
|
|
12
17
|
ParamTypeNode,
|
|
13
18
|
ConditionalType,
|
|
14
19
|
RefType,
|
|
20
|
+
OrType,
|
|
15
21
|
} from '@player-tools/xlr';
|
|
16
22
|
import type { TopLevelDeclaration } from '@player-tools/xlr-utils';
|
|
17
23
|
import {
|
|
@@ -160,7 +166,11 @@ export class TsConverter {
|
|
|
160
166
|
/** Converts an arbitrary ts.TypeNode to XLRs */
|
|
161
167
|
public convertTsTypeNode(node: ts.TypeNode): NodeType | undefined {
|
|
162
168
|
if (this.context.cache.convertedNodes.has(node)) {
|
|
163
|
-
|
|
169
|
+
const cachedType = this.context.cache.convertedNodes.get(
|
|
170
|
+
node
|
|
171
|
+
) as NodeType;
|
|
172
|
+
// return deep copy of node so modifications don't effect referenced to the original
|
|
173
|
+
return JSON.parse(JSON.stringify(cachedType));
|
|
164
174
|
}
|
|
165
175
|
|
|
166
176
|
const convertedNode = this.tsNodeToType(node);
|
|
@@ -391,20 +401,63 @@ export class TsConverter {
|
|
|
391
401
|
ts.isTypeReferenceNode(node.objectType) &&
|
|
392
402
|
ts.isLiteralTypeNode(node.indexType)
|
|
393
403
|
) {
|
|
394
|
-
const baseObject = this.convertTsTypeNode(
|
|
395
|
-
node.objectType
|
|
396
|
-
) as ObjectType;
|
|
404
|
+
const baseObject = this.convertTsTypeNode(node.objectType);
|
|
397
405
|
const accessor = node.indexType.literal.getText().replace(/["']/g, '');
|
|
398
|
-
if (
|
|
399
|
-
|
|
406
|
+
if (!baseObject) {
|
|
407
|
+
this.context.throwError(
|
|
408
|
+
`Error: Couldn't resolve index access on property ${accessor} on type ${node.objectType.typeName.getText()}`
|
|
409
|
+
);
|
|
410
|
+
} else if (baseObject.type === 'object') {
|
|
411
|
+
if (Object.keys(baseObject.properties ?? {}).includes(accessor)) {
|
|
412
|
+
return baseObject.properties[accessor].node;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if (baseObject.additionalProperties) {
|
|
416
|
+
return baseObject.additionalProperties;
|
|
417
|
+
}
|
|
418
|
+
} else if (baseObject.type === 'ref') {
|
|
419
|
+
return { ...baseObject, property: accessor };
|
|
420
|
+
} else {
|
|
421
|
+
this.context.throwError(
|
|
422
|
+
`Error: Index access on non object/ref type ${baseObject.type}`
|
|
423
|
+
);
|
|
400
424
|
}
|
|
425
|
+
}
|
|
401
426
|
|
|
402
|
-
|
|
403
|
-
|
|
427
|
+
if (ts.isTypeQueryNode(node.objectType)) {
|
|
428
|
+
const effectiveType = this.context.typeChecker.getTypeAtLocation(node);
|
|
429
|
+
// eslint-disable-next-line no-bitwise
|
|
430
|
+
if (ts.TypeFlags.Union & effectiveType.flags) {
|
|
431
|
+
return {
|
|
432
|
+
type: 'or',
|
|
433
|
+
or: (effectiveType as UnionType).types.map((type) => {
|
|
434
|
+
// eslint-disable-next-line no-bitwise
|
|
435
|
+
if (ts.TypeFlags.StringLiteral & type.flags) {
|
|
436
|
+
return {
|
|
437
|
+
type: 'string',
|
|
438
|
+
const: (type as StringLiteralType).value,
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// eslint-disable-next-line no-bitwise
|
|
443
|
+
if (ts.TypeFlags.NumberLiteral & type.flags) {
|
|
444
|
+
return {
|
|
445
|
+
type: 'number',
|
|
446
|
+
const: (type as NumberLiteralType).value,
|
|
447
|
+
};
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
return {
|
|
451
|
+
type: 'unknown',
|
|
452
|
+
};
|
|
453
|
+
}),
|
|
454
|
+
} as OrType;
|
|
404
455
|
}
|
|
405
456
|
}
|
|
406
457
|
|
|
407
|
-
|
|
458
|
+
this.context.throwError(
|
|
459
|
+
`Error: could not solve IndexedAccessType ${node.getFullText()}`
|
|
460
|
+
);
|
|
408
461
|
} else {
|
|
409
462
|
this.context.throwError(`Unimplemented type ${ts.SyntaxKind[node.kind]}`);
|
|
410
463
|
}
|
|
@@ -532,6 +585,11 @@ export class TsConverter {
|
|
|
532
585
|
}
|
|
533
586
|
|
|
534
587
|
typeToApply = this.convertDeclaration(parentInterface);
|
|
588
|
+
|
|
589
|
+
if (typeToApply.extends) {
|
|
590
|
+
extendsType = typeToApply.extends;
|
|
591
|
+
}
|
|
592
|
+
|
|
535
593
|
if (parentInterface.typeParameters && parent.typeArguments) {
|
|
536
594
|
typeToApply = this.solveGenerics(
|
|
537
595
|
typeToApply as NodeTypeWithGenerics,
|
package/src/xlr-to-ts.ts
CHANGED
|
@@ -20,7 +20,8 @@ import {
|
|
|
20
20
|
import ts from 'typescript';
|
|
21
21
|
import { ConversionError } from './types';
|
|
22
22
|
|
|
23
|
-
const
|
|
23
|
+
const templateTokenize = /(?=true\|false|\.\*|\[0-9]\*)/gm;
|
|
24
|
+
const tokenSplit = /(?<=true\|false|\.\*|\[0-9]\*)/gm;
|
|
24
25
|
|
|
25
26
|
export interface ConvertedType {
|
|
26
27
|
/** Converted input type represented as in TS Nodes */
|
|
@@ -85,12 +86,33 @@ export class TSWriter {
|
|
|
85
86
|
generics = this.createTypeParameters(type);
|
|
86
87
|
}
|
|
87
88
|
|
|
89
|
+
let customPrimitiveHeritageClass;
|
|
90
|
+
if (type.type === 'object' && type.extends) {
|
|
91
|
+
const refName = type.extends.ref.split('<')[0];
|
|
92
|
+
customPrimitiveHeritageClass = [
|
|
93
|
+
this.context.factory.createHeritageClause(
|
|
94
|
+
ts.SyntaxKind.ExtendsKeyword,
|
|
95
|
+
[
|
|
96
|
+
this.context.factory.createExpressionWithTypeArguments(
|
|
97
|
+
this.context.factory.createIdentifier(refName),
|
|
98
|
+
type.extends.genericArguments
|
|
99
|
+
? (type.extends.genericArguments.map((node) =>
|
|
100
|
+
this.convertTypeNode(node)
|
|
101
|
+
) as any)
|
|
102
|
+
: undefined
|
|
103
|
+
),
|
|
104
|
+
]
|
|
105
|
+
),
|
|
106
|
+
];
|
|
107
|
+
}
|
|
108
|
+
|
|
88
109
|
let finalNode;
|
|
89
110
|
if (ts.isTypeLiteralNode(tsNode)) {
|
|
90
111
|
finalNode = this.makeInterfaceDeclaration(
|
|
91
112
|
typeName,
|
|
92
113
|
tsNode.members,
|
|
93
|
-
generics
|
|
114
|
+
generics,
|
|
115
|
+
customPrimitiveHeritageClass
|
|
94
116
|
);
|
|
95
117
|
} else {
|
|
96
118
|
finalNode = this.makeTypeDeclaration(typeName, tsNode, generics);
|
|
@@ -263,7 +285,7 @@ export class TSWriter {
|
|
|
263
285
|
|
|
264
286
|
if (xlrNode.type === 'string') {
|
|
265
287
|
return xlrNode.const
|
|
266
|
-
? this.context.factory.createStringLiteral(xlrNode.const)
|
|
288
|
+
? this.context.factory.createStringLiteral(xlrNode.const, true)
|
|
267
289
|
: this.context.throwError(
|
|
268
290
|
"Can't make literal type out of non constant string"
|
|
269
291
|
);
|
|
@@ -287,7 +309,6 @@ export class TSWriter {
|
|
|
287
309
|
undefined,
|
|
288
310
|
xlrNode.parameters.map((e) => {
|
|
289
311
|
return this.context.factory.createParameterDeclaration(
|
|
290
|
-
undefined,
|
|
291
312
|
undefined,
|
|
292
313
|
undefined,
|
|
293
314
|
e.name,
|
|
@@ -351,11 +372,9 @@ export class TSWriter {
|
|
|
351
372
|
if (additionalProperties) {
|
|
352
373
|
propertyNodes.push(
|
|
353
374
|
this.context.factory.createIndexSignature(
|
|
354
|
-
undefined, // decorators
|
|
355
375
|
undefined, // modifiers
|
|
356
376
|
[
|
|
357
377
|
this.context.factory.createParameterDeclaration(
|
|
358
|
-
undefined, // decorators
|
|
359
378
|
undefined, // modifiers
|
|
360
379
|
undefined, // dotdotdot token
|
|
361
380
|
'key',
|
|
@@ -374,10 +393,10 @@ export class TSWriter {
|
|
|
374
393
|
}
|
|
375
394
|
|
|
376
395
|
private createTemplateLiteral(xlrNode: TemplateLiteralType) {
|
|
377
|
-
const templateSegments = xlrNode.format.split(
|
|
396
|
+
const templateSegments = xlrNode.format.split(templateTokenize);
|
|
378
397
|
let templateHead;
|
|
379
398
|
|
|
380
|
-
if (templateSegments.length % 2) {
|
|
399
|
+
if (templateSegments.length % 2 === 0) {
|
|
381
400
|
templateHead = this.context.factory.createTemplateHead(
|
|
382
401
|
templateSegments[0]
|
|
383
402
|
);
|
|
@@ -389,7 +408,7 @@ export class TSWriter {
|
|
|
389
408
|
return this.context.factory.createTemplateLiteralType(
|
|
390
409
|
templateHead,
|
|
391
410
|
templateSegments.map((segments, i) => {
|
|
392
|
-
const [regexSegment, stringSegment] = segments.split(
|
|
411
|
+
const [regexSegment, stringSegment = ''] = segments.split(tokenSplit);
|
|
393
412
|
|
|
394
413
|
let regexTemplateType: ts.KeywordSyntaxKind;
|
|
395
414
|
if (regexSegment === '.*') {
|
|
@@ -480,7 +499,8 @@ export class TSWriter {
|
|
|
480
499
|
private makeInterfaceDeclaration(
|
|
481
500
|
name: string,
|
|
482
501
|
node: ts.NodeArray<ts.TypeElement>,
|
|
483
|
-
generics: Array<ts.TypeParameterDeclaration> | undefined
|
|
502
|
+
generics: Array<ts.TypeParameterDeclaration> | undefined,
|
|
503
|
+
heritageClass: ts.HeritageClause[] | undefined
|
|
484
504
|
) {
|
|
485
505
|
return this.context.factory.createInterfaceDeclaration(
|
|
486
506
|
this.context.factory.createModifiersFromModifierFlags(
|
|
@@ -488,7 +508,7 @@ export class TSWriter {
|
|
|
488
508
|
),
|
|
489
509
|
this.context.factory.createIdentifier(name),
|
|
490
510
|
generics, // type parameters
|
|
491
|
-
|
|
511
|
+
heritageClass, // heritage
|
|
492
512
|
node
|
|
493
513
|
);
|
|
494
514
|
}
|