@eqxjs/swagger-codegen 1.0.0-beta.0
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/ARCHITECTURE.md +230 -0
- package/FORMATS.md +180 -0
- package/OPENAPI-COMPARISON.md +355 -0
- package/QUICKSTART.md +118 -0
- package/README.md +405 -0
- package/SUMMARY.md +184 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +49 -0
- package/dist/cli.js.map +1 -0
- package/dist/file-writer.d.ts +24 -0
- package/dist/file-writer.d.ts.map +1 -0
- package/dist/file-writer.js +95 -0
- package/dist/file-writer.js.map +1 -0
- package/dist/generator.d.ts +6 -0
- package/dist/generator.d.ts.map +1 -0
- package/dist/generator.js +104 -0
- package/dist/generator.js.map +1 -0
- package/dist/generators/client-service.generator.d.ts +6 -0
- package/dist/generators/client-service.generator.d.ts.map +1 -0
- package/dist/generators/client-service.generator.js +203 -0
- package/dist/generators/client-service.generator.js.map +1 -0
- package/dist/generators/controller.generator.d.ts +6 -0
- package/dist/generators/controller.generator.d.ts.map +1 -0
- package/dist/generators/controller.generator.js +241 -0
- package/dist/generators/controller.generator.js.map +1 -0
- package/dist/generators/dto.generator.d.ts +10 -0
- package/dist/generators/dto.generator.d.ts.map +1 -0
- package/dist/generators/dto.generator.js +221 -0
- package/dist/generators/dto.generator.js.map +1 -0
- package/dist/generators/module.generator.d.ts +10 -0
- package/dist/generators/module.generator.d.ts.map +1 -0
- package/dist/generators/module.generator.js +52 -0
- package/dist/generators/module.generator.js.map +1 -0
- package/dist/generators/service.generator.d.ts +6 -0
- package/dist/generators/service.generator.d.ts.map +1 -0
- package/dist/generators/service.generator.js +179 -0
- package/dist/generators/service.generator.js.map +1 -0
- package/dist/parser.d.ts +24 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +82 -0
- package/dist/parser.js.map +1 -0
- package/dist/types.d.ts +97 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +38 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +114 -0
- package/dist/utils.js.map +1 -0
- package/package.json +40 -0
- package/test-all-formats.sh +32 -0
- package/test.sh +27 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateService = generateService;
|
|
4
|
+
const utils_1 = require("../utils");
|
|
5
|
+
const parser_1 = require("../parser");
|
|
6
|
+
/**
|
|
7
|
+
* Generate a service for a specific tag/resource
|
|
8
|
+
*/
|
|
9
|
+
function generateService(tag, endpoints, spec) {
|
|
10
|
+
const serviceName = `${(0, utils_1.toPascalCase)(tag)}Service`;
|
|
11
|
+
const imports = new Set();
|
|
12
|
+
imports.add("import { Injectable } from '@nestjs/common';");
|
|
13
|
+
let serviceContent = `@Injectable()\nexport class ${serviceName} {\n`;
|
|
14
|
+
serviceContent += ` constructor() {}\n\n`;
|
|
15
|
+
// Generate methods for each endpoint
|
|
16
|
+
for (const endpoint of endpoints) {
|
|
17
|
+
const { method, path, operation } = endpoint;
|
|
18
|
+
const methodName = (0, utils_1.getOperationName)(path, method, operation.operationId);
|
|
19
|
+
const methodSignature = generateServiceMethod(methodName, path, operation, spec, imports);
|
|
20
|
+
serviceContent += methodSignature;
|
|
21
|
+
}
|
|
22
|
+
serviceContent += '}\n';
|
|
23
|
+
const content = `${Array.from(imports).join('\n')}\n\n${serviceContent}`;
|
|
24
|
+
return {
|
|
25
|
+
name: serviceName,
|
|
26
|
+
content,
|
|
27
|
+
imports,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Extract path parameters from a path
|
|
32
|
+
*/
|
|
33
|
+
function extractPathParams(path) {
|
|
34
|
+
const matches = path.match(/\{([^}]+)\}/g);
|
|
35
|
+
if (!matches)
|
|
36
|
+
return [];
|
|
37
|
+
return matches.map(match => match.slice(1, -1));
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Generate a service method signature
|
|
41
|
+
*/
|
|
42
|
+
function generateServiceMethod(methodName, path, operation, spec, imports) {
|
|
43
|
+
const parameters = [];
|
|
44
|
+
const comments = [];
|
|
45
|
+
// Add description if available
|
|
46
|
+
if (operation.summary || operation.description) {
|
|
47
|
+
comments.push(' /**');
|
|
48
|
+
if (operation.summary) {
|
|
49
|
+
comments.push(` * ${operation.summary}`);
|
|
50
|
+
}
|
|
51
|
+
if (operation.description && operation.description !== operation.summary) {
|
|
52
|
+
comments.push(` * ${operation.description}`);
|
|
53
|
+
}
|
|
54
|
+
comments.push(' */');
|
|
55
|
+
}
|
|
56
|
+
// Handle path parameters first
|
|
57
|
+
const pathParams = extractPathParams(path);
|
|
58
|
+
for (const param of pathParams) {
|
|
59
|
+
const paramName = (0, utils_1.toCamelCase)(param);
|
|
60
|
+
parameters.push(`${paramName}: string`);
|
|
61
|
+
}
|
|
62
|
+
// Handle query parameters
|
|
63
|
+
if (operation.parameters) {
|
|
64
|
+
for (const param of operation.parameters) {
|
|
65
|
+
if (!param.name)
|
|
66
|
+
continue; // Skip parameters without names
|
|
67
|
+
if (param.in !== 'query')
|
|
68
|
+
continue; // Only process query parameters
|
|
69
|
+
const paramName = (0, utils_1.toCamelCase)(param.name);
|
|
70
|
+
let paramType = 'any';
|
|
71
|
+
if (param.schema?.$ref) {
|
|
72
|
+
const refName = (0, parser_1.getSchemaNameFromRef)(param.schema.$ref);
|
|
73
|
+
paramType = (0, utils_1.toPascalCase)(refName);
|
|
74
|
+
imports.add(`import { ${paramType} } from '../dtos/${(0, utils_1.toKebabCase)(refName)}.dto';`);
|
|
75
|
+
}
|
|
76
|
+
else if (param.type) {
|
|
77
|
+
paramType = getTypeScriptType(param.type);
|
|
78
|
+
}
|
|
79
|
+
else if (param.schema?.type) {
|
|
80
|
+
paramType = getTypeScriptType(param.schema.type);
|
|
81
|
+
}
|
|
82
|
+
const optional = param.required === false ? '?' : '';
|
|
83
|
+
parameters.push(`${paramName}${optional}: ${paramType}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Handle request body (OpenAPI 3.x)
|
|
87
|
+
if (operation.requestBody) {
|
|
88
|
+
let requestBody = operation.requestBody;
|
|
89
|
+
// Resolve requestBody reference if it's a $ref
|
|
90
|
+
if (requestBody.$ref) {
|
|
91
|
+
const refPath = requestBody.$ref.split('/');
|
|
92
|
+
const refName = refPath[refPath.length - 1];
|
|
93
|
+
requestBody = spec.components?.requestBodies?.[refName] || requestBody;
|
|
94
|
+
}
|
|
95
|
+
const content = requestBody.content;
|
|
96
|
+
if (content) {
|
|
97
|
+
const jsonContent = content['application/json'];
|
|
98
|
+
if (jsonContent?.schema?.$ref) {
|
|
99
|
+
const refName = (0, parser_1.getSchemaNameFromRef)(jsonContent.schema.$ref);
|
|
100
|
+
const dtoName = (0, utils_1.toPascalCase)(refName);
|
|
101
|
+
imports.add(`import { ${dtoName} } from '../dtos/${(0, utils_1.toKebabCase)(refName)}.dto';`);
|
|
102
|
+
const optional = requestBody.required === false ? '?' : '';
|
|
103
|
+
parameters.push(`body${optional}: ${dtoName}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Determine return type
|
|
108
|
+
let returnType = 'Promise<any>';
|
|
109
|
+
const responses = operation.responses;
|
|
110
|
+
if (responses && responses['200']) {
|
|
111
|
+
const successResponse = responses['200'];
|
|
112
|
+
// OpenAPI 3.x
|
|
113
|
+
if (successResponse.content) {
|
|
114
|
+
const jsonContent = successResponse.content['application/json'];
|
|
115
|
+
if (jsonContent?.schema) {
|
|
116
|
+
if (jsonContent.schema.$ref) {
|
|
117
|
+
const refName = (0, parser_1.getSchemaNameFromRef)(jsonContent.schema.$ref);
|
|
118
|
+
const typeName = (0, utils_1.toPascalCase)(refName);
|
|
119
|
+
imports.add(`import { ${typeName} } from '../dtos/${(0, utils_1.toKebabCase)(refName)}.dto';`);
|
|
120
|
+
if (jsonContent.schema.type === 'array') {
|
|
121
|
+
returnType = `Promise<${typeName}[]>`;
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
returnType = `Promise<${typeName}>`;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else if (jsonContent.schema.type === 'array' && jsonContent.schema.items?.$ref) {
|
|
128
|
+
const refName = (0, parser_1.getSchemaNameFromRef)(jsonContent.schema.items.$ref);
|
|
129
|
+
const typeName = (0, utils_1.toPascalCase)(refName);
|
|
130
|
+
imports.add(`import { ${typeName} } from '../dtos/${(0, utils_1.toKebabCase)(refName)}.dto';`);
|
|
131
|
+
returnType = `Promise<${typeName}[]>`;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// Swagger 2.0
|
|
136
|
+
else if (successResponse.schema) {
|
|
137
|
+
if (successResponse.schema.$ref) {
|
|
138
|
+
const refName = (0, parser_1.getSchemaNameFromRef)(successResponse.schema.$ref);
|
|
139
|
+
const typeName = (0, utils_1.toPascalCase)(refName);
|
|
140
|
+
imports.add(`import { ${typeName} } from '../dtos/${(0, utils_1.toKebabCase)(refName)}.dto';`);
|
|
141
|
+
returnType = `Promise<${typeName}>`;
|
|
142
|
+
}
|
|
143
|
+
else if (successResponse.schema.type === 'array' && successResponse.schema.items?.$ref) {
|
|
144
|
+
const refName = (0, parser_1.getSchemaNameFromRef)(successResponse.schema.items.$ref);
|
|
145
|
+
const typeName = (0, utils_1.toPascalCase)(refName);
|
|
146
|
+
imports.add(`import { ${typeName} } from '../dtos/${(0, utils_1.toKebabCase)(refName)}.dto';`);
|
|
147
|
+
returnType = `Promise<${typeName}[]>`;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const paramsString = parameters.join(', ');
|
|
152
|
+
let methodSignature = '';
|
|
153
|
+
if (comments.length > 0) {
|
|
154
|
+
methodSignature += comments.join('\n') + '\n';
|
|
155
|
+
}
|
|
156
|
+
methodSignature += ` async ${methodName}(${paramsString}): ${returnType} {\n`;
|
|
157
|
+
methodSignature += ` // TODO: Implement ${methodName}\n`;
|
|
158
|
+
methodSignature += ` throw new Error('Method not implemented');\n`;
|
|
159
|
+
methodSignature += ` }\n\n`;
|
|
160
|
+
return methodSignature;
|
|
161
|
+
}
|
|
162
|
+
function getTypeScriptType(type) {
|
|
163
|
+
switch (type) {
|
|
164
|
+
case 'integer':
|
|
165
|
+
case 'number':
|
|
166
|
+
return 'number';
|
|
167
|
+
case 'string':
|
|
168
|
+
return 'string';
|
|
169
|
+
case 'boolean':
|
|
170
|
+
return 'boolean';
|
|
171
|
+
case 'array':
|
|
172
|
+
return 'any[]';
|
|
173
|
+
case 'object':
|
|
174
|
+
return 'Record<string, any>';
|
|
175
|
+
default:
|
|
176
|
+
return 'any';
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=service.generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.generator.js","sourceRoot":"","sources":["../../src/generators/service.generator.ts"],"names":[],"mappings":"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"}
|
package/dist/parser.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { SwaggerSpec, EndpointInfo } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Parse and bundle a Swagger/OpenAPI file
|
|
4
|
+
* Using bundle() instead of validate() to preserve $ref pointers
|
|
5
|
+
* while still validating and bundling external references
|
|
6
|
+
*/
|
|
7
|
+
export declare function parseSwaggerFile(filePath: string): Promise<SwaggerSpec>;
|
|
8
|
+
/**
|
|
9
|
+
* Get all definitions/schemas from the spec
|
|
10
|
+
*/
|
|
11
|
+
export declare function getSchemas(spec: SwaggerSpec): Record<string, any>;
|
|
12
|
+
/**
|
|
13
|
+
* Group endpoints by tag
|
|
14
|
+
*/
|
|
15
|
+
export declare function groupEndpointsByTag(spec: SwaggerSpec): Map<string, EndpointInfo[]>;
|
|
16
|
+
/**
|
|
17
|
+
* Resolve schema reference
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveSchemaRef(ref: string, spec: SwaggerSpec): any;
|
|
20
|
+
/**
|
|
21
|
+
* Get schema name from $ref
|
|
22
|
+
*/
|
|
23
|
+
export declare function getSchemaNameFromRef(ref: string): string;
|
|
24
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAoB,MAAM,SAAS,CAAC;AAGtE;;;;GAIG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAO7E;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAYjE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,WAAW,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CA6BlF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,GAAG,CASpE;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAExD"}
|
package/dist/parser.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseSwaggerFile = parseSwaggerFile;
|
|
4
|
+
exports.getSchemas = getSchemas;
|
|
5
|
+
exports.groupEndpointsByTag = groupEndpointsByTag;
|
|
6
|
+
exports.resolveSchemaRef = resolveSchemaRef;
|
|
7
|
+
exports.getSchemaNameFromRef = getSchemaNameFromRef;
|
|
8
|
+
const SwaggerParser = require('swagger-parser');
|
|
9
|
+
const utils_1 = require("./utils");
|
|
10
|
+
/**
|
|
11
|
+
* Parse and bundle a Swagger/OpenAPI file
|
|
12
|
+
* Using bundle() instead of validate() to preserve $ref pointers
|
|
13
|
+
* while still validating and bundling external references
|
|
14
|
+
*/
|
|
15
|
+
async function parseSwaggerFile(filePath) {
|
|
16
|
+
try {
|
|
17
|
+
const api = await SwaggerParser.bundle(filePath);
|
|
18
|
+
return api;
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
throw new Error(`Failed to parse Swagger file: ${error instanceof Error ? error.message : String(error)}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get all definitions/schemas from the spec
|
|
26
|
+
*/
|
|
27
|
+
function getSchemas(spec) {
|
|
28
|
+
// OpenAPI 3.x uses components.schemas
|
|
29
|
+
if (spec.components?.schemas) {
|
|
30
|
+
return spec.components.schemas;
|
|
31
|
+
}
|
|
32
|
+
// Swagger 2.0 uses definitions
|
|
33
|
+
if (spec.definitions) {
|
|
34
|
+
return spec.definitions;
|
|
35
|
+
}
|
|
36
|
+
return {};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Group endpoints by tag
|
|
40
|
+
*/
|
|
41
|
+
function groupEndpointsByTag(spec) {
|
|
42
|
+
const endpointsByTag = new Map();
|
|
43
|
+
for (const [path, pathItem] of Object.entries(spec.paths)) {
|
|
44
|
+
const methods = ['get', 'post', 'put', 'patch', 'delete'];
|
|
45
|
+
for (const method of methods) {
|
|
46
|
+
const operation = pathItem[method];
|
|
47
|
+
if (operation) {
|
|
48
|
+
const tags = operation.tags || [(0, utils_1.extractTagFromPath)(path)];
|
|
49
|
+
for (const tag of tags) {
|
|
50
|
+
if (!endpointsByTag.has(tag)) {
|
|
51
|
+
endpointsByTag.set(tag, []);
|
|
52
|
+
}
|
|
53
|
+
endpointsByTag.get(tag).push({
|
|
54
|
+
method,
|
|
55
|
+
path,
|
|
56
|
+
operation,
|
|
57
|
+
tag,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return endpointsByTag;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Resolve schema reference
|
|
67
|
+
*/
|
|
68
|
+
function resolveSchemaRef(ref, spec) {
|
|
69
|
+
const schemas = getSchemas(spec);
|
|
70
|
+
const refName = ref.split('/').pop();
|
|
71
|
+
if (refName && schemas[refName]) {
|
|
72
|
+
return schemas[refName];
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Get schema name from $ref
|
|
78
|
+
*/
|
|
79
|
+
function getSchemaNameFromRef(ref) {
|
|
80
|
+
return ref.split('/').pop() || 'Unknown';
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":";;AASA,4CAOC;AAKD,gCAYC;AAKD,kDA6BC;AAKD,4CASC;AAKD,oDAEC;AAxFD,MAAM,aAAa,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAEhD,mCAA6C;AAE7C;;;;GAIG;AACI,KAAK,UAAU,gBAAgB,CAAC,QAAgB;IACrD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACjD,OAAO,GAAkB,CAAC;IAC5B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,iCAAiC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC7G,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,UAAU,CAAC,IAAiB;IAC1C,sCAAsC;IACtC,IAAI,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,CAAC;QAC7B,OAAO,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;IACjC,CAAC;IAED,+BAA+B;IAC/B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB,CAAC,IAAiB;IACnD,MAAM,cAAc,GAAG,IAAI,GAAG,EAA0B,CAAC;IAEzD,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1D,MAAM,OAAO,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAU,CAAC;QAEnE,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC7B,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAiC,CAAC;YAEnE,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,IAAI,CAAC,IAAA,0BAAkB,EAAC,IAAI,CAAC,CAAC,CAAC;gBAE1D,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;wBAC7B,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;oBAC9B,CAAC;oBAED,cAAc,CAAC,GAAG,CAAC,GAAG,CAAE,CAAC,IAAI,CAAC;wBAC5B,MAAM;wBACN,IAAI;wBACJ,SAAS;wBACT,GAAG;qBACJ,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,cAAc,CAAC;AACxB,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,GAAW,EAAE,IAAiB;IAC7D,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IAErC,IAAI,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAChC,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAAC,GAAW;IAC9C,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,SAAS,CAAC;AAC3C,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
export interface SwaggerSchema {
|
|
2
|
+
type?: string;
|
|
3
|
+
format?: string;
|
|
4
|
+
properties?: Record<string, SwaggerSchema>;
|
|
5
|
+
items?: SwaggerSchema;
|
|
6
|
+
required?: string[];
|
|
7
|
+
enum?: any[];
|
|
8
|
+
$ref?: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
allOf?: SwaggerSchema[];
|
|
11
|
+
oneOf?: SwaggerSchema[];
|
|
12
|
+
anyOf?: SwaggerSchema[];
|
|
13
|
+
}
|
|
14
|
+
export interface SwaggerParameter {
|
|
15
|
+
name: string;
|
|
16
|
+
in: 'query' | 'path' | 'body' | 'header' | 'formData';
|
|
17
|
+
required?: boolean;
|
|
18
|
+
type?: string;
|
|
19
|
+
schema?: SwaggerSchema;
|
|
20
|
+
description?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface SwaggerResponse {
|
|
23
|
+
description: string;
|
|
24
|
+
schema?: SwaggerSchema;
|
|
25
|
+
content?: Record<string, {
|
|
26
|
+
schema?: SwaggerSchema;
|
|
27
|
+
}>;
|
|
28
|
+
}
|
|
29
|
+
export interface SwaggerOperation {
|
|
30
|
+
operationId?: string;
|
|
31
|
+
summary?: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
tags?: string[];
|
|
34
|
+
parameters?: SwaggerParameter[];
|
|
35
|
+
requestBody?: {
|
|
36
|
+
required?: boolean;
|
|
37
|
+
content?: Record<string, {
|
|
38
|
+
schema?: SwaggerSchema;
|
|
39
|
+
}>;
|
|
40
|
+
};
|
|
41
|
+
responses: Record<string, SwaggerResponse>;
|
|
42
|
+
}
|
|
43
|
+
export interface SwaggerPath {
|
|
44
|
+
get?: SwaggerOperation;
|
|
45
|
+
post?: SwaggerOperation;
|
|
46
|
+
put?: SwaggerOperation;
|
|
47
|
+
patch?: SwaggerOperation;
|
|
48
|
+
delete?: SwaggerOperation;
|
|
49
|
+
}
|
|
50
|
+
export interface SwaggerDefinition {
|
|
51
|
+
type?: string;
|
|
52
|
+
properties?: Record<string, SwaggerSchema>;
|
|
53
|
+
required?: string[];
|
|
54
|
+
allOf?: SwaggerSchema[];
|
|
55
|
+
description?: string;
|
|
56
|
+
}
|
|
57
|
+
export interface SwaggerSpec {
|
|
58
|
+
swagger?: string;
|
|
59
|
+
openapi?: string;
|
|
60
|
+
info: {
|
|
61
|
+
title: string;
|
|
62
|
+
version: string;
|
|
63
|
+
};
|
|
64
|
+
paths: Record<string, SwaggerPath>;
|
|
65
|
+
definitions?: Record<string, SwaggerDefinition>;
|
|
66
|
+
components?: {
|
|
67
|
+
schemas?: Record<string, SwaggerDefinition>;
|
|
68
|
+
requestBodies?: Record<string, any>;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
export interface GeneratedDto {
|
|
72
|
+
name: string;
|
|
73
|
+
content: string;
|
|
74
|
+
imports: Set<string>;
|
|
75
|
+
}
|
|
76
|
+
export interface GeneratedService {
|
|
77
|
+
name: string;
|
|
78
|
+
content: string;
|
|
79
|
+
imports: Set<string>;
|
|
80
|
+
}
|
|
81
|
+
export interface GeneratedController {
|
|
82
|
+
name: string;
|
|
83
|
+
content: string;
|
|
84
|
+
imports: Set<string>;
|
|
85
|
+
}
|
|
86
|
+
export interface GeneratedModule {
|
|
87
|
+
name: string;
|
|
88
|
+
content: string;
|
|
89
|
+
imports: Set<string>;
|
|
90
|
+
}
|
|
91
|
+
export interface EndpointInfo {
|
|
92
|
+
method: string;
|
|
93
|
+
path: string;
|
|
94
|
+
operation: SwaggerOperation;
|
|
95
|
+
tag: string;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC3C,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,CAAC;IACtD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,MAAM,CAAC,EAAE,aAAa,CAAA;KAAE,CAAC,CAAC;CACtD;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,UAAU,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAChC,WAAW,CAAC,EAAE;QACZ,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;YAAE,MAAM,CAAC,EAAE,aAAa,CAAA;SAAE,CAAC,CAAC;KACtD,CAAC;IACF,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,gBAAgB,CAAC;IACvB,IAAI,CAAC,EAAE,gBAAgB,CAAC;IACxB,GAAG,CAAC,EAAE,gBAAgB,CAAC;IACvB,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACnC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;IAChD,UAAU,CAAC,EAAE;QACX,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;QAC5C,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;KACrC,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,gBAAgB,CAAC;IAC5B,GAAG,EAAE,MAAM,CAAC;CACb"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a string to PascalCase
|
|
3
|
+
*/
|
|
4
|
+
export declare function toPascalCase(str: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* Convert a string to camelCase
|
|
7
|
+
*/
|
|
8
|
+
export declare function toCamelCase(str: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Convert a string to kebab-case
|
|
11
|
+
*/
|
|
12
|
+
export declare function toKebabCase(str: string): string;
|
|
13
|
+
/**
|
|
14
|
+
* Extract tag name from path
|
|
15
|
+
*/
|
|
16
|
+
export declare function extractTagFromPath(path: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Get TypeScript type from Swagger type
|
|
19
|
+
*/
|
|
20
|
+
export declare function getTypeScriptType(type?: string, format?: string): string;
|
|
21
|
+
/**
|
|
22
|
+
* Sanitize name for use as identifier
|
|
23
|
+
*/
|
|
24
|
+
export declare function sanitizeName(name: string): string;
|
|
25
|
+
/**
|
|
26
|
+
* Extract operation name from path and method
|
|
27
|
+
*/
|
|
28
|
+
export declare function getOperationName(path: string, method: string, operationId?: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* Get decorator for HTTP method
|
|
31
|
+
*/
|
|
32
|
+
export declare function getHttpDecorator(method: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Convert path parameters to NestJS format
|
|
35
|
+
* Example: /users/{id} => /users/:id
|
|
36
|
+
*/
|
|
37
|
+
export declare function convertPathParams(path: string): string;
|
|
38
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAMhD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM/C;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGvD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAqBxE;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAW3F;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAUvD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEtD"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toPascalCase = toPascalCase;
|
|
4
|
+
exports.toCamelCase = toCamelCase;
|
|
5
|
+
exports.toKebabCase = toKebabCase;
|
|
6
|
+
exports.extractTagFromPath = extractTagFromPath;
|
|
7
|
+
exports.getTypeScriptType = getTypeScriptType;
|
|
8
|
+
exports.sanitizeName = sanitizeName;
|
|
9
|
+
exports.getOperationName = getOperationName;
|
|
10
|
+
exports.getHttpDecorator = getHttpDecorator;
|
|
11
|
+
exports.convertPathParams = convertPathParams;
|
|
12
|
+
/**
|
|
13
|
+
* Convert a string to PascalCase
|
|
14
|
+
*/
|
|
15
|
+
function toPascalCase(str) {
|
|
16
|
+
if (!str)
|
|
17
|
+
return '';
|
|
18
|
+
return str
|
|
19
|
+
.replace(/[-_\s]+(.)?/g, (_, char) => (char ? char.toUpperCase() : ''))
|
|
20
|
+
.replace(/^(.)/, (char) => char.toUpperCase())
|
|
21
|
+
.replace(/[^a-zA-Z0-9]/g, '');
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Convert a string to camelCase
|
|
25
|
+
*/
|
|
26
|
+
function toCamelCase(str) {
|
|
27
|
+
if (!str)
|
|
28
|
+
return '';
|
|
29
|
+
const pascal = toPascalCase(str);
|
|
30
|
+
return pascal.charAt(0).toLowerCase() + pascal.slice(1);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Convert a string to kebab-case
|
|
34
|
+
*/
|
|
35
|
+
function toKebabCase(str) {
|
|
36
|
+
if (!str)
|
|
37
|
+
return '';
|
|
38
|
+
return str
|
|
39
|
+
.replace(/([a-z])([A-Z])/g, '$1-$2')
|
|
40
|
+
.replace(/[\s_]+/g, '-')
|
|
41
|
+
.toLowerCase();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Extract tag name from path
|
|
45
|
+
*/
|
|
46
|
+
function extractTagFromPath(path) {
|
|
47
|
+
const parts = path.split('/').filter(p => p && !p.startsWith('{'));
|
|
48
|
+
return parts[0] || 'default';
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get TypeScript type from Swagger type
|
|
52
|
+
*/
|
|
53
|
+
function getTypeScriptType(type, format) {
|
|
54
|
+
if (!type)
|
|
55
|
+
return 'any';
|
|
56
|
+
switch (type) {
|
|
57
|
+
case 'integer':
|
|
58
|
+
case 'number':
|
|
59
|
+
return 'number';
|
|
60
|
+
case 'string':
|
|
61
|
+
if (format === 'date' || format === 'date-time') {
|
|
62
|
+
return 'Date';
|
|
63
|
+
}
|
|
64
|
+
return 'string';
|
|
65
|
+
case 'boolean':
|
|
66
|
+
return 'boolean';
|
|
67
|
+
case 'array':
|
|
68
|
+
return 'any[]';
|
|
69
|
+
case 'object':
|
|
70
|
+
return 'Record<string, any>';
|
|
71
|
+
default:
|
|
72
|
+
return 'any';
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Sanitize name for use as identifier
|
|
77
|
+
*/
|
|
78
|
+
function sanitizeName(name) {
|
|
79
|
+
return name.replace(/[^a-zA-Z0-9_]/g, '_');
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Extract operation name from path and method
|
|
83
|
+
*/
|
|
84
|
+
function getOperationName(path, method, operationId) {
|
|
85
|
+
if (operationId) {
|
|
86
|
+
return toCamelCase(operationId);
|
|
87
|
+
}
|
|
88
|
+
// Remove parameters from path
|
|
89
|
+
const cleanPath = path.replace(/\{[^}]+\}/g, '');
|
|
90
|
+
const parts = cleanPath.split('/').filter(p => p);
|
|
91
|
+
const resource = parts[parts.length - 1] || 'resource';
|
|
92
|
+
return toCamelCase(`${method}-${resource}`);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get decorator for HTTP method
|
|
96
|
+
*/
|
|
97
|
+
function getHttpDecorator(method) {
|
|
98
|
+
const methodMap = {
|
|
99
|
+
get: 'Get',
|
|
100
|
+
post: 'Post',
|
|
101
|
+
put: 'Put',
|
|
102
|
+
patch: 'Patch',
|
|
103
|
+
delete: 'Delete',
|
|
104
|
+
};
|
|
105
|
+
return methodMap[method.toLowerCase()] || 'Get';
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Convert path parameters to NestJS format
|
|
109
|
+
* Example: /users/{id} => /users/:id
|
|
110
|
+
*/
|
|
111
|
+
function convertPathParams(path) {
|
|
112
|
+
return path.replace(/\{([^}]+)\}/g, ':$1');
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@eqxjs/swagger-codegen",
|
|
3
|
+
"version": "1.0.0-beta.0",
|
|
4
|
+
"description": "CLI tool to generate NestJS modules, controllers, services, and DTOs from Swagger/OpenAPI files",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"eqxjs-swagger-codegen": "./dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"start": "node dist/cli.js",
|
|
12
|
+
"dev": "ts-node src/cli.ts",
|
|
13
|
+
"watch": "tsc -w",
|
|
14
|
+
"test": "./test.sh",
|
|
15
|
+
"test:all": "./test-all-formats.sh",
|
|
16
|
+
"clean": "rm -rf dist generated"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"swagger",
|
|
20
|
+
"openapi",
|
|
21
|
+
"nestjs",
|
|
22
|
+
"codegen",
|
|
23
|
+
"cli"
|
|
24
|
+
],
|
|
25
|
+
"author": "",
|
|
26
|
+
"license": "MIT",
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"commander": "^11.1.0",
|
|
29
|
+
"swagger-parser": "^10.0.3",
|
|
30
|
+
"chalk": "^4.1.2",
|
|
31
|
+
"fs-extra": "^11.2.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/fs-extra": "^11.0.4",
|
|
35
|
+
"@types/node": "^20.10.6",
|
|
36
|
+
"@types/swagger-parser": "^7.0.1",
|
|
37
|
+
"ts-node": "^10.9.2",
|
|
38
|
+
"typescript": "^5.3.3"
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
echo "╔════════════════════════════════════════════════════════════╗"
|
|
4
|
+
echo "║ Testing All Format Combinations ║"
|
|
5
|
+
echo "╚════════════════════════════════════════════════════════════╝"
|
|
6
|
+
echo ""
|
|
7
|
+
|
|
8
|
+
test_format() {
|
|
9
|
+
local name=$1
|
|
10
|
+
local input=$2
|
|
11
|
+
local output=$3
|
|
12
|
+
|
|
13
|
+
echo "📋 Testing: $name"
|
|
14
|
+
npm run dev -- generate -i "$input" -o "$output" 2>&1 | grep -E "(✅|Error)" | head -2
|
|
15
|
+
|
|
16
|
+
if [ -d "$output" ]; then
|
|
17
|
+
local dtos=$(find "$output/dtos" -name "*.dto.ts" 2>/dev/null | wc -l)
|
|
18
|
+
local features=$(find "$output" -mindepth 1 -maxdepth 1 -type d ! -name "dtos" 2>/dev/null | wc -l)
|
|
19
|
+
echo " Generated: $dtos DTOs, $features Feature modules"
|
|
20
|
+
rm -rf "$output"
|
|
21
|
+
fi
|
|
22
|
+
echo ""
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
test_format "Swagger 2.0 (JSON)" "./example-swagger.json" "./test-swagger2-json"
|
|
26
|
+
test_format "Swagger 2.0 (YAML)" "./example-swagger.yaml" "./test-swagger2-yaml"
|
|
27
|
+
test_format "OpenAPI 3.0 (JSON)" "./openapi3-example.json" "./test-openapi3-json"
|
|
28
|
+
test_format "OpenAPI 3.0 (YAML)" "./openapi3-example.yaml" "./test-openapi3-yaml"
|
|
29
|
+
|
|
30
|
+
echo "╔════════════════════════════════════════════════════════════╗"
|
|
31
|
+
echo "║ All Format Tests Completed Successfully! ✅ ║"
|
|
32
|
+
echo "╚════════════════════════════════════════════════════════════╝"
|