@devlearning/swagger-generator 1.1.15 → 1.1.17
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/.vscode/launch.json +28 -28
- package/README-OLD.md +209 -209
- package/README.md +277 -277
- package/dist/api.constants.js +22 -22
- package/dist/generator.d.ts +4 -0
- package/dist/generator.js +118 -4
- package/dist/generators-writers/angular/api-angular-writer.js +38 -38
- package/dist/generators-writers/angular/constants.js +24 -24
- package/dist/generators-writers/angular/model-angular-writer.js +6 -6
- package/dist/generators-writers/dart/model-dart-writer.d.ts +1 -0
- package/dist/generators-writers/dart/model-dart-writer.js +13 -0
- package/dist/generators-writers/dart/templates/api.mustache +143 -143
- package/dist/generators-writers/dart/templates/enum.mustache +14 -14
- package/dist/generators-writers/dart/templates/model.mustache +20 -20
- package/dist/generators-writers/nextjs/api-nextjs-writer.js +12 -12
- package/dist/generators-writers/nextjs/constants.js +4 -4
- package/dist/generators-writers/nextjs/model-nextjs-writer.js +6 -6
- package/dist/models/swagger/swagger-component.d.ts +2 -2
- package/dist/models/swagger/swagger-schema.d.ts +1 -0
- package/package.json +49 -49
- package/src/api.constants.ts +26 -26
- package/src/generator-old.ts +449 -449
- package/src/generator.ts +752 -625
- package/src/generators-writers/angular/api-angular-writer.ts +187 -187
- package/src/generators-writers/angular/constants.ts +36 -36
- package/src/generators-writers/angular/model-angular-writer.ts +65 -65
- package/src/generators-writers/angular/normalizator.ts +41 -41
- package/src/generators-writers/dart/api-dart-writer.ts +303 -303
- package/src/generators-writers/dart/model-dart-writer.ts +212 -195
- package/src/generators-writers/dart/models/import-definition-dart.ts +5 -5
- package/src/generators-writers/dart/normalizator.ts +72 -72
- package/src/generators-writers/dart/templates/api.mustache +143 -143
- package/src/generators-writers/dart/templates/enum.mustache +14 -14
- package/src/generators-writers/dart/templates/model.mustache +20 -20
- package/src/generators-writers/nextjs/api-nextjs-writer.ts +157 -157
- package/src/generators-writers/nextjs/constants.ts +5 -5
- package/src/generators-writers/nextjs/model-nextjs-writer.ts +61 -61
- package/src/generators-writers/utils.ts +93 -93
- package/src/index.ts +103 -103
- package/src/models/api-dto.ts +17 -17
- package/src/models/enum-value-dto.ts +3 -3
- package/src/models/model-dto.ts +9 -9
- package/src/models/parameter-dto.ts +7 -7
- package/src/models/property-dto.ts +4 -4
- package/src/models/swagger/swagger-component-property.ts +11 -11
- package/src/models/swagger/swagger-component.ts +17 -17
- package/src/models/swagger/swagger-content.ts +4 -4
- package/src/models/swagger/swagger-info.ts +3 -3
- package/src/models/swagger/swagger-method.ts +7 -7
- package/src/models/swagger/swagger-schema.ts +21 -20
- package/src/models/swagger/swagger.ts +38 -38
- package/src/models/type-dto.ts +7 -7
- package/src/swagger-downloader.ts +46 -46
- package/src/utils/logger.ts +73 -73
- package/src/utils/swagger-validator.ts +89 -89
- package/tsconfig.json +33 -33
- package/dist/templates/api.mustache +0 -29
- package/dist/templates/model.mustache +0 -18
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
// import { SwaggerComponentProperty } from "./swagger-component-property.js";
|
|
2
|
-
|
|
3
|
-
import { SwaggerSchema } from "./swagger-schema.js";
|
|
4
|
-
|
|
5
|
-
// export interface SwaggerComponent {
|
|
6
|
-
// type: string;
|
|
7
|
-
// properties: { [key: string]: SwaggerComponentProperty; };
|
|
8
|
-
// additionalProperties: boolean;
|
|
9
|
-
// enum: string[];
|
|
10
|
-
// }
|
|
11
|
-
|
|
12
|
-
export interface SwaggerComponent {
|
|
13
|
-
type: string;
|
|
14
|
-
properties: { [key: string]: SwaggerSchema; };
|
|
15
|
-
additionalProperties: boolean;
|
|
16
|
-
enum
|
|
17
|
-
required
|
|
1
|
+
// import { SwaggerComponentProperty } from "./swagger-component-property.js";
|
|
2
|
+
|
|
3
|
+
import { SwaggerSchema } from "./swagger-schema.js";
|
|
4
|
+
|
|
5
|
+
// export interface SwaggerComponent {
|
|
6
|
+
// type: string;
|
|
7
|
+
// properties: { [key: string]: SwaggerComponentProperty; };
|
|
8
|
+
// additionalProperties: boolean;
|
|
9
|
+
// enum: string[];
|
|
10
|
+
// }
|
|
11
|
+
|
|
12
|
+
export interface SwaggerComponent {
|
|
13
|
+
type: string;
|
|
14
|
+
properties: { [key: string]: SwaggerSchema; };
|
|
15
|
+
additionalProperties: boolean;
|
|
16
|
+
enum?: Array<string | number>;
|
|
17
|
+
required?: string[];
|
|
18
18
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { SwaggerSchema } from "./swagger-schema.js";
|
|
2
|
-
|
|
3
|
-
export interface SwaggerContent {
|
|
4
|
-
schema: SwaggerSchema;
|
|
1
|
+
import { SwaggerSchema } from "./swagger-schema.js";
|
|
2
|
+
|
|
3
|
+
export interface SwaggerContent {
|
|
4
|
+
schema: SwaggerSchema;
|
|
5
5
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export interface SwaggerInfo {
|
|
2
|
-
title: string;
|
|
3
|
-
version: string;
|
|
1
|
+
export interface SwaggerInfo {
|
|
2
|
+
title: string;
|
|
3
|
+
version: string;
|
|
4
4
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { SwaggerParameter, SwaggerRequestBody, SwaggerResponses } from "./swagger.js";
|
|
2
|
-
|
|
3
|
-
export interface SwaggerMethod {
|
|
4
|
-
tags: string[];
|
|
5
|
-
parameters: SwaggerParameter[];
|
|
6
|
-
requestBody: SwaggerRequestBody;
|
|
7
|
-
responses: { [key: string]: SwaggerResponses; };
|
|
1
|
+
import { SwaggerParameter, SwaggerRequestBody, SwaggerResponses } from "./swagger.js";
|
|
2
|
+
|
|
3
|
+
export interface SwaggerMethod {
|
|
4
|
+
tags: string[];
|
|
5
|
+
parameters: SwaggerParameter[];
|
|
6
|
+
requestBody: SwaggerRequestBody;
|
|
7
|
+
responses: { [key: string]: SwaggerResponses; };
|
|
8
8
|
}
|
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
// import { SwaggerComponentProperty } from "./swagger-component-property.js";
|
|
2
|
-
|
|
3
|
-
// export interface SwaggerSchema {
|
|
4
|
-
// type: string;
|
|
5
|
-
// $ref: string;
|
|
6
|
-
// allOf: SwaggerSchema[];
|
|
7
|
-
// format: string;
|
|
8
|
-
// items: SwaggerSchema;
|
|
9
|
-
// properties: { [key: string]: SwaggerComponentProperty; };
|
|
10
|
-
// }
|
|
11
|
-
|
|
12
|
-
export interface SwaggerSchema {
|
|
13
|
-
type?: string;
|
|
14
|
-
$ref?: string;
|
|
15
|
-
allOf?: SwaggerSchema[];
|
|
16
|
-
format?: string;
|
|
17
|
-
items?: SwaggerSchema;
|
|
18
|
-
properties?: { [key: string]: SwaggerSchema };
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
// import { SwaggerComponentProperty } from "./swagger-component-property.js";
|
|
2
|
+
|
|
3
|
+
// export interface SwaggerSchema {
|
|
4
|
+
// type: string;
|
|
5
|
+
// $ref: string;
|
|
6
|
+
// allOf: SwaggerSchema[];
|
|
7
|
+
// format: string;
|
|
8
|
+
// items: SwaggerSchema;
|
|
9
|
+
// properties: { [key: string]: SwaggerComponentProperty; };
|
|
10
|
+
// }
|
|
11
|
+
|
|
12
|
+
export interface SwaggerSchema {
|
|
13
|
+
type?: string;
|
|
14
|
+
$ref?: string;
|
|
15
|
+
allOf?: SwaggerSchema[];
|
|
16
|
+
format?: string;
|
|
17
|
+
items?: SwaggerSchema;
|
|
18
|
+
properties?: { [key: string]: SwaggerSchema };
|
|
19
|
+
enum?: Array<string | number>;
|
|
20
|
+
nullable?: boolean;
|
|
21
|
+
minLength?: number;
|
|
21
22
|
}
|
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
import { SwaggerComponent } from "./swagger-component.js";
|
|
2
|
-
import { SwaggerContent } from "./swagger-content.js";
|
|
3
|
-
import { SwaggerInfo } from "./swagger-info.js";
|
|
4
|
-
import { SwaggerMethod } from "./swagger-method.js";
|
|
5
|
-
import { SwaggerSchema } from "./swagger-schema.js";
|
|
6
|
-
|
|
7
|
-
export interface Swagger {
|
|
8
|
-
openApi: string;
|
|
9
|
-
info: SwaggerInfo;
|
|
10
|
-
paths: { [key: string]: { [key: string]: SwaggerMethod; }; };
|
|
11
|
-
components: SwaggerComponents;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export interface SwaggerParameter {
|
|
15
|
-
name: string;
|
|
16
|
-
in: string;
|
|
17
|
-
required: boolean;
|
|
18
|
-
schema: SwaggerSchema;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export interface SwaggerRequestBody {
|
|
22
|
-
content: { [key: string]: SwaggerContent; };
|
|
23
|
-
encoding : SwaggerEncoding;
|
|
24
|
-
required?: boolean;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface SwaggerResponses {
|
|
28
|
-
description: string;
|
|
29
|
-
content: { [key: string]: SwaggerContent; };
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface SwaggerComponents {
|
|
33
|
-
schemas: { [key: string]: SwaggerComponent; };
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export interface SwaggerEncoding{
|
|
37
|
-
File: {style: 'form'},
|
|
38
|
-
Id: {style: 'form'},
|
|
1
|
+
import { SwaggerComponent } from "./swagger-component.js";
|
|
2
|
+
import { SwaggerContent } from "./swagger-content.js";
|
|
3
|
+
import { SwaggerInfo } from "./swagger-info.js";
|
|
4
|
+
import { SwaggerMethod } from "./swagger-method.js";
|
|
5
|
+
import { SwaggerSchema } from "./swagger-schema.js";
|
|
6
|
+
|
|
7
|
+
export interface Swagger {
|
|
8
|
+
openApi: string;
|
|
9
|
+
info: SwaggerInfo;
|
|
10
|
+
paths: { [key: string]: { [key: string]: SwaggerMethod; }; };
|
|
11
|
+
components: SwaggerComponents;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface SwaggerParameter {
|
|
15
|
+
name: string;
|
|
16
|
+
in: string;
|
|
17
|
+
required: boolean;
|
|
18
|
+
schema: SwaggerSchema;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface SwaggerRequestBody {
|
|
22
|
+
content: { [key: string]: SwaggerContent; };
|
|
23
|
+
encoding : SwaggerEncoding;
|
|
24
|
+
required?: boolean;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface SwaggerResponses {
|
|
28
|
+
description: string;
|
|
29
|
+
content: { [key: string]: SwaggerContent; };
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface SwaggerComponents {
|
|
33
|
+
schemas: { [key: string]: SwaggerComponent; };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface SwaggerEncoding{
|
|
37
|
+
File: {style: 'form'},
|
|
38
|
+
Id: {style: 'form'},
|
|
39
39
|
}
|
package/src/models/type-dto.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export interface TypeDto {
|
|
2
|
-
typeName: string;
|
|
3
|
-
nullable: boolean;
|
|
4
|
-
isNativeType: boolean;
|
|
5
|
-
isTypeReference: boolean;
|
|
6
|
-
isVoid: boolean;
|
|
7
|
-
isArray: boolean;
|
|
1
|
+
export interface TypeDto {
|
|
2
|
+
typeName: string;
|
|
3
|
+
nullable: boolean;
|
|
4
|
+
isNativeType: boolean;
|
|
5
|
+
isTypeReference: boolean;
|
|
6
|
+
isVoid: boolean;
|
|
7
|
+
isArray: boolean;
|
|
8
8
|
}
|
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
import fetch, { RequestInit } from 'node-fetch';
|
|
2
|
-
import { Swagger } from "./models/swagger/swagger.js";
|
|
3
|
-
import { logger } from './utils/logger.js';
|
|
4
|
-
import { SwaggerValidator } from './utils/swagger-validator.js';
|
|
5
|
-
|
|
6
|
-
const settings: RequestInit = { method: "Get" };
|
|
7
|
-
|
|
8
|
-
export class SwaggerDownloader {
|
|
9
|
-
async download(swaggerJsonUrl: URL): Promise<Swagger> {
|
|
10
|
-
try {
|
|
11
|
-
logger.progress(`Downloading Swagger from: ${swaggerJsonUrl}`);
|
|
12
|
-
|
|
13
|
-
const response = await fetch(swaggerJsonUrl, settings);
|
|
14
|
-
|
|
15
|
-
if (!response.ok) {
|
|
16
|
-
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const json = await response.json();
|
|
20
|
-
|
|
21
|
-
// Validate the downloaded swagger document
|
|
22
|
-
if (!SwaggerValidator.isValidSwaggerDocument(json)) {
|
|
23
|
-
throw new Error('Downloaded document is not a valid Swagger/OpenAPI specification');
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Normalize openapi field to openApi (camelCase) if needed
|
|
27
|
-
const jsonAny = json as any;
|
|
28
|
-
if (jsonAny.openapi && !jsonAny.openApi) {
|
|
29
|
-
jsonAny.openApi = jsonAny.openapi;
|
|
30
|
-
}
|
|
31
|
-
if (jsonAny.swagger && !jsonAny.openApi) {
|
|
32
|
-
jsonAny.openApi = jsonAny.swagger;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const swagger = jsonAny as Swagger;
|
|
36
|
-
SwaggerValidator.validate(swagger);
|
|
37
|
-
|
|
38
|
-
logger.success(`Swagger document downloaded successfully`);
|
|
39
|
-
return swagger;
|
|
40
|
-
|
|
41
|
-
} catch (error) {
|
|
42
|
-
logger.error(`Failed to download Swagger from ${swaggerJsonUrl}`, error);
|
|
43
|
-
throw error;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
1
|
+
import fetch, { RequestInit } from 'node-fetch';
|
|
2
|
+
import { Swagger } from "./models/swagger/swagger.js";
|
|
3
|
+
import { logger } from './utils/logger.js';
|
|
4
|
+
import { SwaggerValidator } from './utils/swagger-validator.js';
|
|
5
|
+
|
|
6
|
+
const settings: RequestInit = { method: "Get" };
|
|
7
|
+
|
|
8
|
+
export class SwaggerDownloader {
|
|
9
|
+
async download(swaggerJsonUrl: URL): Promise<Swagger> {
|
|
10
|
+
try {
|
|
11
|
+
logger.progress(`Downloading Swagger from: ${swaggerJsonUrl}`);
|
|
12
|
+
|
|
13
|
+
const response = await fetch(swaggerJsonUrl, settings);
|
|
14
|
+
|
|
15
|
+
if (!response.ok) {
|
|
16
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const json = await response.json();
|
|
20
|
+
|
|
21
|
+
// Validate the downloaded swagger document
|
|
22
|
+
if (!SwaggerValidator.isValidSwaggerDocument(json)) {
|
|
23
|
+
throw new Error('Downloaded document is not a valid Swagger/OpenAPI specification');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Normalize openapi field to openApi (camelCase) if needed
|
|
27
|
+
const jsonAny = json as any;
|
|
28
|
+
if (jsonAny.openapi && !jsonAny.openApi) {
|
|
29
|
+
jsonAny.openApi = jsonAny.openapi;
|
|
30
|
+
}
|
|
31
|
+
if (jsonAny.swagger && !jsonAny.openApi) {
|
|
32
|
+
jsonAny.openApi = jsonAny.swagger;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const swagger = jsonAny as Swagger;
|
|
36
|
+
SwaggerValidator.validate(swagger);
|
|
37
|
+
|
|
38
|
+
logger.success(`Swagger document downloaded successfully`);
|
|
39
|
+
return swagger;
|
|
40
|
+
|
|
41
|
+
} catch (error) {
|
|
42
|
+
logger.error(`Failed to download Swagger from ${swaggerJsonUrl}`, error);
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
package/src/utils/logger.ts
CHANGED
|
@@ -1,73 +1,73 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Centralized logging utility for the Swagger Generator
|
|
3
|
-
* Provides consistent logging with levels and formatting
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export enum LogLevel {
|
|
7
|
-
DEBUG = 0,
|
|
8
|
-
INFO = 1,
|
|
9
|
-
WARN = 2,
|
|
10
|
-
ERROR = 3,
|
|
11
|
-
SILENT = 4,
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export class Logger {
|
|
15
|
-
private static instance: Logger;
|
|
16
|
-
private logLevel: LogLevel = LogLevel.INFO;
|
|
17
|
-
|
|
18
|
-
private constructor() {}
|
|
19
|
-
|
|
20
|
-
static getInstance(): Logger {
|
|
21
|
-
if (!Logger.instance) {
|
|
22
|
-
Logger.instance = new Logger();
|
|
23
|
-
}
|
|
24
|
-
return Logger.instance;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
setLogLevel(level: LogLevel) {
|
|
28
|
-
this.logLevel = level;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
debug(message: string, ...args: any[]) {
|
|
32
|
-
if (this.logLevel <= LogLevel.DEBUG) {
|
|
33
|
-
console.debug(`[DEBUG] ${message}`, ...args);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
info(message: string, ...args: any[]) {
|
|
38
|
-
if (this.logLevel <= LogLevel.INFO) {
|
|
39
|
-
console.info(`[INFO] ${message}`, ...args);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
warn(message: string, ...args: any[]) {
|
|
44
|
-
if (this.logLevel <= LogLevel.WARN) {
|
|
45
|
-
console.warn(`[WARN] ${message}`, ...args);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
error(message: string, error?: any) {
|
|
50
|
-
if (this.logLevel <= LogLevel.ERROR) {
|
|
51
|
-
if (error) {
|
|
52
|
-
console.error(`[ERROR] ${message}`, error);
|
|
53
|
-
} else {
|
|
54
|
-
console.error(`[ERROR] ${message}`);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
success(message: string) {
|
|
60
|
-
if (this.logLevel <= LogLevel.INFO) {
|
|
61
|
-
console.info(`✓ ${message}`);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
progress(message: string) {
|
|
66
|
-
if (this.logLevel <= LogLevel.INFO) {
|
|
67
|
-
console.info(`→ ${message}`);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Export singleton instance
|
|
73
|
-
export const logger = Logger.getInstance();
|
|
1
|
+
/**
|
|
2
|
+
* Centralized logging utility for the Swagger Generator
|
|
3
|
+
* Provides consistent logging with levels and formatting
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export enum LogLevel {
|
|
7
|
+
DEBUG = 0,
|
|
8
|
+
INFO = 1,
|
|
9
|
+
WARN = 2,
|
|
10
|
+
ERROR = 3,
|
|
11
|
+
SILENT = 4,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export class Logger {
|
|
15
|
+
private static instance: Logger;
|
|
16
|
+
private logLevel: LogLevel = LogLevel.INFO;
|
|
17
|
+
|
|
18
|
+
private constructor() {}
|
|
19
|
+
|
|
20
|
+
static getInstance(): Logger {
|
|
21
|
+
if (!Logger.instance) {
|
|
22
|
+
Logger.instance = new Logger();
|
|
23
|
+
}
|
|
24
|
+
return Logger.instance;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
setLogLevel(level: LogLevel) {
|
|
28
|
+
this.logLevel = level;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
debug(message: string, ...args: any[]) {
|
|
32
|
+
if (this.logLevel <= LogLevel.DEBUG) {
|
|
33
|
+
console.debug(`[DEBUG] ${message}`, ...args);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
info(message: string, ...args: any[]) {
|
|
38
|
+
if (this.logLevel <= LogLevel.INFO) {
|
|
39
|
+
console.info(`[INFO] ${message}`, ...args);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
warn(message: string, ...args: any[]) {
|
|
44
|
+
if (this.logLevel <= LogLevel.WARN) {
|
|
45
|
+
console.warn(`[WARN] ${message}`, ...args);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
error(message: string, error?: any) {
|
|
50
|
+
if (this.logLevel <= LogLevel.ERROR) {
|
|
51
|
+
if (error) {
|
|
52
|
+
console.error(`[ERROR] ${message}`, error);
|
|
53
|
+
} else {
|
|
54
|
+
console.error(`[ERROR] ${message}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
success(message: string) {
|
|
60
|
+
if (this.logLevel <= LogLevel.INFO) {
|
|
61
|
+
console.info(`✓ ${message}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
progress(message: string) {
|
|
66
|
+
if (this.logLevel <= LogLevel.INFO) {
|
|
67
|
+
console.info(`→ ${message}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Export singleton instance
|
|
73
|
+
export const logger = Logger.getInstance();
|
|
@@ -1,89 +1,89 @@
|
|
|
1
|
-
import { Swagger } from '../models/swagger/swagger.js';
|
|
2
|
-
import { logger } from './logger.js';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Validates Swagger/OpenAPI specification
|
|
6
|
-
* Ensures the document has required fields before processing
|
|
7
|
-
*/
|
|
8
|
-
export class SwaggerValidator {
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Validates a Swagger document structure
|
|
12
|
-
* @param swagger - The Swagger document to validate
|
|
13
|
-
* @throws Error if validation fails
|
|
14
|
-
*/
|
|
15
|
-
static validate(swagger: any): void {
|
|
16
|
-
const errors: string[] = [];
|
|
17
|
-
|
|
18
|
-
// Check required top-level fields (support both openapi and openApi)
|
|
19
|
-
const version = swagger.openapi || swagger.swagger || swagger.openApi;
|
|
20
|
-
if (!version) {
|
|
21
|
-
errors.push('Missing openapi/swagger version field');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (!swagger.paths || Object.keys(swagger.paths).length === 0) {
|
|
25
|
-
errors.push('Missing or empty paths object');
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if (!swagger.info) {
|
|
29
|
-
errors.push('Missing info object');
|
|
30
|
-
} else {
|
|
31
|
-
if (!swagger.info.title) {
|
|
32
|
-
errors.push('Missing info.title');
|
|
33
|
-
}
|
|
34
|
-
if (!swagger.info.version) {
|
|
35
|
-
errors.push('Missing info.version');
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Check components
|
|
40
|
-
if (!swagger.components && !swagger.definitions) {
|
|
41
|
-
logger.warn('No components/definitions found - model generation may be limited');
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Validate paths structure
|
|
45
|
-
if (swagger.paths) {
|
|
46
|
-
for (const [path, methods] of Object.entries(swagger.paths)) {
|
|
47
|
-
if (!methods || typeof methods !== 'object') {
|
|
48
|
-
errors.push(`Invalid path definition for: ${path}`);
|
|
49
|
-
continue;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const validMethods = ['get', 'post', 'put', 'delete', 'patch', 'options', 'head'];
|
|
53
|
-
const pathMethods = Object.keys(methods);
|
|
54
|
-
|
|
55
|
-
if (pathMethods.length === 0) {
|
|
56
|
-
errors.push(`No HTTP methods defined for path: ${path}`);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
for (const method of pathMethods) {
|
|
60
|
-
if (!validMethods.includes(method.toLowerCase())) {
|
|
61
|
-
logger.warn(`Unexpected HTTP method '${method}' in path: ${path}`);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// If there are errors, throw
|
|
68
|
-
if (errors.length > 0) {
|
|
69
|
-
const errorMessage = `Swagger validation failed:\n${errors.map(e => ` - ${e}`).join('\n')}`;
|
|
70
|
-
logger.error(errorMessage);
|
|
71
|
-
throw new Error(errorMessage);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
logger.success('Swagger document validation passed');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Checks if the Swagger document is likely valid without throwing
|
|
79
|
-
* @param obj - Object to check
|
|
80
|
-
* @returns true if it looks like a valid Swagger document
|
|
81
|
-
*/
|
|
82
|
-
static isValidSwaggerDocument(obj: any): obj is Swagger {
|
|
83
|
-
return obj &&
|
|
84
|
-
typeof obj === 'object' &&
|
|
85
|
-
(obj.openApi || obj.openapi || obj.swagger) &&
|
|
86
|
-
obj.paths &&
|
|
87
|
-
typeof obj.paths === 'object';
|
|
88
|
-
}
|
|
89
|
-
}
|
|
1
|
+
import { Swagger } from '../models/swagger/swagger.js';
|
|
2
|
+
import { logger } from './logger.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Validates Swagger/OpenAPI specification
|
|
6
|
+
* Ensures the document has required fields before processing
|
|
7
|
+
*/
|
|
8
|
+
export class SwaggerValidator {
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Validates a Swagger document structure
|
|
12
|
+
* @param swagger - The Swagger document to validate
|
|
13
|
+
* @throws Error if validation fails
|
|
14
|
+
*/
|
|
15
|
+
static validate(swagger: any): void {
|
|
16
|
+
const errors: string[] = [];
|
|
17
|
+
|
|
18
|
+
// Check required top-level fields (support both openapi and openApi)
|
|
19
|
+
const version = swagger.openapi || swagger.swagger || swagger.openApi;
|
|
20
|
+
if (!version) {
|
|
21
|
+
errors.push('Missing openapi/swagger version field');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!swagger.paths || Object.keys(swagger.paths).length === 0) {
|
|
25
|
+
errors.push('Missing or empty paths object');
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (!swagger.info) {
|
|
29
|
+
errors.push('Missing info object');
|
|
30
|
+
} else {
|
|
31
|
+
if (!swagger.info.title) {
|
|
32
|
+
errors.push('Missing info.title');
|
|
33
|
+
}
|
|
34
|
+
if (!swagger.info.version) {
|
|
35
|
+
errors.push('Missing info.version');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Check components
|
|
40
|
+
if (!swagger.components && !swagger.definitions) {
|
|
41
|
+
logger.warn('No components/definitions found - model generation may be limited');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Validate paths structure
|
|
45
|
+
if (swagger.paths) {
|
|
46
|
+
for (const [path, methods] of Object.entries(swagger.paths)) {
|
|
47
|
+
if (!methods || typeof methods !== 'object') {
|
|
48
|
+
errors.push(`Invalid path definition for: ${path}`);
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const validMethods = ['get', 'post', 'put', 'delete', 'patch', 'options', 'head'];
|
|
53
|
+
const pathMethods = Object.keys(methods);
|
|
54
|
+
|
|
55
|
+
if (pathMethods.length === 0) {
|
|
56
|
+
errors.push(`No HTTP methods defined for path: ${path}`);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
for (const method of pathMethods) {
|
|
60
|
+
if (!validMethods.includes(method.toLowerCase())) {
|
|
61
|
+
logger.warn(`Unexpected HTTP method '${method}' in path: ${path}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// If there are errors, throw
|
|
68
|
+
if (errors.length > 0) {
|
|
69
|
+
const errorMessage = `Swagger validation failed:\n${errors.map(e => ` - ${e}`).join('\n')}`;
|
|
70
|
+
logger.error(errorMessage);
|
|
71
|
+
throw new Error(errorMessage);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
logger.success('Swagger document validation passed');
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Checks if the Swagger document is likely valid without throwing
|
|
79
|
+
* @param obj - Object to check
|
|
80
|
+
* @returns true if it looks like a valid Swagger document
|
|
81
|
+
*/
|
|
82
|
+
static isValidSwaggerDocument(obj: any): obj is Swagger {
|
|
83
|
+
return obj &&
|
|
84
|
+
typeof obj === 'object' &&
|
|
85
|
+
(obj.openApi || obj.openapi || obj.swagger) &&
|
|
86
|
+
obj.paths &&
|
|
87
|
+
typeof obj.paths === 'object';
|
|
88
|
+
}
|
|
89
|
+
}
|