next-openapi-gen 0.8.6 → 0.8.8

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/README.md CHANGED
@@ -201,6 +201,7 @@ export async function POST(request: NextRequest) {
201
201
  | Tag | Description |
202
202
  | ---------------------- | ------------------------------------------------------------------------------------------------------------------------ |
203
203
  | `@description` | Endpoint description |
204
+ | `@operationId` | Custom operation ID (overrides auto-generated ID) |
204
205
  | `@pathParams` | Path parameters type/schema |
205
206
  | `@params` | Query parameters type/schema |
206
207
  | `@body` | Request body type/schema |
@@ -424,6 +425,23 @@ export async function GET() {
424
425
  }
425
426
  ```
426
427
 
428
+ ### Custom Operation ID
429
+
430
+ ```typescript
431
+ // src/app/api/users/[id]/route.ts
432
+
433
+ /**
434
+ * Get user by ID
435
+ * @operationId getUserById
436
+ * @pathParams UserParams
437
+ * @response UserResponse
438
+ */
439
+ export async function GET() {
440
+ // ...
441
+ }
442
+ // Generates: operationId: "getUserById" instead of auto-generated "get-users-{id}"
443
+ ```
444
+
427
445
  ### File Uploads / Multipart Form Data
428
446
 
429
447
  ```typescript
@@ -248,7 +248,7 @@ export class RouteProcessor {
248
248
  const method = varName.toLowerCase();
249
249
  const routePath = this.getRoutePath(filePath);
250
250
  const rootPath = capitalize(routePath.split("/")[1]);
251
- const operationId = getOperationId(routePath, method);
251
+ const operationId = dataTypes.operationId || getOperationId(routePath, method);
252
252
  const { tag, summary, description, auth, isOpenApi, deprecated, bodyDescription, responseDescription, } = dataTypes;
253
253
  if (this.config.includeOpenApiRoutes && !isOpenApi) {
254
254
  // If flag is enabled and there is no @openapi tag, then skip path
package/dist/lib/utils.js CHANGED
@@ -34,6 +34,7 @@ export function extractJSDocComments(path) {
34
34
  let responseSet = "";
35
35
  let addResponses = "";
36
36
  let successCode = "";
37
+ let operationId = "";
37
38
  if (comments) {
38
39
  comments.forEach((comment) => {
39
40
  const commentValue = cleanComment(comment.value);
@@ -124,6 +125,13 @@ export function extractJSDocComments(path) {
124
125
  addResponses = match[1].trim();
125
126
  }
126
127
  }
128
+ if (commentValue.includes("@operationId")) {
129
+ const regex = /@operationId\s+(\S+)/;
130
+ const match = commentValue.match(regex);
131
+ if (match && match[1]) {
132
+ operationId = match[1].trim();
133
+ }
134
+ }
127
135
  if (commentValue.includes("@response")) {
128
136
  // Updated regex to support generic types
129
137
  const responseMatch = commentValue.match(/@response\s+(?:(\d+):)?([^@\n\r]+)(?:\s+(.*))?/);
@@ -156,6 +164,7 @@ export function extractJSDocComments(path) {
156
164
  responseSet,
157
165
  addResponses,
158
166
  successCode,
167
+ operationId,
159
168
  };
160
169
  }
161
170
  export function extractTypeFromComment(commentValue, tag) {
@@ -700,6 +700,16 @@ export class ZodSchemaConverter {
700
700
  }
701
701
  logger.debug(`[processZodNode] Could not expand factory function '${node.callee.name}' - missing context or not a factory`);
702
702
  }
703
+ // Handle standalone identifier references (e.g., userSchema used directly)
704
+ if (t.isIdentifier(node)) {
705
+ const schemaName = node.name;
706
+ // Try to find and process the referenced schema
707
+ if (!this.zodSchemas[schemaName]) {
708
+ this.convertZodSchemaToOpenApi(schemaName);
709
+ }
710
+ // Return a reference to the schema
711
+ return { $ref: `#/components/schemas/${schemaName}` };
712
+ }
703
713
  logger.debug("Unknown Zod schema node:", node);
704
714
  return { type: "object" };
705
715
  }
@@ -932,6 +942,7 @@ export class ZodSchemaConverter {
932
942
  $ref: `#/components/schemas/${referencedSchemaName}`,
933
943
  };
934
944
  required.push(propName); // Assuming it's required unless marked optional
945
+ return; // Skip further processing for this property
935
946
  }
936
947
  // For array of schemas (like z.array(PaymentMethodSchema))
937
948
  if (t.isCallExpression(prop.value) &&
@@ -957,6 +968,7 @@ export class ZodSchemaConverter {
957
968
  if (!isOptional) {
958
969
  required.push(propName);
959
970
  }
971
+ return; // Skip further processing for this property
960
972
  }
961
973
  // Process property value (a Zod schema)
962
974
  const propSchema = this.processZodNode(prop.value);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-openapi-gen",
3
- "version": "0.8.6",
3
+ "version": "0.8.8",
4
4
  "description": "Automatically generate OpenAPI 3.0 documentation from Next.js projects, with support for Zod schemas and TypeScript types.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",