@trapi/metadata 1.2.2 → 1.3.0

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.
Files changed (81) hide show
  1. package/dist/cache/{driver.d.ts → client.d.ts} +3 -2
  2. package/dist/cache/{driver.d.ts.map → client.d.ts.map} +1 -1
  3. package/dist/cache/{driver.js → client.js} +19 -5
  4. package/dist/cache/{driver.js.map → client.js.map} +1 -1
  5. package/dist/cache/index.d.ts +1 -1
  6. package/dist/cache/index.js +1 -1
  7. package/dist/cache/utils.js +2 -3
  8. package/dist/cache/utils.js.map +1 -1
  9. package/dist/decorator/preset/utils/check.js +1 -2
  10. package/dist/decorator/preset/utils/check.js.map +1 -1
  11. package/dist/decorator/preset/utils/load.js +1 -2
  12. package/dist/decorator/preset/utils/load.js.map +1 -1
  13. package/dist/decorator/preset/utils/normalize.js +1 -2
  14. package/dist/decorator/preset/utils/normalize.js.map +1 -1
  15. package/dist/decorator/property-manager/utils.js +3 -4
  16. package/dist/decorator/property-manager/utils.js.map +1 -1
  17. package/dist/generator/metadata/module.js +1 -1
  18. package/dist/generator/metadata/utils.js +1 -2
  19. package/dist/generator/metadata/utils.js.map +1 -1
  20. package/dist/generator/parameter/module.js +17 -7
  21. package/dist/generator/parameter/module.js.map +1 -1
  22. package/dist/module.js +1 -2
  23. package/dist/module.js.map +1 -1
  24. package/dist/resolver/constants.d.ts +1 -0
  25. package/dist/resolver/constants.d.ts.map +1 -1
  26. package/dist/resolver/constants.js +1 -0
  27. package/dist/resolver/constants.js.map +1 -1
  28. package/dist/resolver/error.js +3 -3
  29. package/dist/resolver/error.js.map +1 -1
  30. package/dist/resolver/extension/module.js +1 -2
  31. package/dist/resolver/extension/module.js.map +1 -1
  32. package/dist/resolver/module.d.ts +6 -7
  33. package/dist/resolver/module.d.ts.map +1 -1
  34. package/dist/resolver/module.js +130 -216
  35. package/dist/resolver/module.js.map +1 -1
  36. package/dist/resolver/sub/base.d.ts +7 -0
  37. package/dist/resolver/sub/base.d.ts.map +1 -0
  38. package/dist/resolver/sub/base.js +50 -0
  39. package/dist/resolver/sub/base.js.map +1 -0
  40. package/dist/resolver/sub/index.d.ts +4 -0
  41. package/dist/resolver/sub/index.d.ts.map +1 -0
  42. package/dist/resolver/sub/index.js +26 -0
  43. package/dist/resolver/sub/index.js.map +1 -0
  44. package/dist/resolver/sub/primitive.d.ts +11 -0
  45. package/dist/resolver/sub/primitive.d.ts.map +1 -0
  46. package/dist/resolver/sub/primitive.js +124 -0
  47. package/dist/resolver/sub/primitive.js.map +1 -0
  48. package/dist/resolver/sub/reference.d.ts +15 -0
  49. package/dist/resolver/sub/reference.d.ts.map +1 -0
  50. package/dist/resolver/sub/reference.js +141 -0
  51. package/dist/resolver/sub/reference.js.map +1 -0
  52. package/dist/resolver/type.d.ts +5 -1
  53. package/dist/resolver/type.d.ts.map +1 -1
  54. package/dist/resolver/type.js +33 -28
  55. package/dist/resolver/type.js.map +1 -1
  56. package/dist/resolver/utils.d.ts +4 -0
  57. package/dist/resolver/utils.d.ts.map +1 -0
  58. package/dist/resolver/utils.js +37 -0
  59. package/dist/resolver/utils.js.map +1 -0
  60. package/dist/utils/array.js +1 -2
  61. package/dist/utils/array.js.map +1 -1
  62. package/dist/utils/initializer.d.ts.map +1 -1
  63. package/dist/utils/initializer.js +19 -9
  64. package/dist/utils/initializer.js.map +1 -1
  65. package/dist/utils/js-doc/module.js +6 -7
  66. package/dist/utils/js-doc/module.js.map +1 -1
  67. package/dist/utils/js-doc/utils.js +1 -2
  68. package/dist/utils/js-doc/utils.js.map +1 -1
  69. package/dist/utils/node/module.js +1 -2
  70. package/dist/utils/node/module.js.map +1 -1
  71. package/dist/utils/object.js +1 -2
  72. package/dist/utils/object.js.map +1 -1
  73. package/dist/utils/path-normalize.js +1 -2
  74. package/dist/utils/path-normalize.js.map +1 -1
  75. package/dist/utils/source-files.js +1 -2
  76. package/dist/utils/source-files.js.map +1 -1
  77. package/dist/utils/tsconfig/module.js +2 -3
  78. package/dist/utils/tsconfig/module.js.map +1 -1
  79. package/dist/utils/validator/module.js +1 -2
  80. package/dist/utils/validator/module.js.map +1 -1
  81. package/package.json +4 -4
