next-openapi-gen 0.6.7 → 0.6.9

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
@@ -1,13 +1,13 @@
1
1
  # next-openapi-gen
2
2
 
3
- Automatically generate OpenAPI 3.0 documentation from Next.js projects, with support for TypeScript types and Zod schemas.
3
+ Automatically generate OpenAPI 3.0 documentation from Next.js projects, with support for Zod schemas and TypeScript types.
4
4
 
5
5
  ## Features
6
6
 
7
7
  - ✅ Automatic OpenAPI documentation generation from Next.js code
8
8
  - ✅ Support for Next.js App Router (including `/api/users/[id]/route.ts` routes)
9
- - ✅ TypeScript types support
10
9
  - ✅ Zod schemas support
10
+ - ✅ TypeScript types support
11
11
  - ✅ JSDoc comments support
12
12
  - ✅ Multiple UI interfaces: `Scalar`, `Swagger`, `Redoc`, `Stoplight` and `Rapidoc` available at `/api-docs` url
13
13
  - ✅ Path parameters detection (`/users/{id}`)
@@ -32,7 +32,7 @@ npm install next-openapi-gen --save-dev
32
32
 
33
33
  ```bash
34
34
  # Initialize OpenAPI configuration
35
- npx next-openapi-gen init --ui scalar --docs-url api-docs
35
+ npx next-openapi-gen init --ui scalar --docs-url api-docs --schema zod
36
36
 
37
37
  # Generate OpenAPI documentation
38
38
  npx next-openapi-gen generate
@@ -58,7 +58,7 @@ During initialization (`npx next-openapi-gen init`), a configuration file `next.
58
58
  ],
59
59
  "apiDir": "src/app/api",
60
60
  "schemaDir": "src/types", // or "src/schemas" for Zod schemas
61
- "schemaType": "typescript", // or "zod" for Zod schemas
61
+ "schemaType": "zod", // or "typescript" for TypeScript types
62
62
  "outputFile": "openapi.json",
63
63
  "docsUrl": "/api-docs",
64
64
  "includeOpenApiRoutes": false,
@@ -72,7 +72,7 @@ During initialization (`npx next-openapi-gen init`), a configuration file `next.
72
72
  | ---------------------- | ------------------------------------------------ |
73
73
  | `apiDir` | Path to the API directory |
74
74
  | `schemaDir` | Path to the types/schemas directory |
75
- | `schemaType` | Schema type: `"typescript"` or `"zod"` |
75
+ | `schemaType` | Schema type: `"zod"` or `"typescript"` |
76
76
  | `outputFile` | Path to the OpenAPI output file |
77
77
  | `docsUrl` | API documentation URL (for Swagger UI) |
78
78
  | `includeOpenApiRoutes` | Whether to include only routes with @openapi tag |
@@ -83,28 +83,29 @@ During initialization (`npx next-openapi-gen init`), a configuration file `next.
83
83
 
84
84
  ## Documenting Your API
85
85
 
86
- ### With TypeScript Types
86
+ ### With Zod Schemas
87
87
 
88
88
  ```typescript
89
- // src/app/api/users/[id]/route.ts
89
+ // src/app/api/products/[id]/route.ts
90
90
 
91
91
  import { NextRequest, NextResponse } from "next/server";
92
+ import { z } from "zod";
92
93
 
93
- type UserParams = {
94
- id: string; // User ID
95
- };
94
+ export const ProductParams = z.object({
95
+ id: z.string().describe("Product ID"),
96
+ });
96
97
 
97
- type UserResponse = {
98
- id: string; // User ID
99
- name: string; // Full name
100
- email: string; // Email address
101
- };
98
+ export const ProductResponse = z.object({
99
+ id: z.string().describe("Product ID"),
100
+ name: z.string().describe("Product name"),
101
+ price: z.number().positive().describe("Product price"),
102
+ });
102
103
 
103
104
  /**
104
- * Get user information
105
- * @description Fetches detailed user information by ID
106
- * @pathParams UserParams
107
- * @response UserResponse
105
+ * Get product information
106
+ * @description Fetches detailed product information by ID
107
+ * @pathParams ProductParams
108
+ * @response ProductResponse
108
109
  * @openapi
109
110
  */
110
111
  export async function GET(
@@ -115,29 +116,28 @@ export async function GET(
115
116
  }
116
117
  ```
117
118
 
