next-openapi-gen 0.8.1 → 0.8.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.
package/README.md CHANGED
@@ -4,16 +4,13 @@ Automatically generate OpenAPI 3.0 documentation from Next.js projects, with sup
4
4
 
5
5
  ## Features
6
6
 
7
- - ✅ Automatic OpenAPI documentation generation from Next.js code
8
- - ✅ Support for Next.js App Router (including `/api/users/[id]/route.ts` routes)
9
- - ✅ TypeScript types support
10
- - ✅ Zod schemas support
11
- - ✅ Drizzle-Zod support - Generate schemas from Drizzle ORM tables 🆕
12
- - ✅ JSDoc comments support
13
- - ✅ Multiple UI interfaces: `Scalar`, `Swagger`, `Redoc`, `Stoplight` and `Rapidoc` available at `/api-docs` url
14
- - ✅ Path parameters detection (`/users/{id}`)
15
- - ✅ Intelligent parameter examples
16
- - ✅ Intuitive CLI for initialization and documentation generation
7
+ - ✅ Automatic OpenAPI 3.0 documentation generation from Next.js App Router
8
+ - ✅ Multiple schema types: `TypeScript`, `Zod`, `Drizzle-Zod`, or `custom YAML/JSON` files 🆕
9
+ - ✅ Mix schema sources simultaneously - perfect for gradual migrations 🆕
10
+ - ✅ JSDoc comments with intelligent parameter examples
11
+ - ✅ Multiple UI interfaces: `Scalar`, `Swagger`, `Redoc`, `Stoplight`, and `RapiDoc` available at `/api-docs` url
12
+ - ✅ Auto-detection of path parameters (e.g., `/users/[id]/route.ts`)
13
+ - ✅ Intuitive CLI for quick setup and generation
17
14
 
18
15
  ## Supported interfaces
19
16
 
@@ -23,6 +20,9 @@ Automatically generate OpenAPI 3.0 documentation from Next.js projects, with sup
23
20
  - Stoplight Elements
24
21
  - RapiDoc
25
22
 
23
+ > [!TIP]
24
+ > You can use the `--ui none` option during initialization to skip UI setup if you only care about generating the OpenAPI documentation.
25
+
26
26
  ## Installation
27
27
 
28
28
  ```bash
@@ -39,6 +39,9 @@ npx next-openapi-gen init --ui scalar --docs-url api-docs --schema zod
39
39
  npx next-openapi-gen generate
40
40
  ```
41
41
 
42
+ > [!TIP]
43
+ > Use the `--output` option in the `init` command to specify a custom output file for the template. Then you can use the `--template` option in the `generate` command to point to that file.
44
+
42
45
  ## Configuration
43
46
 
44
47
  During initialization (`npx next-openapi-gen init`), a configuration file `next.openapi.json` will be created in the project's root directory:
@@ -59,7 +62,8 @@ During initialization (`npx next-openapi-gen init`), a configuration file `next.
59
62
  ],
60
63
  "apiDir": "src/app/api",
61
64
  "schemaDir": "src/types", // or "src/schemas" for Zod schemas
62
- "schemaType": "zod", // or "typescript" for TypeScript types
65
+ "schemaType": "zod", // or "typescript", or ["zod", "typescript"] for multiple
66
+ "schemaFiles": [], // Optional: ["./schemas/models.yaml", "./schemas/api.json"]
63
67
  "outputFile": "openapi.json",
64
68
  "outputDir": "./public",
65
69
  "docsUrl": "/api-docs",
@@ -71,20 +75,21 @@ During initialization (`npx next-openapi-gen init`), a configuration file `next.
71
75
 
72
76
  ### Configuration Options
73
77
 