@@ -21,46 +21,47 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
21
21
  }) : function(o, v) {
22
22
  o["default"] = v;
23
23
  });
24
- var __importStar = (this && this.__importStar) || function (mod) {
25
- if (mod && mod.__esModule) return mod;
26
- var result = {};
27
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
28
- __setModuleDefault(result, mod);
29
- return result;
30
- };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
31
41
  Object.defineProperty(exports, "__esModule", { value: true });
32
42
  exports.TypeNodeResolver = void 0;
43
+ const typescript_1 = require("typescript");
33
44
  const ts = __importStar(require("typescript"));
34
45
  const decorator_1 = require("../decorator");
35
46
  const constants_1 = require("./constants");
36
47
  const utils_1 = require("../utils");
37
48
  const error_1 = require("./error");
38
49
  const extension_1 = require("./extension");
50
+ const sub_1 = require("./sub");
39
51
  const type_1 = require("./type");
52
+ const utils_2 = require("./utils");
40
53
  const localReferenceTypeCache = {};
41
54
  const inProgressTypes = {};
42
- class TypeNodeResolver {
55
+ class TypeNodeResolver extends sub_1.ResolverBase {
43
56
  constructor(typeNode, current, parentNode, context, referencer) {
44
- this.attemptToResolveKindToPrimitive = (syntaxKind) => {
45
- if (syntaxKind === ts.SyntaxKind.NumberKeyword) {
46
- return 'number';
47
- }
48
- if (syntaxKind === ts.SyntaxKind.StringKeyword) {
49
- return 'string';
50
- }
51
- if (syntaxKind === ts.SyntaxKind.BooleanKeyword) {
52
- return 'boolean';
53
- }
54
- if (syntaxKind === ts.SyntaxKind.VoidKeyword) {
55
- return 'void';
56
- }
57
- return undefined;
58
- };
57
+ super();
59
58
  this.typeNode = typeNode;
60
59
  this.current = current;
61
60
  this.parentNode = parentNode;
62
61
  this.context = context || {};
63
62
  this.referencer = referencer;
63
+ this.primitiveResolver = new sub_1.PrimitiveResolver(current.decoratorResolver);
64
+ this.referenceResolver = new sub_1.ReferenceResolver(current.typeChecker);
64
65
  }
65
66
  static clearCache() {
66
67
  Object.keys(localReferenceTypeCache).forEach((key) => {
@@ -71,7 +72,7 @@ class TypeNodeResolver {
71
72
  });
72
73
  }
73
74
  resolve() {
74
- const primitiveType = this.getPrimitiveType(this.typeNode, this.parentNode);
75
+ const primitiveType = this.primitiveResolver.resolve(this.typeNode, this.parentNode);
75
76
  if (primitiveType) {
76
77
  return primitiveType;
77
78
  }
@@ -81,11 +82,6 @@ class TypeNodeResolver {
81
82
  members: [null],
82
83
  };
83
84
  }
84
- if (this.typeNode.kind === ts.SyntaxKind.UndefinedKeyword) {
85
- return {
86
- typeName: constants_1.TypeName.UNDEFINED,
87
- };
88
- }
89
85
  if (ts.isArrayTypeNode(this.typeNode)) {
90
86
  return {
91
87
  typeName: constants_1.TypeName.ARRAY,
@@ -177,7 +173,7 @@ class TypeNodeResolver {
177
173
  const properties = type
178
174
  .getProperties()
179
175
  // Ignore methods, getter, setter and @ignored props
180
- .filter((property) => isIgnored(property) === false)
176
+ .filter((property) => !isIgnored(property))
181
177
  // Transform to property
182
178
  .map((property) => {
183
179
  const propertyType = typeChecker.getTypeOfSymbolAtLocation(property, this.typeNode);
@@ -190,7 +186,7 @@ class TypeNodeResolver {
190
186
  }
191
187
  // Resolve default value, required and typeNode
192
188
  let required = false;
193
- const typeNode = this.current.typeChecker.typeToTypeNode(propertyType, undefined, ts.NodeBuilderFlags.NoTruncation);
189
+ const typeNode = (0, utils_2.toTypeNodeOrFail)(this.current.typeChecker, propertyType, undefined, ts.NodeBuilderFlags.NoTruncation);
194
190
  if (mappedTypeNode.questionToken && mappedTypeNode.questionToken.kind === ts.SyntaxKind.MinusToken) {
195
191
  required = true;
196
192
  }
@@ -216,32 +212,38 @@ class TypeNodeResolver {
216
212
  ts.isTypeReferenceNode(this.referencer)) {
217
213
  const type = this.current.typeChecker.getTypeFromTypeNode(this.referencer);
218
214
  if (type.aliasSymbol) {
219
- let declaration = type.aliasSymbol.declarations[0];
220
- if (declaration.name) {
215
+ let [declaration] = type.aliasSymbol.declarations;
216
+ if (declaration && declaration.name) {
221
217
  declaration = this.getModelTypeDeclaration(declaration.name);
222
218
  }
223
219
  const name = TypeNodeResolver.getRefTypeName(this.referencer.getText());
224
220
  return this.handleCachingAndCircularReferences(name, () => {
225
- if (ts.isTypeAliasDeclaration(declaration)) {
226
- // Note: I don't understand why typescript lose type for `this.referencer` (from above with isTypeReferenceNode())
227
- return this.getTypeAliasReference(declaration, this.current.typeChecker.typeToString(type), this.referencer);
228
- }
229
- if (ts.isEnumDeclaration(declaration)) {
230
- return this.getEnumerateType(declaration.name);
221
+ if (declaration) {
222
+ if (ts.isTypeAliasDeclaration(declaration)) {
223
+ // Note: I don't understand why typescript lose type for `this.referencer`
224
+ // (from above with isTypeReferenceNode())
225
+ return this.getTypeAliasReference(declaration, this.current.typeChecker.typeToString(type), this.referencer);
226
+ }
227
+ if (ts.isEnumDeclaration(declaration)) {
228
+ return this.getEnumerateType(declaration.name);
229
+ }
231
230
  }
232
231
  throw new error_1.ResolverError(`Couldn't resolve Conditional to TypeNode. If you think this should be resolvable, please file an Issue. We found an aliasSymbol and it's declaration was of kind ${declaration.kind}`, this.typeNode);
233
232
  });
234
233
  }
235
234
  if (type.isClassOrInterface()) {
236
- let declaration = type.symbol.declarations[0];
237
- if (declaration.name) {
235
+ let [declaration] = type.symbol.declarations;
236
+ if (declaration && declaration.name) {
238
237
  declaration = this.getModelTypeDeclaration(declaration.name);
239
238
  }
239
+ if (!declaration) {
240
+ throw new error_1.ResolverError('Couldn\'t get declaration for type symbol', this.typeNode);
241
+ }
240
242
  const name = TypeNodeResolver.getRefTypeName(this.referencer.getText());
241
243
  return this.handleCachingAndCircularReferences(name, () => this.getModelReference(declaration, this.current.typeChecker.typeToString(type)));
242
244
  }
243
245
  try {
244
- return new TypeNodeResolver(this.current.typeChecker.typeToTypeNode(type, undefined, ts.NodeBuilderFlags.NoTruncation), this.current, this.typeNode, this.context, this.referencer).resolve();
246
+ return new TypeNodeResolver((0, utils_2.toTypeNodeOrFail)(this.current.typeChecker, type, undefined, ts.NodeBuilderFlags.NoTruncation), this.current, this.typeNode, this.context, this.referencer).resolve();
245
247
  }
246
248
  catch {
247
249
  throw new error_1.ResolverError(`Couldn't resolve Conditional to TypeNode. If you think this should be resolvable, please file an Issue. The flags on the result of the ConditionalType was ${type.flags}`, this.typeNode);
@@ -251,7 +253,7 @@ class TypeNodeResolver {
251
253
  if (this.typeNode.operator === ts.SyntaxKind.KeyOfKeyword) {
252
254
  const type = this.current.typeChecker.getTypeFromTypeNode(this.typeNode);
253
255
  try {
254
- return new TypeNodeResolver(this.current.typeChecker.typeToTypeNode(type, undefined, ts.NodeBuilderFlags.NoTruncation), this.current, this.typeNode, this.context, this.referencer).resolve();
256
+ return new TypeNodeResolver((0, utils_2.toTypeNodeOrFail)(this.current.typeChecker, type, undefined, ts.NodeBuilderFlags.NoTruncation), this.current, this.typeNode, this.context, this.referencer).resolve();
255
257
  }
256
258
  catch (err) {
257
259
  const indexedTypeName = this.current.typeChecker.typeToString(this.current.typeChecker.getTypeFromTypeNode(this.typeNode.type));
@@ -271,11 +273,12 @@ class TypeNodeResolver {
271
273
  if (type === undefined) {
272
274
  throw new error_1.ResolverError(`Could not determine ${numberIndexType ? 'number' : 'string'} index on ${this.current.typeChecker.typeToString(objectType)}`, this.typeNode);
273
275
  }
274
- return new TypeNodeResolver(this.current.typeChecker.typeToTypeNode(type, undefined, undefined), this.current, this.typeNode, this.context, this.referencer).resolve();
276
+ return new TypeNodeResolver((0, utils_2.toTypeNodeOrFail)(this.current.typeChecker, type, undefined, undefined), this.current, this.typeNode, this.context, this.referencer).resolve();
275
277
  }
276
278
  if (ts.isIndexedAccessTypeNode(this.typeNode) &&
277
279
  ts.isLiteralTypeNode(this.typeNode.indexType) &&
278
- (ts.isStringLiteral(this.typeNode.indexType.literal) || ts.isNumericLiteral(this.typeNode.indexType.literal))) {
280
+ (ts.isStringLiteral(this.typeNode.indexType.literal) ||
281
+ ts.isNumericLiteral(this.typeNode.indexType.literal))) {
279
282
  const hasType = (node) => node !== undefined &&
280
283
  Object.prototype.hasOwnProperty.call(node, 'type');
281
284
  const symbol = this.current.typeChecker.getPropertyOfType(this.current.typeChecker.getTypeFromTypeNode(this.typeNode.objectType), this.typeNode.indexType.literal.text);
@@ -287,10 +290,10 @@ class TypeNodeResolver {
287
290
  }
288
291
  const declaration = this.current.typeChecker.getTypeOfSymbolAtLocation(symbol, this.typeNode.objectType);
289
292
  try {
290
- return new TypeNodeResolver(this.current.typeChecker.typeToTypeNode(declaration, undefined, undefined), this.current, this.typeNode, this.context, this.referencer).resolve();
293
+ return new TypeNodeResolver((0, utils_2.toTypeNodeOrFail)(this.current.typeChecker, declaration, undefined, undefined), this.current, this.typeNode, this.context, this.referencer).resolve();
291
294
  }
292
295
  catch {
293
- throw new error_1.ResolverError(`Could not determine the keys on ${this.current.typeChecker.typeToString(this.current.typeChecker.getTypeFromTypeNode(this.current.typeChecker.typeToTypeNode(declaration, undefined, undefined)))}`, this.typeNode);
296
+ throw new error_1.ResolverError(`Could not determine the keys on ${this.current.typeChecker.typeToString(this.current.typeChecker.getTypeFromTypeNode((0, utils_2.toTypeNodeOrFail)(this.current.typeChecker, declaration, undefined, undefined)))}`, this.typeNode);
294
297
  }
295
298
  }
296
299
  if (this.typeNode.kind === ts.SyntaxKind.TemplateLiteralType) {
@@ -312,7 +315,8 @@ class TypeNodeResolver {
312
315
  const typeReference = this.typeNode;
313
316
  if (typeReference.typeName.kind === ts.SyntaxKind.Identifier) {
314
317
  // Special Utility Type
315
- if (typeReference.typeName.text === 'Record') {
318
+ if (typeReference.typeName.text === 'Record' &&
319
+ typeReference.typeArguments) {
316
320
  return {
317
321
  additionalProperties: new TypeNodeResolver(typeReference.typeArguments[1], this.current, this.parentNode, this.context).resolve(),
318
322
  typeName: constants_1.TypeName.NESTED_OBJECT_LITERAL,
@@ -455,85 +459,6 @@ class TypeNodeResolver {
455
459
  }
456
460
  return value;
457
461
  }
458
- getPrimitiveType(typeNode, parentNode) {
459
- if (!typeNode) {
460
- return {
461
- typeName: constants_1.TypeName.VOID,
462
- };
463
- }
464
- const resolvedType = this.attemptToResolveKindToPrimitive(typeNode.kind);
465
- if (typeof resolvedType === 'undefined') {
466
- return undefined;
467
- }
468
- if (resolvedType === 'number') {
469
- if (!parentNode) {
470
- return { typeName: constants_1.TypeName.DOUBLE };
471
- }
472
- const lookupTags = [
473
- 'isInt',
474
- 'isLong',
475
- 'isFloat',
476
- 'isDouble',
477
- ];
478
- const tags = (0, utils_1.getJSDocTagNames)(parentNode)
479
- .filter((name) => lookupTags.some((m) => m.toLowerCase() === name.toLowerCase()))
480
- .map((name) => name.toLowerCase());
481
- const decoratorIds = [
482
- decorator_1.DecoratorID.IS_INT,
483
- decorator_1.DecoratorID.IS_LONG,
484
- decorator_1.DecoratorID.IS_FLOAT,
485
- decorator_1.DecoratorID.IS_DOUBLE,
486
- ];
487
- let decoratorID;
488
- for (let i = 0; i < decoratorIds.length; i++) {
489
- const decorator = this.current.decoratorResolver.match(decoratorIds[i], parentNode);
490
- if (decorator) {
491
- decoratorID = decoratorIds[i];
492
- break;
493
- }
494
- }
495
- if (!decoratorID && tags.length === 0) {
496
- return { typeName: constants_1.TypeName.DOUBLE };
497
- }
498
- switch (decoratorID || tags[0]) {
499
- case decorator_1.DecoratorID.IS_INT:
500
- case 'isint':
501
- return { typeName: constants_1.TypeName.INTEGER };
502
- case decorator_1.DecoratorID.IS_LONG:
503
- case 'islong':
504
- return { typeName: constants_1.TypeName.LONG };
505
- case decorator_1.DecoratorID.IS_FLOAT:
506
- case 'isfloat':
507
- return { typeName: constants_1.TypeName.FLOAT };
508
- case decorator_1.DecoratorID.IS_DOUBLE:
509
- case 'isdouble':
510
- return { typeName: constants_1.TypeName.DOUBLE };
511
- default:
512
- return { typeName: constants_1.TypeName.DOUBLE };
513
- }
514
- }
515
- else if (resolvedType === 'string') {
516
- return {
517
- typeName: constants_1.TypeName.STRING,
518
- };
519
- }
520
- else if (resolvedType === 'boolean') {
521
- return {
522
- typeName: constants_1.TypeName.BOOLEAN,
523
- };
524
- }
525
- else if (resolvedType === 'void') {
526
- return {
527
- typeName: constants_1.TypeName.VOID,
528
- };
529
- }
530
- else {
531
- // todo: should not occur
532
- return {
533
- typeName: resolvedType,
534
- };
535
- }
536
- }
537
462
  getDateType(parentNode) {
538
463
  if (!parentNode) {
539
464
  return { typeName: constants_1.TypeName.DATETIME };
@@ -595,7 +520,7 @@ class TypeNodeResolver {
595
520
  if (ts.isLiteralTypeNode(arg)) {
596
521
  return `'${String(TypeNodeResolver.getLiteralValue(arg))}'`;
597
522
  }
598
- const resolvedType = this.attemptToResolveKindToPrimitive(arg.kind);
523
+ const resolvedType = this.primitiveResolver.resolveSyntaxKind(arg.kind);
599
524
  if (typeof resolvedType === 'undefined') {
600
525
  return 'any';
601
526
  }
@@ -610,16 +535,21 @@ class TypeNodeResolver {
610
535
  let utilityTypeOptions;
611
536
  if (utilityType) {
612
537
  const { typeArguments } = type.parent;
613
- if (ts.isTypeReferenceNode(typeArguments[0])) {
614
- type = typeArguments[0].typeName;
615
- }
616
- else if (ts.isExpressionWithTypeArguments(typeArguments[0])) {
617
- type = typeArguments[0].expression;
538
+ if (typeArguments) {
539
+ if (ts.isTypeReferenceNode(typeArguments[0])) {
540
+ type = typeArguments[0].typeName;
541
+ }
542
+ else if (ts.isExpressionWithTypeArguments(typeArguments[0])) {
543
+ type = typeArguments[0].expression;
544
+ }
545
+ else {
546
+ throw new error_1.ResolverError('Can\'t resolve Reference type.');
547
+ }
548
+ utilityTypeOptions = TypeNodeResolver.getUtilityTypeOptions(typeArguments);
618
549
  }
619
550
  else {
620
- throw new error_1.ResolverError('Can\'t resolve Reference type.');
551
+ throw new error_1.ResolverError('Can\'t resolve type arguments of utility type.');
621
552
  }
622
- utilityTypeOptions = TypeNodeResolver.getUtilityTypeOptions(typeArguments);
623
553
  }
624
554
  else {
625
555
  this.typeArgumentsToContext(node, type, this.context);
@@ -629,35 +559,30 @@ class TypeNodeResolver {
629
559
  if (existingType) {
630
560
  return existingType;
631
561
  }
632
- const refEnumType = this.getEnumerateType(type);
633
- if (refEnumType) {
634
- localReferenceTypeCache[name] = refEnumType;
635
- return refEnumType;
636
- }
637
562
  if (inProgressTypes[name]) {
638
563
  return this.createCircularDependencyResolver(name);
639
564
  }
640
565
  inProgressTypes[name] = true;
641
- const declaration = this.getModelTypeDeclaration(type);
642
- let referenceType;
643
- if (ts.isTypeAliasDeclaration(declaration)) {
644
- referenceType = this.getTypeAliasReference(declaration, name, node, utilityType, utilityTypeOptions);
645
- localReferenceTypeCache[name] = referenceType;
646
- return referenceType;
647
- }
648
- if (ts.isEnumMember(declaration)) {
649
- referenceType = {
650
- typeName: constants_1.TypeName.REF_ENUM,
651
- refName: TypeNodeResolver.getRefTypeName(name, utilityType),
652
- members: [this.current.typeChecker.getConstantValue(declaration)],
653
- memberNames: [declaration.name.getText()],
654
- deprecated: (0, utils_1.hasJSDocTag)(declaration, utils_1.JSDocTagName.DEPRECATED),
655
- };
656
- localReferenceTypeCache[name] = referenceType;
657
- return referenceType;
566
+ const refName = TypeNodeResolver.getRefTypeName(name, utilityType);
567
+ const declarations = this.getModelTypeDeclarations(type);
568
+ const referenceTypes = [];
569
+ for (let i = 0; i < declarations.length; i++) {
570
+ const declaration = declarations[i];
571
+ if (ts.isTypeAliasDeclaration(declaration)) {
572
+ referenceTypes.push(this.getTypeAliasReference(declaration, name, node, utilityType, utilityTypeOptions));
573
+ }
574
+ else if ((0, typescript_1.isEnumDeclaration)(declaration)) {
575
+ referenceTypes.push(this.referenceResolver.transformEnum(declaration, refName));
576
+ }
577
+ else if ((0, typescript_1.isEnumMember)(declaration)) {
578
+ referenceTypes.push(this.referenceResolver.transformEnumMember(declaration, refName));
579
+ }
580
+ else {
581
+ // todo: dont cast handle property-signature
582
+ referenceTypes.push(this.getModelReference(declaration, name, utilityType, utilityTypeOptions));
583
+ }
658
584
  }
659
- // todo: dont cast handle property-signature
660
- referenceType = this.getModelReference(declaration, name, utilityType, utilityTypeOptions);
585
+ const referenceType = this.referenceResolver.merge(referenceTypes);
661
586
  localReferenceTypeCache[name] = referenceType;
662
587
  return referenceType;
663
588
  }
@@ -710,8 +635,13 @@ class TypeNodeResolver {
710
635
  let nodeType = toJSON.valueDeclaration.type;
711
636
  if (!nodeType) {
712
637
  const signature = this.current.typeChecker.getSignatureFromDeclaration(toJSON.valueDeclaration);
713
- const implicitType = this.current.typeChecker.getReturnTypeOfSignature(signature);
714
- nodeType = this.current.typeChecker.typeToTypeNode(implicitType, undefined, ts.NodeBuilderFlags.NoTruncation);
638
+ if (signature) {
639
+ const implicitType = this.current.typeChecker.getReturnTypeOfSignature(signature);
640
+ nodeType = this.current.typeChecker.typeToTypeNode(implicitType, undefined, ts.NodeBuilderFlags.NoTruncation);
641
+ }
642
+ else {
643
+ throw new error_1.ResolverError('Can\'t get signature from toJson value declaration', modelType);
644
+ }
715
645
  }
716
646
  return {
717
647
  refName: `${TypeNodeResolver.getRefTypeName(name, utilityType)}Alias`,
@@ -816,11 +746,46 @@ class TypeNodeResolver {
816
746
  return false;
817
747
  }
818
748
  }
749
+ getModelTypeDeclarations(type) {
750
+ let typeName = type.kind === ts.SyntaxKind.Identifier ? type.text : type.right.text;
751
+ let symbol = this.getSymbolAtLocation(type);
752
+ if (!symbol && type.kind === ts.SyntaxKind.QualifiedName) {
753
+ const fullEnumSymbol = this.getSymbolAtLocation(type.left);
754
+ symbol = fullEnumSymbol.exports?.get(typeName);
755
+ }
756
+ if (!symbol) {
757
+ throw new error_1.ResolverError(`No symbol found for referenced type ${typeName}.`);
758
+ }
759
+ const declarations = symbol.getDeclarations();
760
+ if (!declarations || declarations.length === 0) {
761
+ throw new error_1.ResolverError(`No declarations found for referenced type ${typeName}.`);
762
+ }
763
+ if (symbol.escapedName !== typeName && symbol.escapedName !== 'default') {
764
+ typeName = symbol.escapedName;
765
+ }
766
+ let modelTypes = declarations.filter((node) => {
767
+ if (!TypeNodeResolver.nodeIsUsable(node) || !this.current.isExportedNode(node)) {
768
+ return false;
769
+ }
770
+ const modelTypeDeclaration = node;
771
+ return modelTypeDeclaration.name?.text === typeName;
772
+ });
773
+ if (!modelTypes.length) {
774
+ throw new error_1.ResolverError(`No matching model found for referenced type ${typeName}. If ${typeName} comes from a dependency, please create an interface in your own code that has the same structure. The compiler can not utilize interfaces from external dependencies.`);
775
+ }
776
+ if (modelTypes.length > 1) {
777
+ // remove types that are from typescript e.g. 'Account'
778
+ modelTypes = modelTypes.filter((modelType) => modelType.getSourceFile()
779
+ .fileName.replace(/\\/g, '/').toLowerCase().indexOf('node_modules/typescript') <= -1);
780
+ modelTypes = TypeNodeResolver.getDesignatedModels(modelTypes, typeName);
781
+ }
782
+ return modelTypes;
783
+ }
819
784
  getModelTypeDeclaration(type) {
820
785
  let typeName = type.kind === ts.SyntaxKind.Identifier ? type.text : type.right.text;
821
786
  const symbol = this.getSymbolAtLocation(type);
822
787
  const declarations = symbol.getDeclarations();
823
- if (declarations.length === 0) {
788
+ if (!declarations || declarations.length === 0) {
824
789
  throw new error_1.ResolverError(`No models found for referenced type ${typeName}.`);
825
790
  }
826
791
  if (symbol.escapedName !== typeName && symbol.escapedName !== 'default') {
@@ -862,7 +827,8 @@ class TypeNodeResolver {
862
827
  const isIgnored = (e) => (0, utils_1.hasJSDocTag)(e, utils_1.JSDocTagName.IGNORE);
863
828
  // Interface model
864
829
  if (ts.isInterfaceDeclaration(node)) {
865
- return node.members.filter((member) => !isIgnored(member) &&
830
+ return node.members
831
+ .filter((member) => !isIgnored(member) &&
866
832
  ts.isPropertySignature(member)).map((member) => this.propertyFromSignature(member, overrideToken));
867
833
  }
868
834
  // Class model
@@ -1031,60 +997,8 @@ class TypeNodeResolver {
1031
997
  });
1032
998
  return properties;
1033
999
  }
1034
- hasPublicModifier(node) {
1035
- if (!ts.canHaveModifiers(node)) {
1036
- return true;
1037
- }
1038
- const modifiers = ts.getModifiers(node);
1039
- if (!modifiers) {
1040
- return true;
1041
- }
1042
- return modifiers.every((modifier) => modifier.kind !== ts.SyntaxKind.ProtectedKeyword && modifier.kind !== ts.SyntaxKind.PrivateKeyword);
1043
- }
1044
- hasStaticModifier(node) {
1045
- if (!ts.canHaveModifiers(node)) {
1046
- return false;
1047
- }
1048
- const modifiers = ts.getModifiers(node);
1049
- return modifiers && modifiers.some((modifier) => modifier.kind === ts.SyntaxKind.StaticKeyword);
1050
- }
1051
- isAccessibleParameter(node) {
1052
- // No modifiers
1053
- if (!ts.canHaveModifiers(node)) {
1054
- return false;
1055
- }
1056
- const modifiers = ts.getModifiers(node);
1057
- if (!modifiers) {
1058
- return false;
1059
- }
1060
- // public || public readonly
1061
- if (modifiers.some((modifier) => modifier.kind === ts.SyntaxKind.PublicKeyword)) {
1062
- return true;
1063
- }
1064
- // readonly, not private readonly, not public readonly
1065
- const isReadonly = modifiers.some((modifier) => modifier.kind === ts.SyntaxKind.ReadonlyKeyword);
1066
- const isProtectedOrPrivate = modifiers.some((modifier) => modifier.kind === ts.SyntaxKind.ProtectedKeyword ||
1067
- modifier.kind === ts.SyntaxKind.PrivateKeyword);
1068
- return isReadonly && !isProtectedOrPrivate;
1069
- }
1070
1000
  getNodeDescription(node) {
1071
- const symbol = this.current.typeChecker.getSymbolAtLocation(node.name);
1072
- if (!symbol) {
1073
- return undefined;
1074
- }
1075
- /**
1076
- * TODO: Workaround for what seems like a bug in the compiler
1077
- * Warrants more investigation and possibly a PR against typescript
1078
- */
1079
- if (node.kind === ts.SyntaxKind.Parameter) {
1080
- // TypeScript won't parse jsdoc if the flag is 4, i.e. 'Property'
1081
- symbol.flags = 0;
1082
- }
1083
- const comments = symbol.getDocumentationComment(this.current.typeChecker);
1084
- if (comments.length) {
1085
- return ts.displayPartsToString(comments);
1086
- }
1087
- return undefined;
1001
+ return (0, utils_2.getNodeDescription)(node, this.current.typeChecker);
1088
1002
  }
1089
1003
  static getNodeFormat(node) {
1090
1004
  return (0, utils_1.getJSDocTagComment)(node, utils_1.JSDocTagName.FORMAT);