118
- ### With Zod Schemas
119
+ ### With TypeScript Types
119
120
 
120
121
  ```typescript
121
- // src/app/api/products/[id]/route.ts
122
+ // src/app/api/users/[id]/route.ts
122
123
 
123
124
  import { NextRequest, NextResponse } from "next/server";
124
- import { z } from "zod";
125
125
 
126
- export const ProductParams = z.object({
127
- id: z.string().describe("Product ID"),
128
- });
126
+ type UserParams = {
127
+ id: string; // User ID
128
+ };
129
129
 
130
- export const ProductResponse = z.object({
131
- id: z.string().describe("Product ID"),
132
- name: z.string().describe("Product name"),
133
- price: z.number().positive().describe("Product price"),
134
- });
130
+ type UserResponse = {
131
+ id: string; // User ID
132
+ name: string; // Full name
133
+ email: string; // Email address
134
+ };
135
135
 
136
136
  /**
137
- * Get product information
138
- * @description Fetches detailed product information by ID
139
- * @pathParams ProductParams
140
- * @response ProductResponse
137
+ * Get user information
138
+ * @description Fetches detailed user information by ID
139
+ * @pathParams UserParams
140
+ * @response UserResponse
141
141
  * @openapi
142
142
  */
143
143
  export async function GET(
@@ -178,8 +178,9 @@ npx next-openapi-gen init
178
178
  This command will generate following elements:
179
179
 
180
180
  - Generate `next.openapi.json` configuration file
181
- - Install UI interface (default `Scalar`)
181
+ - Set up `Scalar` UI for documentation display
182
182
  - Add `/api-docs` page to display OpenAPI documentation
183
+ - Configure `zod` as the default schema tool
183
184
 
184
185
  ### 2. Generate Documentation
185
186
 
@@ -192,7 +193,7 @@ This command will generate OpenAPI documentation based on your API code:
192
193
  - Scan API directories for routes
193
194
  - Analyze types/schemas
194
195
  - Generate OpenAPI file (`openapi.json`) in `public` folder
195
- - Create Swagger/Scalar UI endpoint and page (if enabled)
196
+ - Create Scalar/Swagger UI endpoint and page (if enabled)
196
197
 
197
198
  ### 3. View API Documentation
198
199
 
@@ -205,16 +206,16 @@ To see API documenation go to `http://localhost:3000/api-docs`
205
206
  ```typescript
206
207
  // src/app/api/users/[id]/route.ts
207
208
 
208
- // TypeScript
209
- type UserParams = {
210
- id: string; // User ID
211
- };
212
-
213
- // Or Zod
209
+ // Zod
214
210
  const UserParams = z.object({
215
211
  id: z.string().describe("User ID"),
216
212
  });
217
213
 
214
+ // Or TypeScript
215
+ type UserParams = {
216
+ id: string; // User ID
217
+ };
218
+
218
219
  /**
219
220
  * @pathParams UserParams
220
221
  */
@@ -228,20 +229,20 @@ export async function GET() {
228
229
  ```typescript
229
230
  // src/app/api/users/route.ts
230
231
 
231
- // TypeScript
232
- type UsersQueryParams = {
233
- page?: number; // Page number
234
- limit?: number; // Results per page
235
- search?: string; // Search phrase
236
- };
237
-
238
- // Or Zod
232
+ // Zod
239
233
  const UsersQueryParams = z.object({
240
234
  page: z.number().optional().describe("Page number"),
241
235
  limit: z.number().optional().describe("Results per page"),
242
236
  search: z.string().optional().describe("Search phrase"),
243
237
  });
244
238
 
239
+ // Or TypeScript
240
+ type UsersQueryParams = {
241
+ page?: number; // Page number
242
+ limit?: number; // Results per page
243
+ search?: string; // Search phrase
244
+ };
245
+
245
246
  /**
246
247
  * @params UsersQueryParams
247
248
  */
