ts-class-to-openapi 1.0.3 → 1.0.5

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/run.js CHANGED
@@ -38,6 +38,7 @@ const validatorDecorators = {
38
38
  ArrayNotEmpty: { name: 'ArrayNotEmpty' },
39
39
  ArrayMaxSize: { name: 'ArrayMaxSize' },
40
40
  ArrayMinSize: { name: 'ArrayMinSize' },
41
+ IsEnum: { name: 'IsEnum', type: 'string' },
41
42
  };
42
43
  const constants = {
43
44
  TS_CONFIG_DEFAULT_PATH,
@@ -96,6 +97,12 @@ class SchemaTransformer {
96
97
  * @private
97
98
  */
98
99
  loadedFiles = new Set();
100
+ /**
101
+ * Set of class names currently being processed to prevent circular references
102
+ * Key format: "fileName:className" for uniqueness across different files
103
+ * @private
104
+ */
105
+ processingClasses = new Set();
99
106
  /**
100
107
  * Private constructor for singleton pattern.
101
108
  *
@@ -148,20 +155,19 @@ class SchemaTransformer {
148
155
  }
149
156
  }
150
157
  /**
151
- * Gets relevant source files for a class, filtering out unnecessary files to save memory.
158
+ * Transforms a class by its name into an OpenAPI schema object.
159
+ * Considers the context of the calling file to resolve ambiguous class names.
160
+ * Includes circular reference detection to prevent infinite recursion.
152
161
  *
153
- * @param className - The name of the class to find files for
154
- * @param filePath - Optional specific file path
155
- * @returns Array of relevant source files
162
+ * @param className - The name of the class to transform
163
+ * @param contextFilePath - Optional path to context file for resolving class ambiguity
164
+ * @returns Object containing the class name and its corresponding JSON schema
165
+ * @throws {Error} When the specified class cannot be found
156
166
  * @private
157
167
  */
158
- getRelevantSourceFiles(className, filePath) {
159
- if (filePath) {
160
- const sourceFile = this.program.getSourceFile(filePath);
161
- return sourceFile ? [sourceFile] : [];
162
- }
163
- // Only get source files that are not declaration files and not in node_modules
164
- return this.program.getSourceFiles().filter(sf => {
168
+ transformByName(className, contextFilePath) {
169
+ // Get all relevant source files (not declaration files and not in node_modules)
170
+ const sourceFiles = this.program.getSourceFiles().filter(sf => {
165
171
  if (sf.isDeclarationFile)
166
172
  return false;
167
173
  if (sf.fileName.includes('.d.ts'))
@@ -172,19 +178,46 @@ class SchemaTransformer {
172
178
  this.loadedFiles.add(sf.fileName);
173
179
  return true;
174
180
  });
175
- }
176
- /**
177
- * Transforms a class by its name into an OpenAPI schema object.
178
- *
179
- * @param className - The name of the class to transform
180
- * @param filePath - Optional path to the file containing the class
181
- * @returns Object containing the class name and its corresponding JSON schema
182
- * @throws {Error} When the specified class cannot be found
183
- * @private
184
- */
185
- transformByName(className, filePath) {
186
- const sourceFiles = this.getRelevantSourceFiles(className, filePath);
187
- for (const sourceFile of sourceFiles) {
181
+ // If we have a context file, try to find the class in that file first
182
+ if (contextFilePath) {
183
+ const contextSourceFile = this.program.getSourceFile(contextFilePath);
184
+ if (contextSourceFile) {
185
+ const classNode = this.findClassByName(contextSourceFile, className);
186
+ if (classNode) {
187
+ const cacheKey = this.getCacheKey(contextSourceFile.fileName, className);
188
+ // Check cache first
189
+ if (this.classCache.has(cacheKey)) {
190
+ return this.classCache.get(cacheKey);
191
+ }
192
+ // Check for circular reference before processing
193
+ if (this.processingClasses.has(cacheKey)) {
194
+ // Return a $ref reference to break circular dependency (OpenAPI 3.1 style)
195
+ return {
196
+ name: className,
197
+ schema: {
198
+ $ref: `#/components/schemas/${className}`,
199
+ description: `Reference to ${className} (circular reference detected)`,
200
+ },
201
+ };
202
+ }
203
+ // Mark this class as being processed
204
+ this.processingClasses.add(cacheKey);
205
+ try {
206
+ const result = this.transformClass(classNode, contextSourceFile);
207
+ this.classCache.set(cacheKey, result);
208
+ this.cleanupCache();
209
+ return result;
210
+ }
211
+ finally {
212
+ // Always remove from processing set when done
213
+ this.processingClasses.delete(cacheKey);
214
+ }
215
+ }
216
+ }
217
+ }
218
+ // Fallback to searching all files, but prioritize files that are more likely to be relevant
219
+ const prioritizedFiles = this.prioritizeSourceFiles(sourceFiles, contextFilePath);
220
+ for (const sourceFile of prioritizedFiles) {
188
221
  const classNode = this.findClassByName(sourceFile, className);
189
222
  if (classNode && sourceFile?.fileName) {
190
223
  const cacheKey = this.getCacheKey(sourceFile.fileName, className);
@@ -192,16 +225,67 @@ class SchemaTransformer {
192
225
  if (this.classCache.has(cacheKey)) {
193
226
  return this.classCache.get(cacheKey);
194
227
  }
195
- const result = this.transformClass(classNode);
196
- // Cache using fileName:className as key for uniqueness
197
- this.classCache.set(cacheKey, result);
198
- // Clean up cache if it gets too large
199
- this.cleanupCache();
200
- return result;
228
+ // Check for circular reference before processing
229
+ if (this.processingClasses.has(cacheKey)) {
230
+ // Return a $ref reference to break circular dependency (OpenAPI 3.1 style)
231
+ return {
232
+ name: className,
233
+ schema: {
234
+ $ref: `#/components/schemas/${className}`,
235
+ description: `Reference to ${className} (circular reference detected)`,
236
+ },
237
+ };
238
+ }
239
+ // Mark this class as being processed
240
+ this.processingClasses.add(cacheKey);
241
+ try {
242
+ const result = this.transformClass(classNode, sourceFile);
243
+ // Cache using fileName:className as key for uniqueness
244
+ this.classCache.set(cacheKey, result);
245
+ // Clean up cache if it gets too large
246
+ this.cleanupCache();
247
+ return result;
248
+ }
249
+ finally {
250
+ // Always remove from processing set when done
251
+ this.processingClasses.delete(cacheKey);
252
+ }
201
253
  }
202
254
  }
203
255
  throw new Error(`Class ${className} not found`);
204
256
  }
257
+ /**
258
+ * Prioritizes source files based on context to resolve class name conflicts.
259
+ * Gives priority to files in the same directory or with similar names.
260
+ *
261
+ * @param sourceFiles - Array of source files to prioritize
262
+ * @param contextFilePath - Optional path to context file for prioritization
263
+ * @returns Prioritized array of source files
264
+ * @private
265
+ */
266
+ prioritizeSourceFiles(sourceFiles, contextFilePath) {
267
+ if (!contextFilePath) {
268
+ return sourceFiles;
269
+ }
270
+ const contextDir = contextFilePath.substring(0, contextFilePath.lastIndexOf('/'));
271
+ return sourceFiles.sort((a, b) => {
272
+ const aDir = a.fileName.substring(0, a.fileName.lastIndexOf('/'));
273
+ const bDir = b.fileName.substring(0, b.fileName.lastIndexOf('/'));
274
+ // Prioritize files in the same directory as context
275
+ const aInSameDir = aDir === contextDir ? 1 : 0;
276
+ const bInSameDir = bDir === contextDir ? 1 : 0;
277
+ if (aInSameDir !== bInSameDir) {
278
+ return bInSameDir - aInSameDir; // Higher priority first
279
+ }
280
+ // Prioritize non-test files over test files
281
+ const aIsTest = a.fileName.includes('test') || a.fileName.includes('spec') ? 0 : 1;
282
+ const bIsTest = b.fileName.includes('test') || b.fileName.includes('spec') ? 0 : 1;
283
+ if (aIsTest !== bIsTest) {
284
+ return bIsTest - aIsTest; // Non-test files first
285
+ }
286
+ return 0;
287
+ });
288
+ }
205
289
  /**
206
290
  * Gets the singleton instance of SchemaTransformer.
207
291
  *
@@ -228,16 +312,88 @@ class SchemaTransformer {
228
312
  /**
229
313
  * Clears the current singleton instance. Useful for testing or when you need
230
314
  * to create a new instance with different configuration.
315
+ * @private
231
316
  */
232
317
  static clearInstance() {
233
- SchemaTransformer.instance = null;
318
+ SchemaTransformer.instance = undefined;
319
+ }
320
+ /**
321
+ * Flag to prevent recursive disposal calls
322
+ * @private
323
+ */
324
+ static disposingInProgress = false;
325
+ /**
326
+ * Completely disposes of the current singleton instance and releases all resources.
327
+ * This is a static method that can be called without having an instance reference.
328
+ * Ensures complete memory cleanup regardless of the current state.
329
+ *
330
+ * @example
331
+ * ```typescript
332
+ * SchemaTransformer.disposeInstance();
333
+ * // All resources released, next getInstance() will create fresh instance
334
+ * ```
335
+ *
336
+ * @public
337
+ */
338
+ static disposeInstance() {
339
+ // Prevent recursive disposal calls
340
+ if (SchemaTransformer.disposingInProgress) {
341
+ return;
342
+ }
343
+ SchemaTransformer.disposingInProgress = true;
344
+ try {
345
+ if (SchemaTransformer.instance) {
346
+ SchemaTransformer.instance.dispose();
347
+ }
348
+ }
349
+ catch (error) {
350
+ // Log any disposal errors but continue with cleanup
351
+ console.warn('Warning during static disposal:', error);
352
+ }
353
+ finally {
354
+ // Always ensure the static instance is cleared
355
+ SchemaTransformer.instance = undefined;
356
+ SchemaTransformer.disposingInProgress = false;
357
+ // Force garbage collection for cleanup
358
+ if (global.gc) {
359
+ global.gc();
360
+ }
361
+ }
362
+ }
363
+ /**
364
+ * @deprecated Use disposeInstance() instead for better clarity
365
+ * @private
366
+ */
367
+ static dispose() {
368
+ SchemaTransformer.disposeInstance();
234
369
  }
235
370
  static getInstance(tsConfigPath, options) {
236
- if (!SchemaTransformer.instance) {
371
+ if (!SchemaTransformer.instance || SchemaTransformer.isInstanceDisposed()) {
237
372
  SchemaTransformer.instance = new SchemaTransformer(tsConfigPath, options);
238
373
  }
239
374
  return SchemaTransformer.instance;
240
375
  }
376
+ /**
377
+ * Internal method to check if current instance is disposed
378
+ * @private
379
+ */
380
+ static isInstanceDisposed() {
381
+ return SchemaTransformer.instance
382
+ ? SchemaTransformer.instance.isDisposed()
383
+ : true;
384
+ }
385
+ /**
386
+ * Transforms a class using the singleton instance
387
+ * @param cls - The class constructor function to transform
388
+ * @param options - Optional configuration for memory management (only used if no instance exists)
389
+ * @returns Object containing the class name and its corresponding JSON schema
390
+ * @public
391
+ */
392
+ static transformClass(cls, options) {
393
+ // Use the singleton instance instead of creating a temporary one
394
+ const transformer = SchemaTransformer.getInstance(undefined, options);
395
+ return transformer.transform(cls);
396
+ }
241
397
  /**
242
398
  * Transforms a class constructor function into an OpenAPI schema object.
243
399
  *
@@ -272,31 +428,147 @@ class SchemaTransformer {
272
428
  clearCache() {
273
429
  this.classCache.clear();
274
430
  this.loadedFiles.clear();
431
+ this.processingClasses.clear();
275
432
  // Force garbage collection hint if available
276
433
  if (global.gc) {
277
434
  global.gc();
278
435
  }
279
436
  }
437
+ /**
438
+ * Completely disposes of the transformer instance and releases all resources.
439
+ * This includes clearing all caches, releasing TypeScript program resources,
440
+ * and resetting the singleton instance.
441
+ *
442
+ * After calling this method, you need to call getInstance() again to get a new instance.
443
+ *
444
+ * @example
445
+ * ```typescript
446
+ * const transformer = SchemaTransformer.getInstance();
447
+ * // ... use transformer
448
+ * transformer.dispose();
449
+ * // transformer is now unusable, need to get new instance
450
+ * const newTransformer = SchemaTransformer.getInstance();
451
+ * ```
452
+ *
453
+ * @private
454
+ */
455
+ dispose() {
456
+ try {
457
+ // Clear all caches and sets completely
458
+ this.classCache.clear();
459
+ this.loadedFiles.clear();
460
+ this.processingClasses.clear();
461
+ // Release TypeScript program resources
462
+ // While TypeScript doesn't provide explicit disposal methods,
463
+ // we can help garbage collection by clearing all references
464
+ // Clear all references to TypeScript objects
465
+ // @ts-ignore - We're intentionally setting these to null for cleanup
466
+ this.program = null;
467
+ // @ts-ignore - We're intentionally setting these to null for cleanup
468
+ this.checker = null;
469
+ }
470
+ catch (error) {
471
+ // If there's any error during disposal, log it but continue
472
+ console.warn('Warning during transformer disposal:', error);
473
+ }
474
+ finally {
475
+ // Force garbage collection for cleanup
476
+ if (global.gc) {
477
+ global.gc();
478
+ }
479
+ }
480
+ }
481
+ /**
482
+ * Completely resets the transformer by disposing current instance and creating a new one.
483
+ * This is useful when you need a fresh start with different TypeScript configuration
484
+ * or want to ensure all resources are properly released and recreated.
485
+ *
486
+ * @param tsConfigPath - Optional path to a specific TypeScript config file for the new instance
487
+ * @param options - Configuration options for memory management for the new instance
488
+ * @returns A fresh SchemaTransformer instance
489
+ *
490
+ * @example
491
+ * ```typescript
492
+ * const transformer = SchemaTransformer.getInstance();
493
+ * // ... use transformer
494
+ * const freshTransformer = transformer.reset('./new-tsconfig.json');
495
+ * ```
496
+ *
497
+ * @private
498
+ */
499
+ reset(tsConfigPath, options) {
500
+ // Dispose current instance using static method to properly clear instance reference
501
+ SchemaTransformer.disposeInstance();
502
+ // Create and return new instance
503
+ return SchemaTransformer.getInstance(tsConfigPath, options);
504
+ }
280
505
  /**
281
506
  * Gets memory usage statistics for monitoring and debugging.
282
507
  *
283
- * @returns Object containing cache size and loaded files count
508
+ * @returns Object containing cache size, loaded files count, and processing status
284
509
  *
285
510
  * @example
286
511
  * ```typescript
287
512
  * const transformer = SchemaTransformer.getInstance();
288
513
  * const stats = transformer.getMemoryStats();
289
514
  * console.log(`Cache entries: ${stats.cacheSize}, Files loaded: ${stats.loadedFiles}`);
515
+ * console.log(`Currently processing: ${stats.currentlyProcessing} classes`);
290
516
  * ```
291
517
  *
292
- * @public
518
+ * @private
293
519
  */
294
520
  getMemoryStats() {
295
521
  return {
296
- cacheSize: this.classCache.size,
297
- loadedFiles: this.loadedFiles.size,
522
+ cacheSize: this.classCache?.size || 0,
523
+ loadedFiles: this.loadedFiles?.size || 0,
524
+ currentlyProcessing: this.processingClasses?.size || 0,
525
+ maxCacheSize: this.maxCacheSize || 0,
526
+ autoCleanup: this.autoCleanup || false,
527
+ isDisposed: !this.program || !this.checker,
298
528
  };
299
529
  }
530
+ /**
531
+ * Checks if the transformer instance has been disposed and is no longer usable.
532
+ *
533
+ * @returns True if the instance has been disposed
534
+ *
535
+ * @example
536
+ * ```typescript
537
+ * const transformer = SchemaTransformer.getInstance();
538
+ * transformer.dispose();
539
+ * console.log(transformer.isDisposed()); // true
540
+ * ```
541
+ *
542
+ * @private
543
+ */
544
+ isDisposed() {
545
+ return (!this.program ||
546
+ !this.checker ||
547
+ !this.classCache ||
548
+ !this.loadedFiles ||
549
+ !this.processingClasses);
550
+ }
551
+ /**
552
+ * Static method to check if there's an active singleton instance.
553
+ *
554
+ * @returns True if there's an active instance, false if disposed or never created
555
+ *
556
+ * @example
557
+ * ```typescript
558
+ * console.log(SchemaTransformer.hasActiveInstance()); // false
559
+ * const transformer = SchemaTransformer.getInstance();
560
+ * console.log(SchemaTransformer.hasActiveInstance()); // true
561
+ * SchemaTransformer.dispose();
562
+ * console.log(SchemaTransformer.hasActiveInstance()); // false
563
+ * ```
564
+ *
565
+ * @private
566
+ */
567
+ static hasActiveInstance() {
568
+ return (SchemaTransformer.instance !== null &&
569
+ SchemaTransformer.instance !== undefined &&
570
+ !SchemaTransformer.isInstanceDisposed());
571
+ }
300
572
  /**
301
573
  * Finds a class declaration by name within a source file.
302
574
  *
@@ -321,13 +593,14 @@ class SchemaTransformer {
321
593
  * Transforms a TypeScript class declaration into a schema object.
322
594
  *
323
595
  * @param classNode - The TypeScript class declaration node
596
+ * @param sourceFile - The source file containing the class (for context)
324
597
  * @returns Object containing class name and generated schema
325
598
  * @private
326
599
  */
327
- transformClass(classNode) {
600
+ transformClass(classNode, sourceFile) {
328
601
  const className = classNode.name?.text || 'Unknown';
329
602
  const properties = this.extractProperties(classNode);
330
- const schema = this.generateSchema(properties);
603
+ const schema = this.generateSchema(properties, sourceFile?.fileName);
331
604
  return { name: className, schema };
332
605
  }
333
606
  /**
@@ -371,6 +644,237 @@ class SchemaTransformer {
371
644
  const type = this.checker.getTypeAtLocation(property);
372
645
  return this.checker.typeToString(type);
373
646
  }
647
+ /**
648
+ * Resolves generic types by analyzing the type alias and its arguments.
649
+ * For example, User<Role> where User is a type alias will be resolved to its structure.
650
+ *
651
+ * @param typeNode - The TypeScript type reference node with generic arguments
652
+ * @returns String representation of the resolved type or schema
653
+ * @private
654
+ */
655
+ resolveGenericType(typeNode) {
656
+ const typeName = typeNode.typeName.text;
657
+ const typeArguments = typeNode.typeArguments;
658
+ if (!typeArguments || typeArguments.length === 0) {
659
+ return typeName;
660
+ }
661
+ // Try to resolve the type using the TypeScript type checker
662
+ const type = this.checker.getTypeAtLocation(typeNode);
663
+ const resolvedType = this.checker.typeToString(type);
664
+ // If we can resolve it to a meaningful structure, use that
665
+ if (resolvedType &&
666
+ resolvedType !== typeName &&
667
+ !resolvedType.includes('any')) {
668
+ // For type aliases like User<Role>, we want to create a synthetic type name
669
+ // that represents the resolved structure
670
+ const typeArgNames = typeArguments.map(arg => {
671
+ if (ts.isTypeReferenceNode(arg) && ts.isIdentifier(arg.typeName)) {
672
+ return arg.typeName.text;
673
+ }
674
+ return this.getTypeNodeToString(arg);
675
+ });
676
+ return `${typeName}_${typeArgNames.join('_')}`;
677
+ }
678
+ return typeName;
679
+ }
680
+ /**
681
+ * Checks if a type string represents a resolved generic type.
682
+ *
683
+ * @param type - The type string to check
684
+ * @returns True if it's a resolved generic type
685
+ * @private
686
+ */
687
+ isResolvedGenericType(type) {
688
+ // Simple heuristic: resolved generic types contain underscores and
689
+ // the parts after underscore should be known types
690
+ const parts = type.split('_');
691
+ return (parts.length > 1 &&
692
+ parts
693
+ .slice(1)
694
+ .every(part => this.isKnownType(part) || this.isPrimitiveType(part)));
695
+ }
696
+ /**
697
+ * Checks if a type is a known class or interface.
698
+ *
699
+ * @param typeName - The type name to check
700
+ * @returns True if it's a known type
701
+ * @private
702
+ */
703
+ isKnownType(typeName) {
704
+ // First check if it's a primitive type to avoid unnecessary lookups
705
+ if (this.isPrimitiveType(typeName)) {
706
+ return true;
707
+ }
708
+ try {
709
+ // Use a more conservative approach - check if we can find the class
710
+ // without actually transforming it to avoid side effects
711
+ const found = this.findClassInProject(typeName);
712
+ return found !== null;
713
+ }
714
+ catch {
715
+ return false;
716
+ }
717
+ }
718
+ /**
719
+ * Finds a class by name in the project without transforming it.
720
+ *
721
+ * @param className - The class name to find
722
+ * @returns True if found, false otherwise
723
+ * @private
724
+ */
725
+ findClassInProject(className) {
726
+ const sourceFiles = this.program.getSourceFiles().filter(sf => {
727
+ if (sf.isDeclarationFile)
728
+ return false;
729
+ if (sf.fileName.includes('.d.ts'))
730
+ return false;
731
+ if (sf.fileName.includes('node_modules'))
732
+ return false;
733
+ return true;
734
+ });
735
+ for (const sourceFile of sourceFiles) {
736
+ const found = this.findClassByName(sourceFile, className);
737
+ if (found)
738
+ return true;
739
+ }
740
+ return false;
741
+ }
742
+ /**
743
+ * Checks if a type is a primitive type.
744
+ *
745
+ * @param typeName - The type name to check
746
+ * @returns True if it's a primitive type
747
+ * @private
748
+ */
749
+ isPrimitiveType(typeName) {
750
+ const lowerTypeName = typeName.toLowerCase();
751
+ // Check against all primitive types from constants
752
+ const primitiveTypes = [
753
+ constants.jsPrimitives.String.type.toLowerCase(),
754
+ constants.jsPrimitives.Number.type.toLowerCase(),
755
+ constants.jsPrimitives.Boolean.type.toLowerCase(),
756
+ constants.jsPrimitives.Date.type.toLowerCase(),
757
+ constants.jsPrimitives.Buffer.type.toLowerCase(),
758
+ constants.jsPrimitives.Uint8Array.type.toLowerCase(),
759
+ constants.jsPrimitives.File.type.toLowerCase(),
760
+ constants.jsPrimitives.UploadFile.type.toLowerCase(),
761
+ constants.jsPrimitives.BigInt.type.toLowerCase(),
762
+ ];
763
+ return primitiveTypes.includes(lowerTypeName);
764
+ }
765
+ /**
766
+ * Resolves a generic type schema by analyzing the type alias structure.
767
+ *
768
+ * @param resolvedTypeName - The resolved generic type name (e.g., User_Role)
769
+ * @returns OpenAPI schema for the resolved generic type
770
+ * @private
771
+ */
772
+ resolveGenericTypeSchema(resolvedTypeName) {
773
+ const parts = resolvedTypeName.split('_');
774
+ const baseTypeName = parts[0];
775
+ const typeArgNames = parts.slice(1);
776
+ if (!baseTypeName) {
777
+ return null;
778
+ }
779
+ // Find the original type alias declaration
780
+ const typeAliasSymbol = this.findTypeAliasDeclaration(baseTypeName);
781
+ if (!typeAliasSymbol) {
782
+ return null;
783
+ }
784
+ // Create a schema based on the type alias structure, substituting type parameters
785
+ return this.createSchemaFromTypeAlias(typeAliasSymbol, typeArgNames);
786
+ }
787
+ /**
788
+ * Finds a type alias declaration by name.
789
+ *
790
+ * @param typeName - The type alias name to find
791
+ * @returns The type alias declaration node or null
792
+ * @private
793
+ */
794
+ findTypeAliasDeclaration(typeName) {
795
+ for (const sourceFile of this.program.getSourceFiles()) {
796
+ if (sourceFile.isDeclarationFile)
797
+ continue;
798
+ const findTypeAlias = (node) => {
799
+ if (ts.isTypeAliasDeclaration(node) && node.name.text === typeName) {
800
+ return node;
801
+ }
802
+ return ts.forEachChild(node, findTypeAlias) || null;
803
+ };
804
+ const result = findTypeAlias(sourceFile);
805
+ if (result)
806
+ return result;
807
+ }
808
+ return null;
809
+ }
810
+ /**
811
+ * Creates a schema from a type alias declaration, substituting type parameters.
812
+ *
813
+ * @param typeAlias - The type alias declaration
814
+ * @param typeArgNames - The concrete type arguments
815
+ * @returns OpenAPI schema for the type alias
816
+ * @private
817
+ */
818
+ createSchemaFromTypeAlias(typeAlias, typeArgNames) {
819
+ const typeNode = typeAlias.type;
820
+ if (ts.isTypeLiteralNode(typeNode)) {
821
+ const schema = {
822
+ type: 'object',
823
+ properties: {},
824
+ required: [],
825
+ };
826
+ for (const member of typeNode.members) {
827
+ if (ts.isPropertySignature(member) &&
828
+ member.name &&
829
+ ts.isIdentifier(member.name)) {
830
+ const propertyName = member.name.text;
831
+ const isOptional = !!member.questionToken;
832
+ if (member.type) {
833
+ const propertyType = this.resolveTypeParameterInTypeAlias(member.type, typeAlias.typeParameters, typeArgNames);
834
+ const { type, format, nestedSchema } = this.mapTypeToSchema(propertyType);
835
+ if (nestedSchema) {
836
+ schema.properties[propertyName] = nestedSchema;
837
+ }
838
+ else {
839
+ schema.properties[propertyName] = { type };
840
+ if (format)
841
+ schema.properties[propertyName].format = format;
842
+ }
843
+ if (!isOptional) {
844
+ schema.required.push(propertyName);
845
+ }
846
+ }
847
+ }
848
+ }
849
+ return schema;
850
+ }
851
+ return null;
852
+ }
853
+ /**
854
+ * Resolves type parameters in a type alias to concrete types.
855
+ *
856
+ * @param typeNode - The type node to resolve
857
+ * @param typeParameters - The type parameters of the type alias
858
+ * @param typeArgNames - The concrete type arguments
859
+ * @returns The resolved type string
860
+ * @private
861
+ */
862
+ resolveTypeParameterInTypeAlias(typeNode, typeParameters, typeArgNames) {
863
+ if (ts.isTypeReferenceNode(typeNode) &&
864
+ ts.isIdentifier(typeNode.typeName)) {
865
+ const typeName = typeNode.typeName.text;
866
+ // Check if this is a type parameter
867
+ if (typeParameters) {
868
+ const paramIndex = typeParameters.findIndex(param => param.name.text === typeName);
869
+ if (paramIndex !== -1 && paramIndex < typeArgNames.length) {
870
+ const resolvedType = typeArgNames[paramIndex];
871
+ return resolvedType || typeName;
872
+ }
873
+ }
874
+ return typeName;
875
+ }
876
+ return this.getTypeNodeToString(typeNode);
877
+ }
374
878
  /**
375
879
  * Converts a TypeScript type node to its string representation.
376
880
  *
@@ -396,6 +900,7 @@ class SchemaTransformer {
396
900
  return firstTypeArg.typeName.text;
397
901
  }
398
902
  }
903
+ return this.resolveGenericType(typeNode);
399
904
  }
400
905
  return typeNode.typeName.text;
401
906
  }
@@ -494,19 +999,24 @@ class SchemaTransformer {
494
999
  * Generates an OpenAPI schema from extracted property information.
495
1000
  *
496
1001
  * @param properties - Array of property information to process
1002
+ * @param contextFilePath - Optional context file path for resolving class references
497
1003
  * @returns Complete OpenAPI schema object with properties and validation rules
498
1004
  * @private
499
1005
  */
500
- generateSchema(properties) {
1006
+ generateSchema(properties, contextFilePath) {
501
1007
  const schema = {
502
1008
  type: 'object',
503
1009
  properties: {},
504
1010
  required: [],
505
1011
  };
506
1012
  for (const property of properties) {
507
- const { type, format, nestedSchema } = this.mapTypeToSchema(property.type);
1013
+ const { type, format, nestedSchema } = this.mapTypeToSchema(property.type, contextFilePath);
508
1014
  if (nestedSchema) {
509
1015
  schema.properties[property.name] = nestedSchema;
1016
+ // Skip decorator application for $ref schemas
1017
+ if (this.isRefSchema(nestedSchema)) {
1018
+ continue;
1019
+ }
510
1020
  }
511
1021
  else {
512
1022
  schema.properties[property.name] = { type };
@@ -529,14 +1039,15 @@ class SchemaTransformer {
529
1039
  * Handles primitive types, arrays, and nested objects recursively.
530
1040
  *
531
1041
  * @param type - The TypeScript type string to map
1042
+ * @param contextFilePath - Optional context file path for resolving class references
532
1043
  * @returns Object containing OpenAPI type, optional format, and nested schema
533
1044
  * @private
534
1045
  */
535
- mapTypeToSchema(type) {
1046
+ mapTypeToSchema(type, contextFilePath) {
536
1047
  // Handle arrays
537
1048
  if (type.endsWith('[]')) {
538
1049
  const elementType = type.slice(0, -2);
539
- const elementSchema = this.mapTypeToSchema(elementType);
1050
+ const elementSchema = this.mapTypeToSchema(elementType, contextFilePath);
540
1051
  const items = elementSchema.nestedSchema || {
541
1052
  type: elementSchema.type,
542
1053
  };
@@ -580,9 +1091,31 @@ class SchemaTransformer {
580
1091
  format: constants.jsPrimitives.UploadFile.format,
581
1092
  };
582
1093
  default:
1094
+ // Check if it's a resolved generic type (e.g., User_Role)
1095
+ if (type.includes('_') && this.isResolvedGenericType(type)) {
1096
+ try {
1097
+ const genericSchema = this.resolveGenericTypeSchema(type);
1098
+ if (genericSchema) {
1099
+ return {
1100
+ type: constants.jsPrimitives.Object.value,
1101
+ nestedSchema: genericSchema,
1102
+ };
1103
+ }
1104
+ }
1105
+ catch (error) {
1106
+ console.warn(`Failed to resolve generic type ${type}:`, error);
1107
+ }
1108
+ }
583
1109
  // Handle nested objects
584
1110
  try {
585
- const nestedResult = this.transformByName(type);
1111
+ const nestedResult = this.transformByName(type, contextFilePath);
1112
+ // Check if it's a $ref schema (circular reference)
1113
+ if (nestedResult.schema.$ref) {
1114
+ return {
1115
+ type: constants.jsPrimitives.Object.value,
1116
+ nestedSchema: nestedResult.schema,
1117
+ };
1118
+ }
586
1119
  return {
587
1120
  type: constants.jsPrimitives.Object.value,
588
1121
  nestedSchema: nestedResult.schema,
@@ -593,6 +1126,16 @@ class SchemaTransformer {
593
1126
  }
594
1127
  }
595
1128
  }
1129
+ /**
1130
+ * Checks if a schema is a $ref schema (circular reference).
1131
+ *
1132
+ * @param schema - The schema to check
1133
+ * @returns True if it's a $ref schema
1134
+ * @private
1135
+ */
1136
+ isRefSchema(schema) {
1137
+ return '$ref' in schema;
1138
+ }
596
1139
  /**
597
1140
  * Applies class-validator decorators to schema properties.
598
1141
  * Maps validation decorators to their corresponding OpenAPI schema constraints.
@@ -603,6 +1146,10 @@ class SchemaTransformer {
603
1146
  * @private
604
1147
  */
605
1148
  applyDecorators(decorators, schema, propertyName) {
1149
+ // Skip applying decorators to $ref schemas
1150
+ if (this.isRefSchema(schema)) {
1151
+ return;
1152
+ }
606
1153
  const isArrayType = schema.properties[propertyName].type ===
607
1154
  constants.jsPrimitives.Array.value;
608
1155
  for (const decorator of decorators) {
@@ -718,8 +1265,193 @@ class SchemaTransformer {
718
1265
  case constants.validatorDecorators.ArrayMaxSize.name:
719
1266
  schema.properties[propertyName].maxItems = decorator.arguments[0];
720
1267
  break;
1268
+ case constants.validatorDecorators.IsEnum.name:
1269
+ this.applyEnumDecorator(decorator, schema, propertyName, isArrayType);
1270
+ break;
1271
+ }
1272
+ }
1273
+ }
1274
+ /**
1275
+ * Applies the @IsEnum decorator to a property, handling both primitive values and object enums.
1276
+ * Supports arrays of enum values as well.
1277
+ *
1278
+ * @param decorator - The IsEnum decorator information
1279
+ * @param schema - The schema object to modify
1280
+ * @param propertyName - The name of the property
1281
+ * @param isArrayType - Whether the property is an array type
1282
+ * @private
1283
+ */
1284
+ applyEnumDecorator(decorator, schema, propertyName, isArrayType) {
1285
+ if (!decorator.arguments || decorator.arguments.length === 0) {
1286
+ return;
1287
+ }
1288
+ const enumArg = decorator.arguments[0];
1289
+ let enumValues = [];
1290
+ // Handle different enum argument types
1291
+ if (typeof enumArg === 'string') {
1292
+ // This is likely a reference to an enum type name
1293
+ // We need to try to resolve this to actual enum values
1294
+ enumValues = this.resolveEnumValues(enumArg);
1295
+ }
1296
+ else if (typeof enumArg === 'object' && enumArg !== null) {
1297
+ // Object enum - extract values
1298
+ if (Array.isArray(enumArg)) {
1299
+ // Already an array of values
1300
+ enumValues = enumArg;
1301
+ }
1302
+ else {
1303
+ // Enum object - get all values
1304
+ enumValues = Object.values(enumArg);
1305
+ }
1306
+ }
1307
+ // If we couldn't resolve enum values, fall back to string type without enum constraint
1308
+ if (enumValues.length === 0) {
1309
+ if (!isArrayType) {
1310
+ schema.properties[propertyName].type = 'string';
1311
+ }
1312
+ else if (schema.properties[propertyName].items) {
1313
+ schema.properties[propertyName].items.type = 'string';
1314
+ }
1315
+ return;
1316
+ }
1317
+ // Determine the type based on enum values
1318
+ let enumType = 'string';
1319
+ if (enumValues.length > 0) {
1320
+ const firstValue = enumValues[0];
1321
+ if (typeof firstValue === 'number') {
1322
+ enumType = 'number';
1323
+ }
1324
+ else if (typeof firstValue === 'boolean') {
1325
+ enumType = 'boolean';
1326
+ }
1327
+ }
1328
+ // Apply enum to schema
1329
+ if (!isArrayType) {
1330
+ schema.properties[propertyName].type = enumType;
1331
+ schema.properties[propertyName].enum = enumValues;
1332
+ }
1333
+ else if (schema.properties[propertyName].items) {
1334
+ schema.properties[propertyName].items.type = enumType;
1335
+ schema.properties[propertyName].items.enum = enumValues;
1336
+ }
1337
+ }
1338
+ /**
1339
+ * Attempts to resolve enum values from an enum type name.
1340
+ * This searches through the TypeScript AST to find the enum declaration
1341
+ * and extract its values.
1342
+ *
1343
+ * @param enumTypeName - The name of the enum type
1344
+ * @returns Array of enum values if found, empty array otherwise
1345
+ * @private
1346
+ */
1347
+ resolveEnumValues(enumTypeName) {
1348
+ // Search for enum declarations in source files
1349
+ for (const sourceFile of this.program.getSourceFiles()) {
1350
+ if (sourceFile.isDeclarationFile)
1351
+ continue;
1352
+ if (sourceFile.fileName.includes('node_modules'))
1353
+ continue;
1354
+ const enumValues = this.findEnumValues(sourceFile, enumTypeName);
1355
+ if (enumValues.length > 0) {
1356
+ return enumValues;
1357
+ }
1358
+ }
1359
+ return [];
1360
+ }
1361
+ /**
1362
+ * Finds enum values in a specific source file.
1363
+ *
1364
+ * @param sourceFile - The source file to search
1365
+ * @param enumTypeName - The name of the enum to find
1366
+ * @returns Array of enum values if found, empty array otherwise
1367
+ * @private
1368
+ */
1369
+ findEnumValues(sourceFile, enumTypeName) {
1370
+ let enumValues = [];
1371
+ const visit = (node) => {
1372
+ // Handle TypeScript enum declarations
1373
+ if (ts.isEnumDeclaration(node) && node.name?.text === enumTypeName) {
1374
+ enumValues = this.extractEnumValues(node);
1375
+ return;
1376
+ }
1377
+ // Handle const object declarations (like const Status = { ... } as const)
1378
+ if (ts.isVariableStatement(node)) {
1379
+ for (const declaration of node.declarationList.declarations) {
1380
+ if (ts.isVariableDeclaration(declaration) &&
1381
+ ts.isIdentifier(declaration.name) &&
1382
+ declaration.name.text === enumTypeName &&
1383
+ declaration.initializer) {
1384
+ let initializer = declaration.initializer;
1385
+ // Handle "as const" assertions
1386
+ if (ts.isAsExpression(initializer) && initializer.expression) {
1387
+ initializer = initializer.expression;
1388
+ }
1389
+ enumValues = this.extractObjectEnumValues(initializer);
1390
+ return;
1391
+ }
1392
+ }
1393
+ }
1394
+ ts.forEachChild(node, visit);
1395
+ };
1396
+ visit(sourceFile);
1397
+ return enumValues;
1398
+ }
1399
+ /**
1400
+ * Extracts values from a TypeScript enum declaration.
1401
+ *
1402
+ * @param enumNode - The enum declaration node
1403
+ * @returns Array of enum values
1404
+ * @private
1405
+ */
1406
+ extractEnumValues(enumNode) {
1407
+ const values = [];
1408
+ for (const member of enumNode.members) {
1409
+ if (member.initializer) {
1410
+ // Handle initialized enum members
1411
+ if (ts.isStringLiteral(member.initializer)) {
1412
+ values.push(member.initializer.text);
1413
+ }
1414
+ else if (ts.isNumericLiteral(member.initializer)) {
1415
+ values.push(Number(member.initializer.text));
1416
+ }
1417
+ }
1418
+ else {
1419
+ // Handle auto-incremented numeric enums
1420
+ if (values.length === 0) {
1421
+ values.push(0);
1422
+ }
1423
+ else {
1424
+ const lastValue = values[values.length - 1];
1425
+ if (typeof lastValue === 'number') {
1426
+ values.push(lastValue + 1);
1427
+ }
1428
+ }
1429
+ }
1430
+ }
1431
+ return values;
1432
+ }
1433
+ /**
1434
+ * Extracts values from object literal enum (const object as const).
1435
+ *
1436
+ * @param initializer - The object literal initializer
1437
+ * @returns Array of enum values
1438
+ * @private
1439
+ */
1440
+ extractObjectEnumValues(initializer) {
1441
+ const values = [];
1442
+ if (ts.isObjectLiteralExpression(initializer)) {
1443
+ for (const property of initializer.properties) {
1444
+ if (ts.isPropertyAssignment(property) && property.initializer) {
1445
+ if (ts.isStringLiteral(property.initializer)) {
1446
+ values.push(property.initializer.text);
1447
+ }
1448
+ else if (ts.isNumericLiteral(property.initializer)) {
1449
+ values.push(Number(property.initializer.text));
1450
+ }
1451
+ }
721
1452
  }
722
1453
  }
1454
+ return values;
723
1455
  }
724
1456
  /**
725
1457
  * Applies sensible default behaviors for properties without class-validator decorators.
@@ -739,6 +1471,10 @@ class SchemaTransformer {
739
1471
  * @private
740
1472
  */
741
1473
  applyTypeBasedFormats(property, schema) {
1474
+ // Skip applying type-based formats to $ref schemas
1475
+ if (this.isRefSchema(schema)) {
1476
+ return;
1477
+ }
742
1478
  const propertyName = property.name;
743
1479
  const propertyType = property.type.toLowerCase();
744
1480
  const propertySchema = schema.properties[propertyName];
@@ -773,6 +1509,10 @@ class SchemaTransformer {
773
1509
  * @private
774
1510
  */
775
1511
  determineRequiredStatus(property, schema) {
1512
+ // Skip determining required status for $ref schemas
1513
+ if (this.isRefSchema(schema)) {
1514
+ return;
1515
+ }
776
1516
  const propertyName = property.name;
777
1517
  // Check if already marked as required by IsNotEmpty or ArrayNotEmpty decorator
778
1518
  const isAlreadyRequired = schema.required.includes(propertyName);
@@ -813,7 +1553,7 @@ class SchemaTransformer {
813
1553
  * @public
814
1554
  */
815
1555
  function transform(cls, options) {
816
- return SchemaTransformer.getInstance(undefined, options).transform(cls);
1556
+ return SchemaTransformer.transformClass(cls, options);
817
1557
  }
818
1558
 
819
1559
  class FileTest {
@@ -857,3 +1597,4 @@ try {
857
1597
  catch (error) {
858
1598
  console.error('❌ Error:', error instanceof Error ? error.message : String(error));
859
1599
  }
1600
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLmpzIiwic291cmNlcyI6WyIuLi9zcmMvdHJhbnNmb3JtZXIuZml4dHVyZXMudHMiLCIuLi9zcmMvdHJhbnNmb3JtZXIudHMiLCIuLi9zcmMvcnVuLnRzIl0sInNvdXJjZXNDb250ZW50IjpbbnVsbCxudWxsLG51bGxdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQVdBLE1BQU0sc0JBQXNCLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsZUFBZSxDQUFDO0FBRTNFLE1BQU0sWUFBWSxHQUFHO0lBQ25CLE1BQU0sRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRTtBQUMzQyxJQUFBLE1BQU0sRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFO0lBQzVELE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRTtJQUM5QyxNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUU7QUFDM0MsSUFBQSxNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRTtJQUM3RCxJQUFJLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUU7SUFDckMsTUFBTSxFQUFFLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFO0lBQzNDLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRTtBQUN4QyxJQUFBLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsV0FBVyxFQUFFO0lBQzVELFFBQVEsRUFBRSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRTtBQUNqRCxJQUFBLE1BQU0sRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFO0FBQzdELElBQUEsVUFBVSxFQUFFLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUU7QUFDckUsSUFBQSxVQUFVLEVBQUUsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRTtBQUNyRSxJQUFBLElBQUksRUFBRSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFO0NBQzFEO0FBRUQsTUFBTSxtQkFBbUIsR0FBRztJQUMxQixNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUU7SUFDMUMsU0FBUyxFQUFFLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO0lBQ2hELFNBQVMsRUFBRSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRTtBQUNoRCxJQUFBLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFO0FBQzFELElBQUEsUUFBUSxFQUFFLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUU7QUFDaEUsSUFBQSxRQUFRLEVBQUUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRTtJQUNoRSxVQUFVLEVBQUUsRUFBRSxJQUFJLEVB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