next-openapi-gen 0.0.15 → 0.0.18

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,125 +1,155 @@
1
- # next-openapi-gen
2
-
3
- **next-openapi-gen** super fast and easy way to generate OpenAPI 3.0 documentation automatically from API routes in a Next.js 14.
4
-
5
- With support for multiple user interfaces next-openapi-gen makes documenting your API a breeze!
6
-
7
- ## Prerequisites
8
-
9
- - Nextjs >= 14
10
- - Node >= 18
11
-
12
- ## Supported interfaces
13
-
14
- - Swagger
15
- - Redoc
16
- - Stoplight Elements
17
- - RapiDoc
18
-
19
- ## Features
20
-
21
- - **Automatic OpenAPI Generation**: Generate OpenAPI 3.0 documentation from your Next.js routes, automatically parsing TypeScript types for parameters, request bodies and responses.
22
- - **TypeScript Type Scanning**: Automatically resolve TypeScript types for params, body, and responses based on your API endpoint's TypeScript definitions. Field comments in TypeScript types are reflected as descriptions in the OpenAPI schema.
23
- - **JSDoc-Based Documentation (Optional)**: Document API routes with JSDoc comments, including tags like `@openapi`, `@auth`, `@desc`, `@params`, `@body`, and `@response` to easily define route metadata.
24
- - **UI Interface Options**: Choose between `Swagger UI`, `Redoc`, `Stoplight Elements` or `RapiDoc` to visualize your API documentation. Customize the interface to fit your preferences.
25
- - **Real-time Documentation**: As your API evolves, regenerate the OpenAPI documentation with a single command, ensuring your documentation is always up to date.
26
- - **Easy configuration**: Customize generator behavior using the `next.openapi.json` configuration file, allowing for quick adjustments without modifying the code.
27
-
28
- ## Installation
29
-
30
- ```bash
31
- yarn add next-openapi-gen
32
- ```
33
-
34
- ## Usage
35
-
36
- ### Step 1: Initialize Configuration and Setup
37
-
38
- Run the following command to generate the `next.openapi.json` configuration file and automatically set up Swagger UI with `/api-docs` routes:
39
-
40
- ```bash
41
- npx next-openapi-gen init --ui swagger --docs-url api-docs
42
- ```
43
-
44
- Parameters:
45
- - **ui**: `swagger` | `redoc` | `stoplight` | `rapidoc`
46
- - **docs-url**: url on which api docs will be visible
47
-
48
- This command does the following:
49
-
50
- - Generates a `next.openapi.json` file, which stores the OpenAPI configuration for your project.
51
- - Installs Swagger UI to provide an API documentation interface.
52
- - Adds an `/api-docs` route in the Next.js app for visualizing the generated OpenAPI documentation.
53
-
54
- ### Step 2: Add JSDoc Comments to Your API Routes
55
-
56
- Annotate your API routes using JSDoc comments. Here's an example:
57
-
58
- ```typescript
59
- //app/api/auth/reset-password/route.ts
60
-
61
- import { type NextRequest } from "next/server";
62
-
63
- type ResetPasswordParams = {
64
- token: string; // Token for resetting the password
65
- };
66
-
67
- type ResetPasswordBody = {
68
- password: string; // The new password for the user
69
- };
70
-
71
- type ResetPasswordResponse = {
72
- message: string; // Confirmation message that password has been reset
73
- };
74
-
75
- /**
76
- * Reset the user's password.
77
- * @auth: bearer
78
- * @desc: Allows users to reset their password using a reset token.
79
- * @params: ResetPasswordParams
80
- * @body: ResetPasswordBody
81
- * @response: ResetPasswordResponse
82
- */
83
- export async function POST(req: Request) {
84
- const searchParams = req.nextUrl.searchParams;
85
-
86
- const token = searchParams.get("token"); // Token from query params
87
- const { password } = await req.json(); // New password from request body
88
-
89
- // Logic to reset the user's password
90
-
91
- return Response.json({ message: "Password has been reset" });
92
- }
93
- ```
94
-
95
- - `@openapi`: Marks the route for inclusion in the OpenAPI specification.
96
- - `@auth`: Specifies authentication type used for API route (`basic`, `bearer`, `apikey`)
97
- - `@desc`: Provides a detailed description of the API route.
98
- - `@params`: Specifies the TypeScript interface or Zod schema for the query parameters.
99
- - `@body`: Specifies the TypeScript interface or Zod schema for the request body.
100
- - `@response`: Specifies the TypeScript interface or Zod schema for the response.
101
-
102
- ### Step 3: Generate the OpenAPI Specification
103
-
104
- Run the following command to generate the OpenAPI schema based on your API routes:
105
-
106
- ```bash
107
- npx next-openapi-gen generate
108
- ```
109
-
110
- This command processes all your API routes, extracts the necessary information from JSDoc comments, and generates the OpenAPI schema, typically saved to a `swagger.json` file in the `public` folder.
111
-
112
- ### Step 4: View API Documentation
113
-
114
- With the `/api-docs` route generated from the init command, you can now access your API documentation through Swagger UI by navigating to `http://localhost:3000/api-docs`.
115
-
116
- ## Configuration Options
117
-
118
- The `next.openapi.json` file allows you to configure the behavior of the OpenAPI generator, including options such as:
119
-
120
- - **apiDir**: (default: `./src/app/api`) The directory where your API routes are stored.
121
- - **schemaDir**: (default: `./src`) The directory where your schema definitions are stored.
122
- - **docsUrl**: (default: `./api-docs`) Route where OpenAPI UI is available.
123
- - **ui**: (default: `swagger`) OpenAPI UI interface.
124
- - **outputFile**: (default: `./swagger.json`) The file where the generated OpenAPI specification will be saved in `public` folder.
125
- - **includeOpenApiRoutes**: (default: `false`) When `true`, the generator will only include routes that have the `@openapi` tag in their JSDoc comments.
1
+ # next-openapi-gen
2
+
3
+ **next-openapi-gen** super fast and easy way to generate OpenAPI 3.0 documentation automatically from API routes in a Next.js 14.
4
+
5
+ With support for multiple user interfaces next-openapi-gen makes documenting your API a breeze!
6
+
7
+ ## Prerequisites
8
+
9
+ - Nextjs >= 14
10
+ - Node >= 18
11
+
12
+ ## Supported interfaces
13
+
14
+ - Swagger
15
+ - Redoc
16
+ - Stoplight Elements
17
+ - RapiDoc
18
+
19
+ ## Features
20
+
21
+ - **Automatic OpenAPI Generation**: Generate OpenAPI 3.0 documentation from your Next.js routes, automatically parsing TypeScript types for parameters, request bodies and responses.
22
+ - **TypeScript Type Scanning**: Automatically resolve TypeScript types for params, body, and responses based on your API endpoint's TypeScript definitions. Field comments in TypeScript types are reflected as descriptions in the OpenAPI schema.
23
+ - **JSDoc-Based Documentation (Optional)**: Document API routes with JSDoc comments, including tags like `@openapi`, `@auth`, `@desc`, `@params`, `@body`, and `@response` to easily define route metadata.
24
+ - **UI Interface Options**: Choose between `Swagger UI`, `Redoc`, `Stoplight Elements` or `RapiDoc` to visualize your API documentation. Customize the interface to fit your preferences.
25
+ - **Real-time Documentation**: As your API evolves, regenerate the OpenAPI documentation with a single command, ensuring your documentation is always up to date.
26
+ - **Easy configuration**: Customize generator behavior using the `next.openapi.json` configuration file, allowing for quick adjustments without modifying the code.
27
+
28
+ ![Demo File](https://raw.githubusercontent.com/tazo90/next-openapi-gen/refs/heads/main/assets/demo.gif)
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ yarn add next-openapi-gen
34
+ ```
35
+
36
+ ## Usage
37
+
38
+ ### Step 1: Initialize Configuration and Setup
39
+
40
+ Run the following command to generate the `next.openapi.json` configuration file and automatically set up Swagger UI with `/api-docs` routes:
41
+
42
+ ```bash
43
+ npx next-openapi-gen init --ui swagger --docs-url api-docs
44
+ ```
45
+
46
+ Parameters:
47
+ - **ui**: `swagger` | `redoc` | `stoplight` | `rapidoc`
48
+ - **docs-url**: url on which api docs will be visible
49
+
50
+ This command does the following:
51
+
52
+ - Generates a `next.openapi.json` file, which stores the OpenAPI configuration for your project.
53
+ - Installs Swagger UI to provide an API documentation interface.
54
+ - Adds an `/api-docs` route in the Next.js app for visualizing the generated OpenAPI documentation.
55
+
56
+ ### Step 2: Add JSDoc Comments to Your API Routes
57
+
58
+ Annotate your API routes using JSDoc comments. Here's an example:
59
+
60
+ ```typescript
61
+ //app/api/auth/reset-password/route.ts
62
+
63
+ import { type NextRequest } from "next/server";
64
+
65
+ type ResetPasswordParams = {
66
+ token: string; // Token for resetting the password
67
+ };
68
+
69
+ type ResetPasswordBody = {
70
+ password: string; // The new password for the user
71
+ };
72
+
73
+ type ResetPasswordResponse = {
74
+ message: string; // Confirmation message that password has been reset
75
+ };
76
+
77
+ /**
78
+ * Reset the user's password.
79
+ * @auth: bearer
80
+ * @desc: Allows users to reset their password using a reset token.
81
+ * @params: ResetPasswordParams
82
+ * @body: ResetPasswordBody
83
+ * @response: ResetPasswordResponse
84
+ */
85
+ export async function POST(req: Request) {
86
+ const searchParams = req.nextUrl.searchParams;
87
+
88
+ const token = searchParams.get("token"); // Token from query params
89
+ const { password } = await req.json(); // New password from request body
90
+
91
+ // Logic to reset the user's password
92
+
93
+ return Response.json({ message: "Password has been reset" });
94
+ }
95
+ ```
96
+
97
+ - `@openapi`: Marks the route for inclusion in the OpenAPI specification.
98
+ - `@auth`: Specifies authentication type used for API route (`basic`, `bearer`, `apikey`)
99
+ - `@desc`: Provides a detailed description of the API route.
100
+ - `@params`: Specifies the TypeScript interface for the query parameters.
101
+ - `@body`: Specifies the TypeScript interface for the request body.
102
+ - `@response`: Specifies the TypeScript interface for the response.
103
+
104
+ ### Step 3: Generate the OpenAPI Specification
105
+
106
+ Run the following command to generate the OpenAPI schema based on your API routes:
107
+
108
+ ```bash
109
+ npx next-openapi-gen generate
110
+ ```
111
+
112
+ This command processes all your API routes, extracts the necessary information from JSDoc comments, and generates the OpenAPI schema, typically saved to a `swagger.json` file in the `public` folder.
113
+
114
+ ### Step 4: View API Documentation
115
+
116
+ With the `/api-docs` route generated from the init command, you can now access your API documentation through Swagger UI by navigating to `http://localhost:3000/api-docs`.
117
+
118
+ ## Configuration Options
119
+
120
+ The `next.openapi.json` file allows you to configure the behavior of the OpenAPI generator, including options such as:
121
+
122
+ - **apiDir**: (default: `./src/app/api`) The directory where your API routes are stored.
123
+ - **schemaDir**: (default: `./src`) The directory where your schema definitions are stored.
124
+ - **docsUrl**: (default: `./api-docs`) Route where OpenAPI UI is available.
125
+ - **ui**: (default: `swagger`) OpenAPI UI interface.
126
+ - **outputFile**: (default: `./swagger.json`) The file where the generated OpenAPI specification will be saved in `public` folder.
127
+ - **includeOpenApiRoutes**: (default: `false`) When `true`, the generator will only include routes that have the `@openapi` tag in their JSDoc comments.
128
+
129
+ ## Interface providers
130
+
131
+ <div align="center">
132
+ <table>
133
+ <thead>
134
+ <th>SwaggerUI</th>
135
+ <th>Redoc</th>
136
+ <th>Stoplight Elements</th>
137
+ <th>RapiDoc</th>
138
+ </thead>
139
+ <tbody>
140
+ <tr>
141
+ <td>
142
+ <img width="320" alt="swagger" src="https://raw.githubusercontent.com/tazo90/next-openapi-gen/refs/heads/main/assets/swagger.png" alt-text="swagger">
143
+ </td>
144
+ <td>
145
+ <img width="320" alt="redoc" src="https://raw.githubusercontent.com/tazo90/next-openapi-gen/refs/heads/main/assets/redoc.png" alt-text="redoc">
146
+ </td>
147
+ <td>
148
+ <img width="320" alt="stoplight" src="https://raw.githubusercontent.com/tazo90/next-openapi-gen/refs/heads/main/assets/stoplight.png" alt-text="stoplight">
149
+ </td>
150
+ <td>
151
+ <img width="320" alt="rapidoc" src="https://raw.githubusercontent.com/tazo90/next-openapi-gen/refs/heads/main/assets/rapidoc.png" alt-text="rapidoc">
152
+ </td>
153
+ </tr>
154
+ </tbody>
155
+ </table>
@@ -89,7 +89,8 @@ export class RouteProcessor {
89
89
  ];
90
90
  }
