next-openapi-gen 0.8.1 → 0.8.2
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 +74 -48
- package/dist/lib/openapi-generator.js +2 -1
- package/dist/lib/route-processor.js +1 -1
- package/dist/lib/schema-processor.js +81 -18
- package/dist/openapi-template.js +2 -1
- package/dist/types.js +0 -1
- package/package.json +3 -1
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
|
|
8
|
-
- ✅
|
|
9
|
-
- ✅
|
|
10
|
-
- ✅
|
|
11
|
-
- ✅
|
|
12
|
-
- ✅
|
|
13
|
-
- ✅
|
|
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
|
|
|
@@ -59,7 +56,8 @@ During initialization (`npx next-openapi-gen init`), a configuration file `next.
|
|
|
59
56
|
],
|
|
60
57
|
"apiDir": "src/app/api",
|
|
61
58
|
"schemaDir": "src/types", // or "src/schemas" for Zod schemas
|
|
62
|
-
"schemaType": "zod", // or "typescript" for
|
|
59
|
+
"schemaType": "zod", // or "typescript", or ["zod", "typescript"] for multiple
|
|
60
|
+
"schemaFiles": [], // Optional: ["./schemas/models.yaml", "./schemas/api.json"]
|
|
63
61
|
"outputFile": "openapi.json",
|
|
64
62
|
"outputDir": "./public",
|
|
65
63
|
"docsUrl": "/api-docs",
|
|
@@ -71,20 +69,21 @@ During initialization (`npx next-openapi-gen init`), a configuration file `next.
|
|
|
71
69
|
|
|
72
70
|
### Configuration Options
|
|
73
71
|
|
|
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
|
-
| `
|
|
80
|
-
| `
|
|
81
|
-
| `
|
|
82
|
-
| `
|
|
83
|
-
| `
|
|
84
|
-
| `
|
|
85
|
-
| `
|
|
86
|
-
| `
|
|
87
|
-
| `
|
|
72
|
+
| Option | Description |
|
|
73
|
+
| ---------------------- | ----------------------------------------------------------------------------- |
|
|
74
|
+
| `apiDir` | Path to the API directory |
|
|
75
|
+
| `schemaDir` | Path to the types/schemas directory |
|
|
76
|
+
| `schemaType` | Schema type: `"zod"`, `"typescript"`, or `["zod", "typescript"]` for multiple |
|
|
77
|
+
| `schemaFiles` | Optional: Array of custom OpenAPI schema files (YAML/JSON) to include |
|
|
78
|
+
| `outputFile` | Name of the OpenAPI output file |
|
|
79
|
+
| `outputDir` | Directory where OpenAPI file will be generated (default: `"./public"`) |
|
|
80
|
+
| `docsUrl` | API documentation URL (for Swagger UI) |
|
|
81
|
+
| `includeOpenApiRoutes` | Whether to include only routes with @openapi tag |
|
|
82
|
+
| `ignoreRoutes` | Array of route patterns to exclude from documentation (supports wildcards) |
|
|
83
|
+
| `defaultResponseSet` | Default error response set for all endpoints |
|
|
84
|
+
| `responseSets` | Named sets of error response codes |
|
|
85
|
+
| `errorConfig` | Error schema configuration |
|
|
86
|
+
| `debug` | Enable detailed logging during generation |
|
|
88
87
|
|
|
89
88
|
## Documenting Your API
|
|
90
89
|
|
|
@@ -766,19 +765,61 @@ export const CreatePostSchema = createInsertSchema(posts, {
|
|
|
766
765
|
|
|
767
766
|
See the [complete Drizzle-Zod example](./examples/next15-app-drizzle-zod) for a full working implementation with a blog API.
|
|
768
767
|
|
|
768
|
+
## Multiple Schema Types Support 🆕
|
|
769
|
+
|
|
770
|
+
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.
|
|
771
|
+
|
|
772
|
+
### Configuration
|
|
773
|
+
|
|
774
|
+
```json
|
|
775
|
+
{
|
|
776
|
+
"schemaType": ["zod", "typescript"],
|
|
777
|
+
"schemaDir": "./src/schemas",
|
|
778
|
+
"schemaFiles": ["./schemas/external-api.yaml"]
|
|
779
|
+
}
|
|
780
|
+
```
|
|
781
|
+
|
|
782
|
+
### Schema Resolution Priority
|
|
783
|
+
|
|
784
|
+
1. **Custom files** (highest) - from `schemaFiles` array
|
|
785
|
+
2. **Zod schemas** (medium) - if `"zod"` in `schemaType`
|
|
786
|
+
3. **TypeScript types** (fallback) - if `"typescript"` in `schemaType`
|
|
787
|
+
|
|
788
|
+
### Common Use Cases
|
|
789
|
+
|
|
790
|
+
```json
|
|
791
|
+
// Gradual TypeScript → Zod migration
|
|
792
|
+
{ "schemaType": ["zod", "typescript"] }
|
|
793
|
+
|
|
794
|
+
// Zod + protobuf schemas
|
|
795
|
+
{
|
|
796
|
+
"schemaType": ["zod"],
|
|
797
|
+
"schemaFiles": ["./proto/schemas.yaml"]
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
// Everything together
|
|
801
|
+
{
|
|
802
|
+
"schemaType": ["zod", "typescript"],
|
|
803
|
+
"schemaFiles": ["./openapi-models.yaml"]
|
|
804
|
+
}
|
|
805
|
+
```
|
|
806
|
+
|
|
807
|
+
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.
|
|
808
|
+
|
|
769
809
|
## Examples
|
|
770
810
|
|
|
771
811
|
This repository includes several complete example projects:
|
|
772
812
|
|
|
773
813
|
### 📦 Available Examples
|
|
774
814
|
|
|
775
|
-
| Example | Description
|
|
776
|
-
| --------------------------------------------------------------- |
|
|
777
|
-
| **[next15-app-zod](./examples/next15-app-zod)** | Zod schemas example
|
|
778
|
-
| **[next15-app-drizzle-zod](./examples/next15-app-drizzle-zod)** | Drizzle-Zod integration
|
|
779
|
-
| **[next15-app-
|
|
780
|
-
| **[next15-app-
|
|
781
|
-
| **[next15-app-
|
|
815
|
+
| Example | Description | Features |
|
|
816
|
+
| --------------------------------------------------------------- | ----------------------- | ----------------------------------------------- |
|
|
817
|
+
| **[next15-app-zod](./examples/next15-app-zod)** | Zod schemas example | Users, Products, Orders API with Zod validation |
|
|
818
|
+
| **[next15-app-drizzle-zod](./examples/next15-app-drizzle-zod)** | Drizzle-Zod integration | Blog API with Drizzle ORM + drizzle-zod |
|
|
819
|
+
| **[next15-app-mixed-schemas](./examples/next15-app-mixed-schemas)** 🆕 | Multiple schema types | Zod + TypeScript + Custom YAML schemas combined |
|
|
820
|
+
| **[next15-app-typescript](./examples/next15-app-typescript)** | TypeScript types | API with pure TypeScript type definitions |
|
|
821
|
+
| **[next15-app-scalar](./examples/next15-app-scalar)** | Scalar UI | Modern API documentation interface |
|
|
822
|
+
| **[next15-app-swagger](./examples/next15-app-swagger)** | Swagger UI | Classic Swagger documentation |
|
|
782
823
|
|
|
783
824
|
### 🚀 Running Examples
|
|
784
825
|
|
|
@@ -824,26 +865,11 @@ Visit `http://localhost:3000/api-docs` to see the generated documentation.
|
|
|
824
865
|
</table>
|
|
825
866
|
</div>
|
|
826
867
|
|
|
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
868
|
## Contributing
|
|
838
869
|
|
|
839
870
|
We welcome contributions! 🎉
|
|
840
871
|
|
|
841
|
-
Please read our [Contributing Guide](CONTRIBUTING.md) for details
|
|
842
|
-
|
|
843
|
-
- 📝 Commit message guidelines (Conventional Commits)
|
|
844
|
-
- 🔧 Development setup
|
|
845
|
-
- ✅ Pull request process
|
|
846
|
-
- 🚀 Release workflow
|
|
872
|
+
Please read our [Contributing Guide](CONTRIBUTING.md) for details.
|
|
847
873
|
|
|
848
874
|
## Changelog
|
|
849
875
|
|
|
@@ -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
|
-
|
|
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.
|
|
25
|
-
if
|
|
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
|
-
|
|
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
|
-
|
|
41
|
-
|
|
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
|
-
|
|
44
|
-
...filteredSchemas,
|
|
45
|
-
...zodSchemas,
|
|
46
|
-
};
|
|
101
|
+
Object.assign(merged, zodSchemas);
|
|
47
102
|
}
|
|
48
|
-
|
|
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
|
|
59
|
-
if (this.
|
|
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.
|
|
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.
|
|
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.
|
|
850
|
+
if (this.schemaTypes.includes("zod")) {
|
|
788
851
|
const schemasToProcess = [
|
|
789
852
|
paramsType,
|
|
790
853
|
pathParamsType,
|
package/dist/openapi-template.js
CHANGED
|
@@ -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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next-openapi-gen",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.2",
|
|
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",
|