74
- | Option | Description |
75
- | ---------------------- | -------------------------------------------------------------------------- |
76
- | `apiDir` | Path to the API directory |
77
- | `schemaDir` | Path to the types/schemas directory |
78
- | `schemaType` | Schema type: `"zod"` or `"typescript"` |
79
- | `outputFile` | Name of the OpenAPI output file |
80
- | `outputDir` | Directory where OpenAPI file will be generated (default: `"./public"`) |
81
- | `docsUrl` | API documentation URL (for Swagger UI) |
82
- | `includeOpenApiRoutes` | Whether to include only routes with @openapi tag |
83
- | `ignoreRoutes` | Array of route patterns to exclude from documentation (supports wildcards) |
84
- | `defaultResponseSet` | Default error response set for all endpoints |
85
- | `responseSets` | Named sets of error response codes |
86
- | `errorConfig` | Error schema configuration |
87
- | `debug` | Enable detailed logging during generation |
78
+ | Option | Description |
79
+ | ---------------------- | ----------------------------------------------------------------------------- |
80
+ | `apiDir` | Path to the API directory |
81
+ | `schemaDir` | Path to the types/schemas directory |
82
+ | `schemaType` | Schema type: `"zod"`, `"typescript"`, or `["zod", "typescript"]` for multiple |
83
+ | `schemaFiles` | Optional: Array of custom OpenAPI schema files (YAML/JSON) to include |
84
+ | `outputFile` | Name of the OpenAPI output file |
85
+ | `outputDir` | Directory where OpenAPI file will be generated (default: `"./public"`) |
86
+ | `docsUrl` | API documentation URL (for Swagger UI) |
87
+ | `includeOpenApiRoutes` | Whether to include only routes with @openapi tag |
88
+ | `ignoreRoutes` | Array of route patterns to exclude from documentation (supports wildcards) |
89
+ | `defaultResponseSet` | Default error response set for all endpoints |
90
+ | `responseSets` | Named sets of error response codes |
91
+ | `errorConfig` | Error schema configuration |
92
+ | `debug` | Enable detailed logging during generation |
88
93
 
89
94
  ## Documenting Your API
90
95
 
