@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 CHANGED
@@ -103,7 +103,8 @@ class TsConverter {
103
103
  }
104
104
  convertTsTypeNode(node) {
105
105
  if (this.context.cache.convertedNodes.has(node)) {
106
- return this.context.cache.convertedNodes.get(node);
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 (Object.keys((_d = baseObject.properties) != null ? _d : {}).includes(accessor)) {
269
- return baseObject.properties[accessor].node;
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
- if (baseObject.additionalProperties) {
272
- return baseObject.additionalProperties;
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
- return { type: "null" };
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 templateSplit = /(?=true\|false|\.\*|\[0-9]\*)/gm;
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, 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);
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, void 0, [
714
- this.context.factory.createParameterDeclaration(void 0, void 0, void 0, "key", void 0, this.context.factory.createKeywordTypeNode(ts__default["default"].SyntaxKind.StringKeyword))
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(templateSplit);
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(" ", 1);
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, void 0, node);
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
- return this.context.cache.convertedNodes.get(node);
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 (Object.keys((_d = baseObject.properties) != null ? _d : {}).includes(accessor)) {
261
- return baseObject.properties[accessor].node;
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
- if (baseObject.additionalProperties) {
264
- return baseObject.additionalProperties;
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
- return { type: "null" };
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 templateSplit = /(?=true\|false|\.\*|\[0-9]\*)/gm;
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, 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);
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, void 0, [
706
- this.context.factory.createParameterDeclaration(void 0, void 0, void 0, "key", void 0, this.context.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword))
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(templateSplit);
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(" ", 1);
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, void 0, node);
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.1-next.4",
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.1-next.4",
13
- "@player-tools/xlr-utils": "0.2.1-next.4",
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
- return this.context.cache.convertedNodes.get(node);
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 (Object.keys(baseObject.properties ?? {}).includes(accessor)) {
399
- return baseObject.properties[accessor].node;
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
- if (baseObject.additionalProperties) {
403
- return baseObject.additionalProperties;
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
- return { type: 'null' };
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 templateSplit = /(?=true\|false|\.\*|\[0-9]\*)/gm;
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(templateSplit);
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(' ', 1);
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
- undefined, // heritage
511
+ heritageClass, // heritage
492
512
  node
493
513
  );
494
514
  }