@@ -255,20 +256,20 @@ export async function GET() {
255
256
  ```typescript
256
257
  // src/app/api/users/route.ts
257
258
 
258
- // TypeScript
259
- type CreateUserBody = {
260
- name: string; // Full name
261
- email: string; // Email address
262
- password: string; // Password
263
- };
264
-
265
- // Or Zod
259
+ // Zod
266
260
  const CreateUserBody = z.object({
267
261
  name: z.string().describe("Full name"),
268
262
  email: z.string().email().describe("Email address"),
269
263
  password: z.string().min(8).describe("Password"),
270
264
  });
271
265
 
266
+ // Or TypeScript
267
+ type CreateUserBody = {
268
+ name: string; // Full name
269
+ email: string; // Email address
270
+ password: string; // Password
271
+ };
272
+
272
273
  /**
273
274
  * @body CreateUserBody
274
275
  * @bodyDescription User registration data including email and password
@@ -283,15 +284,7 @@ export async function POST() {
283
284
  ```typescript
284
285
  // src/app/api/users/route.ts
285
286
 
286
- // TypeScript
287
- type UserResponse = {
288
- id: string; // User ID
289
- name: string; // Full name
290
- email: string; // Email address
291
- createdAt: Date; // Creation date
292
- };
293
-
294
- // Or Zod
287
+ // Zod
295
288
  const UserResponse = z.object({
296
289
  id: z.string().describe("User ID"),
297
290
  name: z.string().describe("Full name"),
@@ -299,6 +292,14 @@ const UserResponse = z.object({
299
292
  createdAt: z.date().describe("Creation date"),
300
293
  });
301
294
 
295
+ // Or TypeScript
296
+ type UserResponse = {
297
+ id: string; // User ID
298
+ name: string; // Full name
299
+ email: string; // Email address
300
+ createdAt: Date; // Creation date
301
+ };
302
+
302
303
  /**
303
304
  * @response UserResponse
304
305
  * @responseDescription Returns newly created user object
@@ -326,7 +327,15 @@ export async function GET() {
326
327
  ```typescript
327
328
  // src/app/api/v1/route.ts
328
329
 
329
- // TypeScript
330
+ // Zod
331
+ const UserSchema = z.object({
332
+ id: z.string(),
333
+ name: z.string(),
334
+ fullName: z.string().optional().describe("@deprecated Use name instead"),
335
+ email: z.string().email(),
336
+ });
337
+
338
+ // Or TypeScript
330
339
  type UserResponse = {
331
340
  id: string;
332
341
  name: string;
@@ -335,14 +344,6 @@ type UserResponse = {
335
344
  email: string;
336
345
  };
337
346
 
338
- // Or Zod
339
- const UserSchema = z.object({
340
- id: z.string(),
341
- name: z.string(),
342
- fullName: z.string().optional().describe("@deprecated Use name instead"),
343
- email: z.string().email(),
344
- });
345
-
346
347
  /**
347
348
  * @body UserSchema
348
349
  * @response UserResponse
@@ -357,20 +358,20 @@ export async function GET() {
357
358
  ```typescript
358
359
  // src/app/api/upload/route.ts
359
360
 
360
- // TypeScript
361
- type FileUploadFormData = {
362
- file: File;
363
- description?: string;
364
- category: string;
365
- };
366
-
367
- // Or Zod
361
+ // Zod
368
362
  const FileUploadSchema = z.object({
369
363
  file: z.custom<File>().describe("Image file (PNG/JPG)"),
370
364
  description: z.string().optional().describe("File description"),
371
365
  category: z.string().describe("File category"),
372
366
  });
373
367
 
368
+ // Or TypeScript
369
+ type FileUploadFormData = {
370
+ file: File;
371
+ description?: string;
372
+ category: string;
373
+ };
374
+
374
375
  /**
375
376
  * @body FileUploadSchema
376
377
  * @contentType multipart/form-data
@@ -92,14 +92,15 @@ async function installDependencies(ui) {
92
92
  function extendOpenApiTemplate(spec, options) {
93
93
  spec.ui = options.ui ?? spec.ui;
94
94
  spec.docsUrl = options.docsUrl ?? spec.docsUrl;
95
+ spec.schemaType = options.schema ?? spec.schemaType;
95
96
  }
96
97
  export async function init(options) {
97
- const { ui, docsUrl } = options;
98
+ const { ui } = options;
98
99
  spinner.start();
99
100
  try {
100
101
  const outputPath = path.join(process.cwd(), "next.openapi.json");
101
102
  const template = { ...openapiTemplate };
102
- extendOpenApiTemplate(template, { docsUrl, ui });
103
+ extendOpenApiTemplate(template, options);
103
104
  await fse.writeJson(outputPath, template, { spaces: 2 });
104
105
  spinner.succeed(`Created OpenAPI template in next.openapi.json`);
105
106
  createDocsPage(ui, template.outputFile);
@@ -1,20 +1,20 @@
1
1
  export const rapidocDeps = ["rapidoc"];
2
2
  export function RapidocUI(outputFile) {
3
- return `
4
- "use client";
5
-
6
- import "rapidoc";
7
-
8
- export default function ApiDocsPage() {
9
- return (
10
- <section style={{ height: "100vh" }}>
11
- <rapi-doc
12
- spec-url="${outputFile}"
13
- render-style="read"
14
- style={{ height: "100vh", width: "100%" }}
15
- ></rapi-doc>
16
- </section>
17
- );
18
- }
3
+ return `
4
+ "use client";
5
+
6
+ import "rapidoc";
7
+
8
+ export default function ApiDocsPage() {
9
+ return (
10
+ <section style={{ height: "100vh" }}>
11
+ <rapi-doc
12
+ spec-url="${outputFile}"
13
+ render-style="read"
14
+ style={{ height: "100vh", width: "100%" }}
15
+ ></rapi-doc>
16
+ </section>
17
+ );
18
+ }
19
19
  `;
20
20
  }
@@ -1,16 +1,16 @@
1
1
  export const redocDeps = ["redoc"];
2
2
  export function RedocUI(outputFile) {
3
- return `
4
- "use client";
5
-
6
- import { RedocStandalone } from "redoc";
7
-
8
- export default async function ApiDocsPage() {
9
- return (
10
- <section>
11
- <RedocStandalone specUrl="/${outputFile}" />
12
- </section>
13
- );
14
- }
3
+ return `
4
+ "use client";
5
+
6
+ import { RedocStandalone } from "redoc";
7
+
8
+ export default async function ApiDocsPage() {
9
+ return (
10
+ <section>
11
+ <RedocStandalone specUrl="/${outputFile}" />
12
+ </section>
13
+ );
14
+ }
15
15
  `;
16
16
  }
@@ -1,17 +1,17 @@
1
1
  export const stoplightDeps = ["@stoplight/elements"];
2
2
  export function StoplightUI(outputFile) {
3
- return `
4
- "use client";
5
-
6
- import { API } from "@stoplight/elements";
7
- import "@stoplight/elements/styles.min.css";
8
-
9
- export default function ApiDocsPage() {
10
- return (
11
- <section style={{ height: "100vh" }}>
12
- <API apiDescriptionUrl="${outputFile}" />
13
- </section>
14
- );
15
- }
3
+ return `
4
+ "use client";
5
+
6
+ import { API } from "@stoplight/elements";
7
+ import "@stoplight/elements/styles.min.css";
8
+
9
+ export default function ApiDocsPage() {
10
+ return (
11
+ <section style={{ height: "100vh" }}>
12
+ <API apiDescriptionUrl="${outputFile}" />
13
+ </section>
14
+ );
15
+ }
16
16
  `;
17
17
  }
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ import { generate } from "./commands/generate.js";
5
5
  const program = new Command();
6
6
  program
7
7
  .name("next-openapi-gen")
8
- .version("0.0.1")
8
+ .version("0.6.7")
9
9
  .description("Super fast and easy way to generate OpenAPI documentation for Next.js");
10
10
  program
11
11
  .command("init")
@@ -13,6 +13,9 @@ program
13
13
  .choices(["scalar", "swagger", "redoc", "stoplight", "rapidoc"])
14
14
  .default("swagger"))
15
15
  .option("-u, --docs-url <url>", "Specify the docs URL", "api-docs")
16
+ .addOption(new Option("-s, --schema <schemaType>", "Specify the schema tool")
17
+ .choices(["zod", "typescript"])
18
+ .default("zod"))
16
19
  .description("Initialize a openapi specification")
17
20
  .action(init);
18
21
  program
@@ -65,7 +65,7 @@ export default {
65
65
  },
66
66
  apiDir: "./src/app/api",
67
67
  schemaDir: "./src",
68
- schemaType: "typescript",
68
+ schemaType: "zod",
69
69
  docsUrl: "api-docs",
70
70
  ui: "scalar",
71
71
  outputFile: "openapi.json",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "next-openapi-gen",
3
- "version": "0.6.7",
4
- "description": "Automatically generate OpenAPI 3.0 documentation from Next.js projects, with support for TypeScript types and Zod schemas.",
3
+ "version": "0.6.9",
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",
7
7
  "module": "dist/index.mjs",