@@ -766,19 +771,61 @@ export const CreatePostSchema = createInsertSchema(posts, {
766
771
 
767
772
  See the [complete Drizzle-Zod example](./examples/next15-app-drizzle-zod) for a full working implementation with a blog API.
768
773
 
774
+ ## Multiple Schema Types Support 🆕
775
+
776
+ Use **multiple schema types simultaneously** in a single project - perfect for gradual migrations, combining hand-written schemas with generated ones (protobuf, GraphQL), or using existing OpenAPI specs.
777
+
778
+ ### Configuration
779
+
780
+ ```json
781
+ {
782
+ "schemaType": ["zod", "typescript"],
783
+ "schemaDir": "./src/schemas",
784
+ "schemaFiles": ["./schemas/external-api.yaml"]
785
+ }
786
+ ```
787
+
788
+ ### Schema Resolution Priority
789
+
790
+ 1. **Custom files** (highest) - from `schemaFiles` array
791
+ 2. **Zod schemas** (medium) - if `"zod"` in `schemaType`
792
+ 3. **TypeScript types** (fallback) - if `"typescript"` in `schemaType`
793
+
794
+ ### Common Use Cases
795
+
796
+ ```json
797
+ // Gradual TypeScript → Zod migration
798
+ { "schemaType": ["zod", "typescript"] }
799
+
800
+ // Zod + protobuf schemas
801
+ {
802
+ "schemaType": ["zod"],
803
+ "schemaFiles": ["./proto/schemas.yaml"]
804
+ }
805
+
806
+ // Everything together
807
+ {
808
+ "schemaType": ["zod", "typescript"],
809
+ "schemaFiles": ["./openapi-models.yaml"]
810
+ }
811
+ ```
812
+
813
+ Custom schema files support YAML/JSON in OpenAPI 3.0 format. See **[next15-app-mixed-schemas](./examples/next15-app-mixed-schemas)** for a complete working example.
814
+
769
815
  ## Examples
770
816
 
771
817
  This repository includes several complete example projects:
772
818
 
773
819
  ### 📦 Available Examples
774
820
 
775
- | Example | Description | Features |
776
- | --------------------------------------------------------------- | -------------------------- | ----------------------------------------------- |
777
- | **[next15-app-zod](./examples/next15-app-zod)** | Zod schemas example | Users, Products, Orders API with Zod validation |
778
- | **[next15-app-drizzle-zod](./examples/next15-app-drizzle-zod)** | Drizzle-Zod integration 🆕 | Blog API with Drizzle ORM + drizzle-zod |
779
- | **[next15-app-typescript](./examples/next15-app-typescript)** | TypeScript types | API with pure TypeScript type definitions |
780
- | **[next15-app-scalar](./examples/next15-app-scalar)** | Scalar UI | Modern API documentation interface |
781
- | **[next15-app-swagger](./examples/next15-app-swagger)** | Swagger UI | Classic Swagger documentation |
821
+ | Example | Description | Features |
822
+ | --------------------------------------------------------------- | ----------------------- | ----------------------------------------------- |
823
+ | **[next15-app-zod](./examples/next15-app-zod)** | Zod schemas example | Users, Products, Orders API with Zod validation |
824
+ | **[next15-app-drizzle-zod](./examples/next15-app-drizzle-zod)** | Drizzle-Zod integration | Blog API with Drizzle ORM + drizzle-zod |
825
+ | **[next15-app-mixed-schemas](./examples/next15-app-mixed-schemas)** 🆕 | Multiple schema types | Zod + TypeScript + Custom YAML schemas combined |
826
+ | **[next15-app-typescript](./examples/next15-app-typescript)** | TypeScript types | API with pure TypeScript type definitions |
827
+ | **[next15-app-scalar](./examples/next15-app-scalar)** | Scalar UI | Modern API documentation interface |
828
+ | **[next15-app-swagger](./examples/next15-app-swagger)** | Swagger UI | Classic Swagger documentation |
782
829
 
783
830
  ### 🚀 Running Examples
784
831
 
@@ -824,26 +871,11 @@ Visit `http://localhost:3000/api-docs` to see the generated documentation.
824
871
  </table>
825
872
  </div>
826
873
 
827
- ## Learn More
828
-
829
- - **[Drizzle-Zod Example](./examples/next15-app-drizzle-zod)** - Complete example with Drizzle ORM integration
830
- - **[Drizzle ORM](https://orm.drizzle.team/)** - TypeScript ORM for SQL databases
831
- - **[drizzle-zod](https://orm.drizzle.team/docs/zod)** - Zod schema generator for Drizzle
832
- - **[Zod Documentation](https://zod.dev/)** - TypeScript-first schema validation
833
- - **[Next.js Documentation](https://nextjs.org/docs)** - React framework documentation
834
- - **[OpenAPI Specification](https://swagger.io/specification/)** - OpenAPI 3.0 spec
835
- - **[Scalar Documentation](https://docs.scalar.com/)** - Modern API documentation UI
836
-
837
874
  ## Contributing
838
875
 
839
876
  We welcome contributions! 🎉
840
877
 
841
- Please read our [Contributing Guide](CONTRIBUTING.md) for details on:
842
-
843
- - 📝 Commit message guidelines (Conventional Commits)
844
- - 🔧 Development setup
845
- - ✅ Pull request process
846
- - 🚀 Release workflow
878
+ Please read our [Contributing Guide](CONTRIBUTING.md) for details.
847
879
 
848
880
  ## Changelog
849
881
 
@@ -3,9 +3,12 @@ import fse from "fs-extra";
3
3
  import path from "path";
4
4
  import ora from "ora";
5
5
  import { OpenApiGenerator } from "../lib/openapi-generator.js";
6
- export async function generate() {
6
+ export async function generate(options) {
7
+ const { template } = options;
7
8
  const spinner = ora("Generating OpenAPI specification...\n").start();
8
- const generator = new OpenApiGenerator();
9
+ const generator = new OpenApiGenerator({
10
+ templatePath: template,
11
+ });
9
12
  const config = generator.getConfig();
10
13
  // Create api dir if not exists
11
14
  const apiDir = path.resolve(config.apiDir);
@@ -85,6 +85,9 @@ function getDocsPageDependencies(ui) {
85
85
  return deps.join(" ");
86
86
  }
87
87
  async function createDocsPage(ui, outputFile) {
88
+ if (ui === "none") {
89
+ return;
90
+ }
88
91
  const paths = ["app", "api-docs"];
89
92
  const srcPath = path.join(process.cwd(), "src");
90
93
  if (fs.existsSync(srcPath)) {
@@ -98,6 +101,9 @@ async function createDocsPage(ui, outputFile) {
98
101
  spinner.succeed(`Created ${paths.join("/")}/page.tsx for ${ui}.`);
99
102
  }
100
103
  async function installDependencies(ui) {
104
+ if (ui === "none") {
105
+ return;
106
+ }
101
107
  const packageManager = await getPackageManager();
102
108
  const installCmd = `${packageManager} ${packageManager === "npm" ? "install" : "add"}`;
103
109
  const deps = getDocsPageDependencies(ui);
@@ -111,15 +117,21 @@ function extendOpenApiTemplate(spec, options) {
111
117
  spec.docsUrl = options.docsUrl ?? spec.docsUrl;
112
118
  spec.schemaType = options.schema ?? spec.schemaType;
113
119
  }
120
+ function getOutputPath(output) {
121
+ if (output) {
122
+ return path.isAbsolute(output) ? output : path.join(process.cwd(), output);
123
+ }
124
+ return path.join(process.cwd(), "next.openapi.json");
125
+ }
114
126
  export async function init(options) {
115
- const { ui } = options;
127
+ const { ui, output } = options;
116
128
  spinner.start();
117
129
  try {
118
- const outputPath = path.join(process.cwd(), "next.openapi.json");
130
+ const outputPath = getOutputPath(output);
119
131
  const template = { ...openapiTemplate };
120
132
  extendOpenApiTemplate(template, options);
121
133
  await fse.writeJson(outputPath, template, { spaces: 2 });
122
- spinner.succeed(`Created OpenAPI template in next.openapi.json`);
134
+ spinner.succeed(`Created OpenAPI template in ${outputPath}`);
123
135
  createDocsPage(ui, template.outputFile);
124
136
  installDependencies(ui);
125
137
  }
package/dist/index.js CHANGED
@@ -9,17 +9,19 @@ program
9
9
  .description("Super fast and easy way to generate OpenAPI documentation for Next.js");
10
10
  program
11
11
  .command("init")
12
- .addOption(new Option("-i, --ui <type>", "Specify the UI type, e.g., scalar")
13
- .choices(["scalar", "swagger", "redoc", "stoplight", "rapidoc"])
12
+ .addOption(new Option("-i, --ui <type>", "Specify the UI type, e.g., scalar. Use \"none\" for no UI")
13
+ .choices(["scalar", "swagger", "redoc", "stoplight", "rapidoc", "none"])
14
14
  .default("swagger"))
15
15
  .option("-u, --docs-url <url>", "Specify the docs URL", "api-docs")
16
16
  .addOption(new Option("-s, --schema <schemaType>", "Specify the schema tool")
17
17
  .choices(["zod", "typescript"])
18
18
  .default("zod"))
19
+ .option("-o, --output <file>", "Specify the output path for the OpenAPI template.", "next.openapi.json")
19
20
  .description("Initialize a openapi specification")
20
21
  .action(init);
21
22
  program
22
23
  .command("generate")
23
24
  .description("Generate a specification based on api routes")
25
+ .option("-t, --template <file>", "Specify the OpenAPI template file", "next.openapi.json")
24
26
  .action(generate);
25
27
  program.parse(process.argv);
@@ -7,8 +7,8 @@ export class OpenApiGenerator {
7
7
  config;
8
8
  template;
9
9
  routeProcessor;
10
- constructor() {
11
- const templatePath = path.resolve("./next.openapi.json");
10
+ constructor(opts = {}) {
11
+ const templatePath = opts.templatePath || path.resolve("./next.openapi.json");
12
12
  this.template = JSON.parse(fs.readFileSync(templatePath, "utf-8"));
13
13
  this.config = this.getConfig();
14
14
  this.routeProcessor = new RouteProcessor(this.config);
@@ -17,7 +17,7 @@ export class OpenApiGenerator {
17
17
  }
18
18
  getConfig() {
19
19
  // @ts-ignore
20
- const { apiDir, schemaDir, docsUrl, ui, outputFile, outputDir, includeOpenApiRoutes, ignoreRoutes, schemaType = "typescript", defaultResponseSet, responseSets, errorConfig, debug } = this.template;
20
+ const { apiDir, schemaDir, docsUrl, ui, outputFile, outputDir, includeOpenApiRoutes, ignoreRoutes, schemaType = "typescript", schemaFiles, defaultResponseSet, responseSets, errorConfig, debug } = this.template;
21
21
  return {
22
22
  apiDir: apiDir || "./src/app/api",
23
23
  schemaDir: schemaDir || "./src",
@@ -28,6 +28,7 @@ export class OpenApiGenerator {
28
28
  includeOpenApiRoutes: includeOpenApiRoutes || false,
29
29
  ignoreRoutes: ignoreRoutes || [],
30
30
  schemaType,
31
+ schemaFiles: schemaFiles || [],
31
32
  defaultResponseSet,
32
33
  responseSets,
33
34
  errorConfig,
@@ -18,7 +18,7 @@ export class RouteProcessor {
18
18
  processFileTracker = {};
19
19
  constructor(config) {
20
20
  this.config = config;
21
- this.schemaProcessor = new SchemaProcessor(config.schemaDir, config.schemaType);
21
+ this.schemaProcessor = new SchemaProcessor(config.schemaDir, config.schemaType, config.schemaFiles);
22
22
  }
23
23
  buildResponsesFromConfig(dataTypes, method) {
24
24
  const responses = {};
@@ -2,50 +2,107 @@ import fs from "fs";
2
2
  import path from "path";
3
3
  import traverseModule from "@babel/traverse";
4
4
  import * as t from "@babel/types";
5
+ import yaml from "js-yaml";
5
6
  // Handle both ES modules and CommonJS
6
7
  const traverse = traverseModule.default || traverseModule;
7
8
  import { parseTypeScriptFile } from "./utils.js";
8
9
  import { ZodSchemaConverter } from "./zod-converter.js";
9
10
  import { logger } from "./logger.js";
11
+ /**
12
+ * Normalize schemaType to array
13
+ */
14
+ function normalizeSchemaTypes(schemaType) {
15
+ return Array.isArray(schemaType) ? schemaType : [schemaType];
16
+ }
10
17
  export class SchemaProcessor {
11
18
  schemaDir;
12
19
  typeDefinitions = {};
13
20
  openapiDefinitions = {};
14
21
  contentType = "";
22
+ customSchemas = {};
15
23
  directoryCache = {};
16
24
  statCache = {};
17
25
  processSchemaTracker = {};
18
26
  processingTypes = new Set();
19
- zodSchemaConverter;
20
- schemaType;
27
+ zodSchemaConverter = null;
28
+ schemaTypes;
21
29
  isResolvingPickOmitBase = false;
22
- constructor(schemaDir, schemaType = "typescript") {
30
+ constructor(schemaDir, schemaType = "typescript", schemaFiles) {
23
31
  this.schemaDir = path.resolve(schemaDir);
24
- this.schemaType = schemaType;
25
- if (schemaType === "zod") {
32
+ this.schemaTypes = normalizeSchemaTypes(schemaType);
33
+ // Initialize Zod converter if Zod is enabled
34
+ if (this.schemaTypes.includes("zod")) {
26
35
  this.zodSchemaConverter = new ZodSchemaConverter(schemaDir);
27
36
  }
37
+ // Load custom schema files if provided
38
+ if (schemaFiles && schemaFiles.length > 0) {
39
+ this.loadCustomSchemas(schemaFiles);
40
+ }
41
+ }
42
+ /**
43
+ * Load custom OpenAPI schema files (YAML/JSON)
44
+ */
45
+ loadCustomSchemas(schemaFiles) {
46
+ for (const filePath of schemaFiles) {
47
+ try {
48
+ const resolvedPath = path.resolve(filePath);
49
+ if (!fs.existsSync(resolvedPath)) {
50
+ logger.warn(`Schema file not found: ${filePath}`);
51
+ continue;
52
+ }
53
+ const content = fs.readFileSync(resolvedPath, "utf-8");
54
+ const ext = path.extname(filePath).toLowerCase();
55
+ let parsed;
56
+ if (ext === ".yaml" || ext === ".yml") {
57
+ parsed = yaml.load(content);
58
+ }
59
+ else if (ext === ".json") {
60
+ parsed = JSON.parse(content);
61
+ }
62
+ else {
63
+ logger.warn(`Unsupported file type: ${filePath} (use .json, .yaml, or .yml)`);
64
+ continue;
65
+ }
66
+ // Extract schemas from OpenAPI structure or use file content directly
67
+ const schemas = parsed?.components?.schemas || parsed?.schemas || parsed;
68
+ if (typeof schemas === "object" && schemas !== null) {
69
+ Object.assign(this.customSchemas, schemas);
70
+ logger.log(`✓ Loaded custom schemas from: ${filePath}`);
71
+ }
72
+ else {
73
+ logger.warn(`No valid schemas found in ${filePath}. Expected OpenAPI format with components.schemas or plain object.`);
74
+ }
75
+ }
76
+ catch (error) {
77
+ logger.warn(`Failed to load schema file ${filePath}: ${error.message}`);
78
+ }
79
+ }
28
80
  }
29
81
  /**
30
82
  * Get all defined schemas (for components.schemas section)
83
+ * Merges schemas from all sources with proper priority:
84
+ * 1. TypeScript types (lowest priority - base layer)
85
+ * 2. Zod schemas (medium priority)
86
+ * 3. Custom files (highest priority - overrides all)
31
87
  */
32
88
  getDefinedSchemas() {
33
- // Filter out generic type parameters and invalid schema names
89
+ const merged = {};
90
+ // Layer 1: TypeScript types (base layer)
34
91
  const filteredSchemas = {};
35
92
  Object.entries(this.openapiDefinitions).forEach(([key, value]) => {
36
93
  if (!this.isGenericTypeParameter(key) && !this.isInvalidSchemaName(key)) {
37
94
  filteredSchemas[key] = value;
38
95
  }
39
96
  });
40
- // If using Zod, also include all processed Zod schemas
41
- if (this.schemaType === "zod" && this.zodSchemaConverter) {
97
+ Object.assign(merged, filteredSchemas);
98
+ // Layer 2: Zod schemas (if enabled - overrides TypeScript)
99
+ if (this.schemaTypes.includes("zod") && this.zodSchemaConverter) {
42
100
  const zodSchemas = this.zodSchemaConverter.getProcessedSchemas();
43
- return {
44
- ...filteredSchemas,
45
- ...zodSchemas,
46
- };
101
+ Object.assign(merged, zodSchemas);
47
102
  }
48
- return filteredSchemas;
103
+ // Layer 3: Custom files (highest priority - overrides all)
104
+ Object.assign(merged, this.customSchemas);
105
+ return merged;
49
106
  }
50
107
  findSchemaDefinition(schemaName, contentType) {
51
108
  let schemaNode = null;
@@ -55,8 +112,13 @@ export class SchemaProcessor {
55
112
  if (schemaName.includes("<") && schemaName.includes(">")) {
56
113
  return this.resolveGenericTypeFromString(schemaName);
57
114
  }
58
- // Check if we should use Zod schemas
59
- if (this.schemaType === "zod") {
115
+ // Priority 1: Check custom schemas first (highest priority)
116
+ if (this.customSchemas[schemaName]) {
117
+ logger.debug(`Found schema in custom files: ${schemaName}`);
118
+ return this.customSchemas[schemaName];
119
+ }
120
+ // Priority 2: Try Zod schemas if enabled
121
+ if (this.schemaTypes.includes("zod") && this.zodSchemaConverter) {
60
122
  logger.debug(`Looking for Zod schema: ${schemaName}`);
61
123
  // Check type mapping first
62
124
  const mappedSchemaName = this.zodSchemaConverter.typeToSchemaMapping[schemaName];
@@ -160,7 +222,8 @@ export class SchemaProcessor {
160
222
  this.processingTypes.add(typeName);
161
223
  try {
162
224
  // If we are using Zod and the given type is not found yet, try using Zod converter first
163
- if (this.schemaType === "zod" && !this.openapiDefinitions[typeName]) {
225
+ if (this.schemaTypes.includes("zod") &&
226
+ !this.openapiDefinitions[typeName]) {
164
227
  const zodSchema = this.zodSchemaConverter.convertZodSchemaToOpenApi(typeName);
165
228
  if (zodSchema) {
166
229
  this.openapiDefinitions[typeName] = zodSchema;
@@ -182,7 +245,7 @@ export class SchemaProcessor {
182
245
  t.isMemberExpression(typeNode.callee) &&
183
246
  t.isIdentifier(typeNode.callee.object) &&
184
247
  typeNode.callee.object.name === "z") {
185
- if (this.schemaType === "zod") {
248
+ if (this.schemaTypes.includes("zod")) {
186
249
  const zodSchema = this.zodSchemaConverter.processZodNode(typeNode);
187
250
  if (zodSchema) {
188
251
  this.openapiDefinitions[typeName] = zodSchema;
@@ -784,7 +847,7 @@ export class SchemaProcessor {
784
847
  this.findSchemaDefinition(responseType, "response");
785
848
  responses = this.openapiDefinitions[responseType] || {};
786
849
  }
787
- if (this.schemaType === "zod") {
850
+ if (this.schemaTypes.includes("zod")) {
788
851
  const schemasToProcess = [
789
852
  paramsType,
790
853
  pathParamsType,
@@ -87,7 +87,8 @@ export default {
87
87
  },
88
88
  apiDir: "./src/app/api",
89
89
  schemaDir: "./src",
90
- schemaType: "zod", // or "typescript"
90
+ schemaType: "zod", // or "typescript" or ["zod", "typescript"]
91
+ schemaFiles: [], // Optional: ["./openapi-models.yaml", "./schemas.json"]
91
92
  docsUrl: "api-docs",
92
93
  ui: "scalar",
93
94
  outputFile: "openapi.json",
package/dist/types.js CHANGED
@@ -1,2 +1 @@
1
1
  export {};
2
- // Test feature
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-openapi-gen",
3
- "version": "0.8.1",
3
+ "version": "0.8.3",
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",
@@ -55,9 +55,11 @@
55
55
  "@babel/types": "^7.28.2",
56
56
  "commander": "^14.0.0",
57
57
  "fs-extra": "^11.3.1",
58
+ "js-yaml": "^4.1.0",
58
59
  "ora": "^8.2.0"
59
60
  },
60
61
  "devDependencies": {
62
+ "@types/js-yaml": "^4.0.9",
61
63
  "@types/node": "^24.3.0",
62
64
  "@vitest/ui": "^3.2.4",
63
65
  "conventional-changelog-cli": "^5.0.0",