next-openapi-gen 1.2.1 → 1.2.3

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.
@@ -756,6 +756,17 @@ function mergeJSDocData(target, source) {
756
756
  function cleanComment(commentValue) {
757
757
  return commentValue.replace(/\*\s*/g, "").trim();
758
758
  }
759
+ function extractSchemaIdFromComments(comments) {
760
+ if (!comments)
761
+ return null;
762
+ for (const comment of comments) {
763
+ const cleaned = cleanComment(comment.value);
764
+ const id = extractTokenValue(cleaned, "@id");
765
+ if (id)
766
+ return id;
767
+ }
768
+ return null;
769
+ }
759
770
  function extractLineValue(commentValue, tag) {
760
771
  return commentValue.match(new RegExp(`${escapeRegExp(tag)}\\s*(.*)`, "m"))?.[1]?.trim() || "";
761
772
  }
@@ -3172,7 +3183,8 @@ var DrizzleZodProcessor = class _DrizzleZodProcessor {
3172
3183
  if (firstArg && !t4.isSpreadElement(firstArg) && !t4.isArgumentPlaceholder(firstArg)) {
3173
3184
  const metadata = _DrizzleZodProcessor.extractStaticObject(firstArg);
3174
3185
  if (metadata) {
3175
- Object.assign(result, metadata);
3186
+ const { id: _id, ...rest } = metadata;
3187
+ Object.assign(result, rest);
3176
3188
  }
3177
3189
  }
3178
3190
  break;
@@ -11456,8 +11468,11 @@ var ZodRuntimeExporter = class {
11456
11468
  case "deprecated":
11457
11469
  return schema.meta({ deprecated: true });
11458
11470
  case "meta": {
11459
- const metadata = node.arguments[0] ? this.buildMetadataObject(node.arguments[0]) : null;
11460
- return metadata ? schema.meta(metadata) : schema;
11471
+ const rawMetadata = node.arguments[0] ? this.buildMetadataObject(node.arguments[0]) : null;
11472
+ if (!rawMetadata)
11473
+ return schema;
11474
+ const { id: _id, ...metadata } = rawMetadata;
11475
+ return Object.keys(metadata).length > 0 ? schema.meta(metadata) : schema;
11461
11476
  }
11462
11477
  case "default":
11463
11478
  case "prefault":
@@ -11714,6 +11729,9 @@ var ZodSchemaConverter = class {
11714
11729
  schemaNameToFiles = /* @__PURE__ */ new Map();
11715
11730
  /** Per-file import alias for the `zod` module (`import { z as zod }` sets this to `"zod"`). */
11716
11731
  zodImportAlias = /* @__PURE__ */ new Map();
11732
+ /** Schema variable names whose component name was overridden via .meta({ id }). These must
11733
+ * NOT be copied back under the original variable name in the OpenAPI components object. */
11734
+ metaIdSchemaNames = /* @__PURE__ */ new Set();
11717
11735
  // Current processing context (set during file processing)
11718
11736
  currentFilePath;
11719
11737
  currentAST;
@@ -11740,7 +11758,14 @@ var ZodSchemaConverter = class {
11740
11758
  }
11741
11759
  logger.debug(`Looking for Zod schema: ${schemaName}`);
11742
11760
  const requestedSchemaName = schemaName;
11743
- const mappedSchemaName = this.typeToSchemaMapping[schemaName];
11761
+ let mappedSchemaName = this.typeToSchemaMapping[schemaName];
11762
+ if (!mappedSchemaName) {
11763
+ const candidate = this.deriveSchemaNameByConvention(schemaName);
11764
+ if (candidate && this.locateSchemaByConvention(candidate)) {
11765
+ this.typeToSchemaMapping[schemaName] = candidate;
11766
+ mappedSchemaName = candidate;
11767
+ }
11768
+ }
11744
11769
  if (mappedSchemaName) {
11745
11770
  logger.debug(`Type '${schemaName}' is mapped to schema '${mappedSchemaName}'`);
11746
11771
  schemaName = mappedSchemaName;
@@ -11790,7 +11815,7 @@ var ZodSchemaConverter = class {
11790
11815
  this.processingSchemas.delete(schemaName);
11791
11816
  if (mappedSchemaName && requestedSchemaName !== schemaName) {
11792
11817
  const resolvedReference = this.getSchemaReferenceName(schemaName, this.currentContentType);
11793
- if (this.zodSchemas[resolvedReference] && !this.zodSchemas[requestedSchemaName]) {
11818
+ if (!this.metaIdSchemaNames.has(requestedSchemaName) && this.zodSchemas[resolvedReference] && !this.zodSchemas[requestedSchemaName]) {
11794
11819
  this.zodSchemas[requestedSchemaName] = this.zodSchemas[resolvedReference];
11795
11820
  }
11796
11821
  this.schemaVariantRefs.set(this.getVariantKey(requestedSchemaName, this.currentContentType), this.zodSchemas[requestedSchemaName] ? requestedSchemaName : resolvedReference);
@@ -12247,6 +12272,8 @@ var ZodSchemaConverter = class {
12247
12272
  try {
12248
12273
  const content = this.fileAccess.readFileSync(filePath, "utf-8");
12249
12274
  const ast = parseTypeScriptFile(content);
12275
+ this.currentFilePath = filePath;
12276
+ this.currentAST = ast;
12250
12277
  resolvedTraverse(ast, {
12251
12278
  ExportNamedDeclaration: (path17) => {
12252
12279
  if (t10.isVariableDeclaration(path17.node.declaration)) {
@@ -12261,6 +12288,17 @@ var ZodSchemaConverter = class {
12261
12288
  }
12262
12289
  this.processingSchemas.delete(schemaName);
12263
12290
  }
12291
+ } else if (t10.isIdentifier(declaration.id) && declaration.init) {
12292
+ const schemaName = declaration.id.name;
12293
+ const overrideId = this.extractMetaIdFromNode(declaration.init);
12294
+ if (overrideId && !this.getStoredSchema(schemaName) && !this.processingSchemas.has(schemaName)) {
12295
+ this.processingSchemas.add(schemaName);
12296
+ const schema = this.processZodNode(declaration.init);
12297
+ this.processingSchemas.delete(schemaName);
12298
+ if (schema) {
12299
+ this.applyMetaIdOverride(schemaName, schema, overrideId, filePath);
12300
+ }
12301
+ }
12264
12302
  }
12265
12303
  });
12266
12304
  }
@@ -12814,6 +12852,24 @@ var ZodSchemaConverter = class {
12814
12852
  }
12815
12853
  return void 0;
12816
12854
  }
12855
+ extractMetaIdFromNode(node) {
12856
+ if (!t10.isCallExpression(node))
12857
+ return null;
12858
+ if (t10.isMemberExpression(node.callee) && t10.isIdentifier(node.callee.property)) {
12859
+ if (node.callee.property.name === "meta" && node.arguments.length > 0) {
12860
+ const metadata = this.extractStaticJsonValue(node.arguments[0]);
12861
+ if (metadata && typeof metadata === "object" && !Array.isArray(metadata)) {
12862
+ const id = metadata.id;
12863
+ if (typeof id === "string" && id.length > 0)
12864
+ return id;
12865
+ }
12866
+ }
12867
+ if (t10.isCallExpression(node.callee.object)) {
12868
+ return this.extractMetaIdFromNode(node.callee.object);
12869
+ }
12870
+ }
12871
+ return null;
12872
+ }
12817
12873
  shouldUseRuntimeExport(node) {
12818
12874
  if (!t10.isCallExpression(node)) {
12819
12875
  return false;
@@ -13054,7 +13110,8 @@ var ZodSchemaConverter = class {
13054
13110
  if (node.arguments.length > 0) {
13055
13111
  const metadata = this.extractStaticJsonValue(node.arguments[0]);
13056
13112
  if (metadata && typeof metadata === "object" && !Array.isArray(metadata)) {
13057
- Object.assign(schema, metadata);
13113
+ const { id: _id, ...rest } = metadata;
13114
+ Object.assign(schema, rest);
13058
13115
  }
13059
13116
  }
13060
13117
  break;
@@ -13340,6 +13397,7 @@ var ZodSchemaConverter = class {
13340
13397
  this.currentFilePath = filePath;
13341
13398
  this.currentAST = ast;
13342
13399
  this.currentImports = importedModules;
13400
+ this.preprocessedFiles.add(filePath);
13343
13401
  resolvedTraverse(ast, {
13344
13402
  ExportNamedDeclaration: (path17) => {
13345
13403
  if (t10.isVariableDeclaration(path17.node.declaration)) {
@@ -13347,15 +13405,19 @@ var ZodSchemaConverter = class {
13347
13405
  if (t10.isIdentifier(declaration.id) && declaration.init) {
13348
13406
  const schemaName = declaration.id.name;
13349
13407
  if (this.isZodSchema(declaration.init)) {
13350
- this.indexSchemaName(schemaName, filePath);
13351
13408
  if (!this.getStoredSchema(schemaName)) {
13352
13409
  logger.debug(`Pre-processing Zod schema: ${schemaName}`);
13353
13410
  this.processingSchemas.add(schemaName);
13354
13411
  const schema = this.processZodNode(declaration.init);
13412
+ this.processingSchemas.delete(schemaName);
13355
13413
  if (schema) {
13356
- this.storeResolvedSchema(schemaName, schema);
13414
+ const overrideId = this.extractMetaIdFromNode(declaration.init);
13415
+ this.applyMetaIdOverride(schemaName, schema, overrideId, filePath);
13416
+ } else {
13417
+ this.indexSchemaName(schemaName, filePath);
13357
13418
  }
13358
- this.processingSchemas.delete(schemaName);
13419
+ } else {
13420
+ this.indexSchemaName(schemaName, filePath);
13359
13421
  }
13360
13422
  }
13361
13423
  }
@@ -13368,22 +13430,25 @@ var ZodSchemaConverter = class {
13368
13430
  if (t10.isIdentifier(declaration.id) && declaration.init) {
13369
13431
  const schemaName = declaration.id.name;
13370
13432
  if (this.isZodSchema(declaration.init)) {
13371
- this.indexSchemaName(schemaName, filePath);
13372
13433
  if (!this.getStoredSchema(schemaName) && !this.processingSchemas.has(schemaName)) {
13373
13434
  logger.debug(`Pre-processing Zod schema: ${schemaName}`);
13374
13435
  this.processingSchemas.add(schemaName);
13375
13436
  const schema = this.processZodNode(declaration.init);
13437
+ this.processingSchemas.delete(schemaName);
13376
13438
  if (schema) {
13377
- this.storeResolvedSchema(schemaName, schema);
13439
+ const overrideId = this.extractMetaIdFromNode(declaration.init);
13440
+ this.applyMetaIdOverride(schemaName, schema, overrideId, filePath);
13441
+ } else {
13442
+ this.indexSchemaName(schemaName, filePath);
13378
13443
  }
13379
- this.processingSchemas.delete(schemaName);
13444
+ } else {
13445
+ this.indexSchemaName(schemaName, filePath);
13380
13446
  }
13381
13447
  }
13382
13448
  }
13383
13449
  });
13384
13450
  }
13385
13451
  });
13386
- this.preprocessedFiles.add(filePath);
13387
13452
  } catch (error2) {
13388
13453
  logger.error(`Error pre-processing file ${filePath}: ${error2}`);
13389
13454
  }
@@ -13401,6 +13466,63 @@ var ZodSchemaConverter = class {
13401
13466
  }
13402
13467
  bucket.add(filePath);
13403
13468
  }
13469
+ applyMetaIdOverride(schemaName, schema, overrideId, filePath) {
13470
+ const finalName = overrideId && overrideId !== schemaName ? overrideId : schemaName;
13471
+ this.indexSchemaName(schemaName, filePath);
13472
+ if (finalName !== schemaName) {
13473
+ this.indexSchemaName(finalName, filePath);
13474
+ }
13475
+ if (!this.zodSchemas[finalName]) {
13476
+ if (overrideId && overrideId !== schemaName) {
13477
+ this.typeToSchemaMapping[schemaName] = overrideId;
13478
+ this.metaIdSchemaNames.add(schemaName);
13479
+ if (this.typeToSchemaMapping[overrideId] === schemaName) {
13480
+ delete this.typeToSchemaMapping[overrideId];
13481
+ }
13482
+ }
13483
+ const variantKey = this.getVariantKey(finalName, this.currentContentType);
13484
+ this.zodSchemas[finalName] = schema;
13485
+ this.schemaVariantRefs.set(variantKey, finalName);
13486
+ } else {
13487
+ logger.warn(`Schema component name '${overrideId ?? finalName}' conflicts with an existing schema, ignoring .meta({ id }) on '${schemaName}'`);
13488
+ }
13489
+ }
13490
+ /**
13491
+ * Derives the conventional Zod schema name from a TypeScript type name.
13492
+ * e.g. "Slider" → "sliderSchema", "SliderItem" → "sliderItemSchema".
13493
+ * Returns null when the input is already a schema name or is not PascalCase.
13494
+ */
13495
+ deriveSchemaNameByConvention(typeName) {
13496
+ if (!typeName || !/^[A-Z]/.test(typeName) || typeName.endsWith("Schema")) {
13497
+ return null;
13498
+ }
13499
+ return typeName[0].toLowerCase() + typeName.slice(1) + "Schema";
13500
+ }
13501
+ /**
13502
+ * Checks whether a Zod schema with the given name is present in schemaDirs
13503
+ * WITHOUT populating the processed-schema cache. A file-content substring check
13504
+ * (the same heuristic used by processFileForZodSchema) is sufficient here: we
13505
+ * only want to know whether the candidate *might* live in schemaDirs so that the
13506
+ * convention mapping can be registered; the actual processing happens later in
13507
+ * the normal convertZodSchemaToOpenApi lookup flow.
13508
+ */
13509
+ locateSchemaByConvention(candidate) {
13510
+ if (this.schemaNameToFiles.has(candidate)) {
13511
+ return true;
13512
+ }
13513
+ for (const dir of this.schemaDirs) {
13514
+ for (const filePath of this.getSchemaFiles(dir)) {
13515
+ try {
13516
+ const content = this.fileAccess.readFileSync(filePath, "utf-8");
13517
+ if (content.includes(candidate)) {
13518
+ return true;
13519
+ }
13520
+ } catch {
13521
+ }
13522
+ }
13523
+ }
13524
+ return false;
13525
+ }
13404
13526
  /**
13405
13527
  * Check if node is Zod schema
13406
13528
  */
@@ -13632,7 +13754,7 @@ function parsePropertyComment(commentValue) {
13632
13754
  function getPropertyOptions(node, contentType) {
13633
13755
  const isOptional = !!node.optional;
13634
13756
  const options = {};
13635
- const leadingComment = node.leadingComments?.[node.leadingComments.length - 1];
13757
+ const leadingComment = node.leadingComments?.findLast((c) => c.type === "CommentBlock" || !node.trailingComments?.length);
13636
13758
  const trailingComment = node.trailingComments?.[0];
13637
13759
  const sourceComment = leadingComment ?? trailingComment;
13638
13760
  if (sourceComment) {
@@ -14035,31 +14157,60 @@ function resolveImportPath(importPath, fromFilePath, fileAccess) {
14035
14157
  }
14036
14158
  return null;
14037
14159
  }
14038
- function collectAllExportedDefinitions(ast, typeDefinitions, currentFile) {
14160
+ function collectFirstMemberLeadingComments(interfaceDecl) {
14161
+ const body = interfaceDecl?.body;
14162
+ if (!body)
14163
+ return [];
14164
+ const firstMember = body.body?.[0];
14165
+ return firstMember?.leadingComments ?? [];
14166
+ }
14167
+ function collectAllExportedDefinitions(ast, typeDefinitions, currentFile, schemaIdAliases) {
14168
+ function registerDefinition(name, entry, allComments) {
14169
+ if (!typeDefinitions[name]) {
14170
+ typeDefinitions[name] = entry;
14171
+ }
14172
+ const overrideId = extractSchemaIdFromComments(allComments);
14173
+ if (overrideId && schemaIdAliases) {
14174
+ schemaIdAliases[name] = overrideId;
14175
+ if (!typeDefinitions[overrideId]) {
14176
+ typeDefinitions[overrideId] = entry;
14177
+ }
14178
+ }
14179
+ }
14039
14180
  resolvedTraverse(ast, {
14040
14181
  TSTypeAliasDeclaration: (path17) => {
14041
14182
  if (path17.node.id && t12.isIdentifier(path17.node.id)) {
14042
14183
  const name = path17.node.id.name;
14043
- if (!typeDefinitions[name]) {
14044
- const node = path17.node.typeParameters && path17.node.typeParameters.params.length > 0 ? path17.node : path17.node.typeAnnotation;
14045
- typeDefinitions[name] = { node, filePath: currentFile };
14046
- }
14184
+ const node = path17.node.typeParameters && path17.node.typeParameters.params.length > 0 ? path17.node : path17.node.typeAnnotation;
14185
+ const allComments = [
14186
+ ...path17.parentPath?.node?.leadingComments ?? [],
14187
+ ...path17.node.leadingComments ?? [],
14188
+ ...path17.node.trailingComments ?? []
14189
+ ];
14190
+ registerDefinition(name, { node, filePath: currentFile }, allComments);
14047
14191
  }
14048
14192
  },
14049
14193
  TSInterfaceDeclaration: (path17) => {
14050
14194
  if (path17.node.id && t12.isIdentifier(path17.node.id)) {
14051
14195
  const name = path17.node.id.name;
14052
- if (!typeDefinitions[name]) {
14053
- typeDefinitions[name] = { node: path17.node, filePath: currentFile };
14054
- }
14196
+ const allComments = [
14197
+ ...path17.parentPath?.node?.leadingComments ?? [],
14198
+ ...path17.node.leadingComments ?? [],
14199
+ ...path17.node.trailingComments ?? [],
14200
+ ...collectFirstMemberLeadingComments(path17.node)
14201
+ ];
14202
+ registerDefinition(name, { node: path17.node, filePath: currentFile }, allComments);
14055
14203
  }
14056
14204
  },
14057
14205
  TSEnumDeclaration: (path17) => {
14058
14206
  if (path17.node.id && t12.isIdentifier(path17.node.id)) {
14059
14207
  const name = path17.node.id.name;
14060
- if (!typeDefinitions[name]) {
14061
- typeDefinitions[name] = { node: path17.node, filePath: currentFile };
14062
- }
14208
+ const allComments = [
14209
+ ...path17.parentPath?.node?.leadingComments ?? [],
14210
+ ...path17.node.leadingComments ?? [],
14211
+ ...path17.node.trailingComments ?? []
14212
+ ];
14213
+ registerDefinition(name, { node: path17.node, filePath: currentFile }, allComments);
14063
14214
  }
14064
14215
  },
14065
14216
  ExportNamedDeclaration: (path17) => {
@@ -14067,19 +14218,26 @@ function collectAllExportedDefinitions(ast, typeDefinitions, currentFile) {
14067
14218
  const interfaceDecl = path17.node.declaration;
14068
14219
  if (interfaceDecl.id && t12.isIdentifier(interfaceDecl.id)) {
14069
14220
  const name = interfaceDecl.id.name;
14070
- if (!typeDefinitions[name]) {
14071
- typeDefinitions[name] = { node: interfaceDecl, filePath: currentFile };
14072
- }
14221
+ const allComments = [
14222
+ ...path17.node.leadingComments ?? [],
14223
+ ...interfaceDecl.leadingComments ?? [],
14224
+ ...interfaceDecl.trailingComments ?? [],
14225
+ ...collectFirstMemberLeadingComments(interfaceDecl)
14226
+ ];
14227
+ registerDefinition(name, { node: interfaceDecl, filePath: currentFile }, allComments);
14073
14228
  }
14074
14229
  }
14075
14230
  if (t12.isTSTypeAliasDeclaration(path17.node.declaration)) {
14076
14231
  const typeDecl = path17.node.declaration;
14077
14232
  if (typeDecl.id && t12.isIdentifier(typeDecl.id)) {
14078
14233
  const name = typeDecl.id.name;
14079
- if (!typeDefinitions[name]) {
14080
- const node = typeDecl.typeParameters && typeDecl.typeParameters.params.length > 0 ? typeDecl : typeDecl.typeAnnotation;
14081
- typeDefinitions[name] = { node, filePath: currentFile };
14082
- }
14234
+ const node = typeDecl.typeParameters && typeDecl.typeParameters.params.length > 0 ? typeDecl : typeDecl.typeAnnotation;
14235
+ const allComments = [
14236
+ ...path17.node.leadingComments ?? [],
14237
+ ...typeDecl.leadingComments ?? [],
14238
+ ...typeDecl.trailingComments ?? []
14239
+ ];
14240
+ registerDefinition(name, { node, filePath: currentFile }, allComments);
14083
14241
  }
14084
14242
  }
14085
14243
  }
@@ -14496,6 +14654,7 @@ var SchemaProcessor = class {
14496
14654
  zodSchemaProcessor = null;
14497
14655
  schemaTypes;
14498
14656
  isResolvingPickOmitBase = false;
14657
+ schemaIdAliases = {};
14499
14658
  fileAccess;
14500
14659
  symbolResolver;
14501
14660
  // Track imports per file for resolving ReturnType<typeof func>
@@ -14536,7 +14695,7 @@ var SchemaProcessor = class {
14536
14695
  getDefinedSchemas() {
14537
14696
  const filteredSchemas = {};
14538
14697
  Object.entries(this.openapiDefinitions).forEach(([key, value]) => {
14539
- if (!this.isGenericTypeParameter(key) && !this.isInvalidSchemaName(key) && !this.isBuiltInUtilityType(key) && !this.isFunctionSchema(key)) {
14698
+ if (!this.schemaIdAliases[key] && !this.isGenericTypeParameter(key) && !this.isInvalidSchemaName(key) && !this.isBuiltInUtilityType(key) && !this.isFunctionSchema(key)) {
14540
14699
  filteredSchemas[key] = value;
14541
14700
  }
14542
14701
  });
@@ -14551,6 +14710,10 @@ var SchemaProcessor = class {
14551
14710
  if (schemaName.includes("<") && schemaName.includes(">")) {
14552
14711
  return this.resolveGenericTypeFromString(schemaName);
14553
14712
  }
14713
+ const overrideId = this.schemaIdAliases[schemaName];
14714
+ if (overrideId) {
14715
+ return this.findSchemaDefinition(overrideId, contentType);
14716
+ }
14554
14717
  if (this.openapiDefinitions[schemaName]) {
14555
14718
  return this.openapiDefinitions[schemaName];
14556
14719
  }
@@ -14632,6 +14795,7 @@ var SchemaProcessor = class {
14632
14795
  return;
14633
14796
  }
14634
14797
  this.collectImports(ast, filePath);
14798
+ const aliasesBeforeFile = new Set(Object.keys(this.schemaIdAliases));
14635
14799
  this.collectAllExportedDefinitions(ast, filePath);
14636
14800
  collectTopLevelDefinitionNames(ast).forEach((name) => {
14637
14801
  const indexedFiles = this.schemaDefinitionIndex[name];
@@ -14643,6 +14807,16 @@ var SchemaProcessor = class {
14643
14807
  }
14644
14808
  this.schemaDefinitionIndex[name] = [filePath];
14645
14809
  });
14810
+ Object.entries(this.schemaIdAliases).forEach(([originalName, aliasName]) => {
14811
+ if (aliasesBeforeFile.has(originalName))
14812
+ return;
14813
+ if (!this.schemaDefinitionIndex[aliasName]) {
14814
+ this.schemaDefinitionIndex[aliasName] = [];
14815
+ }
14816
+ if (!this.schemaDefinitionIndex[aliasName].includes(filePath)) {
14817
+ this.schemaDefinitionIndex[aliasName].push(filePath);
14818
+ }
14819
+ });
14646
14820
  }
14647
14821
  getParsedSchemaFile(filePath) {
14648
14822
  const cachedAst = this.fileASTCache.get(filePath);
@@ -14681,7 +14855,7 @@ var SchemaProcessor = class {
14681
14855
  * Used when processing imported files to ensure all referenced types are available
14682
14856
  */
14683
14857
  collectAllExportedDefinitions(ast, filePath) {
14684
- collectAllExportedDefinitions(ast, this.typeDefinitions, filePath || this.currentFilePath);
14858
+ collectAllExportedDefinitions(ast, this.typeDefinitions, filePath || this.currentFilePath, this.schemaIdAliases);
14685
14859
  }
14686
14860
  collectTypeDefinitions(ast, schemaName, filePath) {
14687
14861
  collectTypeDefinitions(ast, schemaName, this.typeDefinitions, filePath || this.currentFilePath);
@@ -15278,6 +15452,9 @@ var SchemaProcessor = class {
15278
15452
  logger.debug(`Record<...> used with ${node.typeParameters?.params.length ?? 0} type parameters; expected 2`);
15279
15453
  return { type: "object", additionalProperties: true };
15280
15454
  }
15455
+ if ((!node.typeParameters || node.typeParameters.params.length === 0) && this.schemaIdAliases[typeName] && this.openapiDefinitions[this.schemaIdAliases[typeName]]) {
15456
+ return { $ref: `#/components/schemas/${this.schemaIdAliases[typeName]}` };
15457
+ }
15281
15458
  const utilityType = resolveUtilityTypeReference(node, {
15282
15459
  currentFilePath: this.currentFilePath,
15283
15460
  contentType: this.contentType,
@@ -15453,7 +15630,9 @@ var SchemaProcessor = class {
15453
15630
  };
15454
15631
  }
15455
15632
  if (t15.isTSTypeReference(node) && t15.isIdentifier(node.typeName)) {
15456
- return { $ref: `#/components/schemas/${node.typeName.name}` };
15633
+ const refName = node.typeName.name;
15634
+ const aliasedName = this.schemaIdAliases[refName] ?? refName;
15635
+ return { $ref: `#/components/schemas/${aliasedName}` };
15457
15636
  }
15458
15637
  logger.debug("Unrecognized TypeScript type node:", node);
15459
15638
  return { type: "object" };
@@ -15594,7 +15773,8 @@ var SchemaProcessor = class {
15594
15773
  if (this.schemaTypes.includes("zod") && this.zodSchemaConverter) {
15595
15774
  return this.zodSchemaConverter.getSchemaReferenceName(baseTypeName, contentType);
15596
15775
  }
15597
- return baseTypeName;
15776
+ const aliasedName = this.schemaIdAliases[baseTypeName] ?? baseTypeName;
15777
+ return aliasedName;
15598
15778
  }
15599
15779
  /**
15600
15780
  * Parse and resolve a generic type from a string like "MyApiSuccessResponseBody<LLMSResponse>"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-openapi-gen",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "Automatically generate OpenAPI 3.0, 3.1, and 3.2 documentation from Next.js projects, with support for Zod schemas, TypeScript types, and reusable OpenAPI fragments.",
5
5
  "keywords": [
6
6
  "api",