91
91
  if (params) {
92
- definition.parameters = params;
92
+ definition.parameters =
93
+ this.schemaProcessor.createRequestParamsSchema(params);
93
94
  }
94
95
  // Add request body
95
96
  if (MUTATION_HTTP_METHODS.includes(method.toUpperCase())) {
@@ -117,7 +118,7 @@ export class RouteProcessor {
117
118
  const aTags = Object.values(aMethods).flatMap((method) => method.tags || []);
118
119
  // Extract tags for all methods in path b
119
120
  const bTags = Object.values(bMethods).flatMap((method) => method.tags || []);
120
- // Assume we are interested in only the first tags
121
+ // Let's user only the first tags
121
122
  const aPrimaryTag = aTags[0] || "";
122
123
  const bPrimaryTag = bTags[0] || "";
123
124
  // Sort alphabetically based on the first tag
@@ -128,7 +129,6 @@ export class RouteProcessor {
128
129
  // Compare lengths of the paths
129
130
  const aLength = a.split("/").length;
130
131
  const bLength = b.split("/").length;
131
- // Return the result of length comparison
132
132
  return aLength - bLength; // Shorter paths come before longer ones
133
133
  }
134
134
  return Object.keys(paths)
@@ -5,111 +5,209 @@ import traverse from "@babel/traverse";
5
5
  import * as t from "@babel/types";
6
6
  export class SchemaProcessor {
7
7
  schemaDir;
8
+ typeDefinitions = {};
9
+ openapiDefinitions = {};
10
+ contentType = "";
8
11
  constructor(schemaDir) {
9
12
  this.schemaDir = path.resolve(schemaDir);
10
13
  }
11
- findSchemaDefinition(schemaName) {
14
+ findSchemaDefinition(schemaName, contentType) {
12
15
  let schemaNode = null;
13
- this.scanSchemaDir(this.schemaDir, schemaName, (node) => {
14
- schemaNode = node;
15
- });
16
+ // assign type that is actually processed
17
+ this.contentType = contentType;
18
+ this.scanSchemaDir(this.schemaDir, schemaName);
16
19
  return schemaNode;
17
20
  }
18
- scanSchemaDir(dir, schemaName, callback) {
21
+ scanSchemaDir(dir, schemaName) {
19
22
  const files = fs.readdirSync(dir);
20
23
  files.forEach((file) => {
21
24
  const filePath = path.join(dir, file);
22
25
  const stat = fs.statSync(filePath);
23
26
  if (stat.isDirectory()) {
24
- this.scanSchemaDir(filePath, schemaName, callback);
27
+ this.scanSchemaDir(filePath, schemaName);
25
28
  }
26
29
  else if (file.endsWith(".ts")) {
27
- this.processSchemaFile(filePath, schemaName, callback);
30
+ this.processSchemaFile(filePath, schemaName);
28
31
  }
29
32
  });
30
33
  }
31
- processSchemaFile(filePath, schemaName, callback) {
32
- const content = fs.readFileSync(filePath, "utf-8");
33
- const ast = parse(content, {
34
- sourceType: "module",
35
- plugins: ["typescript", "decorators-legacy"],
36
- });
34
+ collectTypeDefinitions(ast, schemaName) {
37
35
  traverse.default(ast, {
38
36
  VariableDeclarator: (path) => {
39
37
  if (t.isIdentifier(path.node.id, { name: schemaName })) {
40
- callback(path.node.init || path.node);
38
+ const name = path.node.id.name;
39
+ this.typeDefinitions[name] = path.node.init || path.node;
41
40
  }
42
41
  },
43
42
  TSTypeAliasDeclaration: (path) => {
44
43
  if (t.isIdentifier(path.node.id, { name: schemaName })) {
45
- callback(path.node.typeAnnotation);
44
+ const name = path.node.id.name;
45
+ this.typeDefinitions[name] = path.node.typeAnnotation;
46
46
  }
47
47
  },
48
48
  TSInterfaceDeclaration: (path) => {
49
49
  if (t.isIdentifier(path.node.id, { name: schemaName })) {
50
- callback(path.node);
50
+ const name = path.node.id.name;
51
+ this.typeDefinitions[name] = path.node;
52
+ }
53
+ },
54
+ TSEnumDeclaration: (path) => {
55
+ if (t.isIdentifier(path.node.id, { name: schemaName })) {
56
+ const name = path.node.id.name;
57
+ this.typeDefinitions[name] = path.node;
51
58
  }
52
59
  },
53
60
  });
54
61
  }
55
- extractTypesFromSchema(schema, dataType) {
56
- const result = dataType === "params" ? [] : {};
57
- const handleProperty = (property) => {
58
- const key = property.key.name;
59
- const typeAnnotation = property.typeAnnotation?.typeAnnotation?.type;
60
- const type = this.getTypeFromAnnotation(typeAnnotation);
61
- const isOptional = !!property.optional; // check if property is optional
62
- let description = "";
63
- // get comments for field
64
- if (property.trailingComments && property.trailingComments.length) {
65
- description = property.trailingComments[0].value.trim(); // get first comment
62
+ resolveType(typeName) {
63
+ const typeNode = this.typeDefinitions[typeName.toString()];
64
+ if (!typeNode)
65
+ return {};
66
+ if (t.isTSEnumDeclaration(typeNode)) {
67
+ const enumValues = this.processEnum(typeNode);
68
+ return enumValues;
69
+ }
70
+ if (t.isTSTypeLiteral(typeNode) || t.isTSInterfaceBody(typeNode)) {
71
+ const properties = {};
72
+ if ("members" in typeNode) {
73
+ (typeNode.members || []).forEach((member) => {
74
+ if (t.isTSPropertySignature(member) && t.isIdentifier(member.key)) {
75
+ const propName = member.key.name;
76
+ const options = this.getPropertyOptions(member);
77
+ const property = {
78
+ ...this.resolveTSNodeType(member.typeAnnotation?.typeAnnotation),
79
+ ...options,
80
+ };
81
+ properties[propName] = property;
82
+ }
83
+ });
66
84
  }
67
- const field = {
68
- type: type,
69
- description: description,
85
+ return { type: "object", properties };
86
+ }
87
+ if (t.isTSArrayType(typeNode)) {
88
+ return {
89
+ type: "array",
90
+ items: this.resolveTSNodeType(typeNode.elementType),
70
91
  };
71
- if (dataType === "params") {
92
+ }
93
+ return {};
94
+ }
95
+ resolveTSNodeType(node) {
96
+ if (t.isTSStringKeyword(node))
97
+ return { type: "string" };
98
+ if (t.isTSNumberKeyword(node))
99
+ return { type: "number" };
100
+ if (t.isTSBooleanKeyword(node))
101
+ return { type: "boolean" };
102
+ if (t.isTSTypeReference(node) && t.isIdentifier(node.typeName)) {
103
+ const typeName = node.typeName.name;
104
+ // Find type definition
105
+ this.findSchemaDefinition(typeName, this.contentType);
106
+ return this.resolveType(node.typeName.name);
107
+ }
108
+ if (t.isTSArrayType(node)) {
109
+ return {
110
+ type: "array",
111
+ items: this.resolveTSNodeType(node.elementType),
112
+ };
113
+ }
114
+ if (t.isTSTypeLiteral(node)) {
115
+ const properties = {};
116
+ node.members.forEach((member) => {
117
+ if (t.isTSPropertySignature(member) && t.isIdentifier(member.key)) {
118
+ const propName = member.key.name;
119
+ properties[propName] = this.resolveTSNodeType(member.typeAnnotation?.typeAnnotation);
120
+ }
121
+ });
122
+ return { type: "object", properties };
123
+ }
124
+ return {};
125
+ }
126
+ processSchemaFile(filePath, schemaName) {
127
+ // Recognizes different elements of TS like variable, type, interface, enum
128
+ const content = fs.readFileSync(filePath, "utf-8");
129
+ const ast = parse(content, {
130
+ sourceType: "module",
131
+ plugins: ["typescript", "decorators-legacy"],
132
+ });
133
+ this.collectTypeDefinitions(ast, schemaName);
134
+ const definition = this.resolveType(schemaName);
135
+ this.openapiDefinitions[schemaName] = definition;
136
+ return definition;
137
+ }
138
+ processEnum(enumNode) {
139
+ // Initialization OpenAPI enum object
140
+ const enumSchema = {
141
+ type: "string",
142
+ enum: [],
143
+ };
144
+ // Iterate throught enum members
145
+ enumNode.members.forEach((member) => {
146
+ if (t.isTSEnumMember(member)) {
72
147
  // @ts-ignore
73
- result.push({
74
- name: key,
75
- in: "query",
76
- schema: field,
77
- required: !isOptional,
78
- });
79
- }
80
- else {
81
- result[key] = field;
148
+ const name = member.id?.name;
149
+ // @ts-ignore
150
+ const value = member.initializer?.value;
151
+ let type = member.initializer?.type;
152
+ if (type === "NumericLiteral") {
153
+ enumSchema.type = "number";
154
+ }
155
+ const targetValue = value || name;
156
+ enumSchema.enum.push(targetValue);
82
157
  }
83
- };
84
- if (schema.body?.body) {
85
- schema.body.body.forEach(handleProperty);
158
+ });
159
+ return enumSchema;
160
+ }
161
+ getPropertyOptions(node) {
162
+ const key = node.key.name;
163
+ const isOptional = !!node.optional; // check if property is optional
164
+ const typeName = node.typeAnnotation?.typeAnnotation?.typeName?.name;
165
+ let description = null;
166
+ // get comments for field
167
+ if (node.trailingComments && node.trailingComments.length) {
168
+ description = node.trailingComments[0].value.trim(); // get first comment
169
+ }
170
+ const options = {};
171
+ if (description) {
172
+ options.description = description;
173
+ }
174
+ if (this.contentType === "params") {
175
+ options.required = !isOptional;
86
176
  }
87
- if (schema.type === "TSTypeLiteral" && schema.members) {
88
- schema.members.forEach(handleProperty);
177
+ else if (this.contentType === "body") {
178
+ options.nullable = isOptional;
89
179
  }
90
- return result;
180
+ return options;
91
181
  }
92
- getTypeFromAnnotation(type) {
93
- switch (type) {
94
- case "TSStringKeyword":
95
- return "string";
96
- case "TSNumberKeyword":
97
- return "number";
98
- case "TSBooleanKeyword":
99
- return "boolean";
100
- // Add other cases as needed.
101
- default:
102
- return "object"; // fallback to object for unknown types
182
+ createRequestParamsSchema(params) {
183
+ const queryParams = [];
184
+ if (params.properties) {
185
+ for (let [name, value] of Object.entries(params.properties)) {
186
+ const param = {
187
+ in: "query",
188
+ name,
189
+ schema: {
190
+ type: value.type,
191
+ },
192
+ required: value.required,
193
+ };
194
+ if (value.enum) {
195
+ param.schema.enum = value.enum;
196
+ }
197
+ if (value.description) {
198
+ param.description = value.description;
199
+ param.schema.description = value.description;
200
+ }
201
+ queryParams.push(param);
202
+ }
103
203
  }
204
+ return queryParams;
104
205
  }
105
206
  createRequestBodySchema(body) {
106
207
  return {
107
208
  content: {
108
209
  "application/json": {
109
- schema: {
110
- type: "object",
111
- properties: body,
112
- },
210
+ schema: body,
113
211
  },
114
212
  },
115
213
  };
@@ -120,32 +218,19 @@ export class SchemaProcessor {
120
218
  description: "Successful response",
121
219
  content: {
122
220
  "application/json": {
123
- schema: {
124
- type: "object",
125
- properties: responses,
126
- },
221
+ schema: responses,
127
222
  },
128
223
  },
129
224
  },
130
225
  };
131
226
  }
132
227
  getSchemaContent({ paramsType, bodyType, responseType }) {
133
- const paramsSchema = paramsType
134
- ? this.findSchemaDefinition(paramsType)
135
- : null;
136
- const bodySchema = bodyType ? this.findSchemaDefinition(bodyType) : null;
137
- const responseSchema = responseType
138
- ? this.findSchemaDefinition(responseType)
139
- : null;
140
- let params = paramsSchema
141
- ? this.extractTypesFromSchema(paramsSchema, "params")
142
- : [];
143
- let body = bodySchema
144
- ? this.extractTypesFromSchema(bodySchema, "body")
145
- : {};
146
- let responses = responseSchema
147
- ? this.extractTypesFromSchema(responseSchema, "responses")
148
- : {};
228
+ this.findSchemaDefinition(paramsType, "params");
229
+ this.findSchemaDefinition(bodyType, "body");
230
+ this.findSchemaDefinition(responseType, "response");
231
+ const params = this.openapiDefinitions[paramsType];
232
+ const body = this.openapiDefinitions[bodyType];
233
+ const responses = this.openapiDefinitions[responseType];
149
234
  return {
150
235
  params,
151
236
  body,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-openapi-gen",
3
- "version": "0.0.15",
3
+ "version": "0.0.18",
4
4
  "description": "Super fast and easy way to generate OpenAPI documentation automatically from API routes in a NextJS 14",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -26,7 +26,8 @@
26
26
  "openapi",
27
27
  "swagger",
28
28
  "docs",
29
- "api"
29
+ "api",
30
+ "redoc"
30
31
  ],
31
32
  "publishConfig": {
32
33
  "access": "public"