@hazeljs/swagger 0.2.0-beta.1
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 +583 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +15 -0
- package/dist/src/swagger.controller.d.ts +12 -0
- package/dist/src/swagger.controller.d.ts.map +1 -0
- package/dist/src/swagger.controller.js +238 -0
- package/dist/src/swagger.decorator.d.ts +7 -0
- package/dist/src/swagger.decorator.d.ts.map +1 -0
- package/dist/src/swagger.decorator.js +26 -0
- package/dist/src/swagger.module.d.ts +5 -0
- package/dist/src/swagger.module.d.ts.map +1 -0
- package/dist/src/swagger.module.js +30 -0
- package/dist/src/swagger.service.d.ts +24 -0
- package/dist/src/swagger.service.d.ts.map +1 -0
- package/dist/src/swagger.service.js +117 -0
- package/dist/src/swagger.types.d.ts +50 -0
- package/dist/src/swagger.types.d.ts.map +1 -0
- package/dist/src/swagger.types.js +2 -0
- package/dist/swagger.controller.d.ts +12 -0
- package/dist/swagger.controller.d.ts.map +1 -0
- package/dist/swagger.controller.js +238 -0
- package/dist/swagger.decorator.d.ts +7 -0
- package/dist/swagger.decorator.d.ts.map +1 -0
- package/dist/swagger.decorator.js +26 -0
- package/dist/swagger.module.d.ts +5 -0
- package/dist/swagger.module.d.ts.map +1 -0
- package/dist/swagger.module.js +30 -0
- package/dist/swagger.service.d.ts +25 -0
- package/dist/swagger.service.d.ts.map +1 -0
- package/dist/swagger.service.js +147 -0
- package/dist/swagger.types.d.ts +50 -0
- package/dist/swagger.types.d.ts.map +1 -0
- package/dist/swagger.types.js +2 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
var SwaggerController_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.SwaggerController = void 0;
|
|
17
|
+
const core_1 = require("@hazeljs/core");
|
|
18
|
+
const swagger_service_1 = require("./swagger.service");
|
|
19
|
+
const core_2 = require("@hazeljs/core");
|
|
20
|
+
const core_3 = __importDefault(require("@hazeljs/core"));
|
|
21
|
+
const swagger_decorator_1 = require("./swagger.decorator");
|
|
22
|
+
let SwaggerController = SwaggerController_1 = class SwaggerController {
|
|
23
|
+
constructor(swaggerService) {
|
|
24
|
+
this.swaggerService = swaggerService;
|
|
25
|
+
}
|
|
26
|
+
static setRootModule(module) {
|
|
27
|
+
core_3.default.debug(`Setting root module for SwaggerController: ${module.name}`);
|
|
28
|
+
SwaggerController_1.rootModule = module;
|
|
29
|
+
}
|
|
30
|
+
async getSpec(_context) {
|
|
31
|
+
try {
|
|
32
|
+
if (!SwaggerController_1.rootModule) {
|
|
33
|
+
core_3.default.warn('No root module provided');
|
|
34
|
+
return {
|
|
35
|
+
openapi: '3.0.0',
|
|
36
|
+
info: {
|
|
37
|
+
title: 'API Documentation',
|
|
38
|
+
version: '1.0.0',
|
|
39
|
+
description: 'No root module provided',
|
|
40
|
+
},
|
|
41
|
+
paths: {},
|
|
42
|
+
components: {
|
|
43
|
+
schemas: {},
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
core_3.default.debug('Root module:', SwaggerController_1.rootModule.name);
|
|
48
|
+
// Get all controllers from the AppModule and its imported modules
|
|
49
|
+
const moduleMetadata = (0, core_2.getModuleMetadata)(SwaggerController_1.rootModule);
|
|
50
|
+
core_3.default.debug('Module metadata:', JSON.stringify(moduleMetadata, null, 2));
|
|
51
|
+
const controllers = new Set();
|
|
52
|
+
// Helper function to recursively collect controllers from modules
|
|
53
|
+
const collectControllers = (moduleType) => {
|
|
54
|
+
core_3.default.debug(`Collecting controllers from module: ${moduleType.name}`);
|
|
55
|
+
const metadata = (0, core_2.getModuleMetadata)(moduleType);
|
|
56
|
+
if (!metadata) {
|
|
57
|
+
core_3.default.warn(`No metadata found for module: ${moduleType.name}`);
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// Add controllers from current module
|
|
61
|
+
if (metadata.controllers) {
|
|
62
|
+
const validControllers = metadata.controllers.filter((c) => c && typeof c === 'function');
|
|
63
|
+
core_3.default.debug(`${moduleType.name} controllers:`, validControllers.map((c) => typeof c === 'function' ? c.name : undefined));
|
|
64
|
+
validControllers.forEach((controller) => controllers.add(controller));
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
core_3.default.debug(`No controllers found in module: ${moduleType.name}`);
|
|
68
|
+
}
|
|
69
|
+
// Recursively process imported modules
|
|
70
|
+
if (metadata.imports) {
|
|
71
|
+
const validModules = metadata.imports.filter((m) => m && typeof m === 'function');
|
|
72
|
+
core_3.default.debug(`${moduleType.name} imported modules:`, validModules.map((m) => (typeof m === 'function' ? m.name : undefined)));
|
|
73
|
+
validModules.forEach((moduleType) => collectControllers(moduleType));
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
core_3.default.debug(`No imports found in module: ${moduleType.name}`);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
// Start collecting controllers from the root module
|
|
80
|
+
collectControllers(SwaggerController_1.rootModule);
|
|
81
|
+
const controllerArray = Array.from(controllers);
|
|
82
|
+
core_3.default.debug('Total controllers found:', controllerArray.length);
|
|
83
|
+
core_3.default.debug('Controller names:', controllerArray.map((c) => c.name));
|
|
84
|
+
if (controllerArray.length === 0) {
|
|
85
|
+
core_3.default.warn('No valid controllers found');
|
|
86
|
+
return {
|
|
87
|
+
openapi: '3.0.0',
|
|
88
|
+
info: {
|
|
89
|
+
title: 'API Documentation',
|
|
90
|
+
version: '1.0.0',
|
|
91
|
+
description: 'No controllers found',
|
|
92
|
+
},
|
|
93
|
+
paths: {},
|
|
94
|
+
components: {
|
|
95
|
+
schemas: {},
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const spec = this.swaggerService.generateSpec(controllerArray);
|
|
100
|
+
return spec;
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
core_3.default.error('Error generating Swagger spec:', error);
|
|
104
|
+
throw error;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async getDocs(_context) {
|
|
108
|
+
return `
|
|
109
|
+
<!DOCTYPE html>
|
|
110
|
+
<html>
|
|
111
|
+
<head>
|
|
112
|
+
<title>API Documentation</title>
|
|
113
|
+
<meta charset="utf-8"/>
|
|
114
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
115
|
+
<link rel="stylesheet" type="text/css" href="https://unpkg.com/swagger-ui-dist@4.18.3/swagger-ui.css" />
|
|
116
|
+
<style>
|
|
117
|
+
body {
|
|
118
|
+
margin: 0;
|
|
119
|
+
padding: 20px;
|
|
120
|
+
}
|
|
121
|
+
#swagger-ui {
|
|
122
|
+
max-width: 1460px;
|
|
123
|
+
margin: 0 auto;
|
|
124
|
+
}
|
|
125
|
+
.loading {
|
|
126
|
+
text-align: center;
|
|
127
|
+
padding: 20px;
|
|
128
|
+
font-family: Arial, sans-serif;
|
|
129
|
+
}
|
|
130
|
+
</style>
|
|
131
|
+
</head>
|
|
132
|
+
<body>
|
|
133
|
+
<div id="swagger-ui">
|
|
134
|
+
<div class="loading">Loading API Documentation...</div>
|
|
135
|
+
</div>
|
|
136
|
+
|
|
137
|
+
<script src="https://unpkg.com/swagger-ui-dist@4.18.3/swagger-ui-bundle.js"></script>
|
|
138
|
+
<script src="https://unpkg.com/swagger-ui-dist@4.18.3/swagger-ui-standalone-preset.js"></script>
|
|
139
|
+
<script>
|
|
140
|
+
// Basic error handling
|
|
141
|
+
window.onerror = function(msg, url, line) {
|
|
142
|
+
document.getElementById('swagger-ui').innerHTML =
|
|
143
|
+
'<div style="color: red; padding: 20px;">Error: ' + msg + '<br>at line ' + line + '</div>';
|
|
144
|
+
return false;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
// Simple initialization
|
|
148
|
+
const ui = SwaggerUIBundle({
|
|
149
|
+
url: window.location.origin + "/swagger/spec",
|
|
150
|
+
dom_id: '#swagger-ui',
|
|
151
|
+
deepLinking: true,
|
|
152
|
+
presets: [
|
|
153
|
+
SwaggerUIBundle.presets.apis,
|
|
154
|
+
SwaggerUIStandalonePreset
|
|
155
|
+
],
|
|
156
|
+
plugins: [
|
|
157
|
+
SwaggerUIBundle.plugins.DownloadUrl
|
|
158
|
+
],
|
|
159
|
+
layout: "BaseLayout"
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
window.ui = ui;
|
|
163
|
+
</script>
|
|
164
|
+
</body>
|
|
165
|
+
</html>
|
|
166
|
+
`;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
exports.SwaggerController = SwaggerController;
|
|
170
|
+
__decorate([
|
|
171
|
+
(0, core_1.Get)('/spec'),
|
|
172
|
+
(0, swagger_decorator_1.ApiOperation)({
|
|
173
|
+
summary: 'Get OpenAPI specification',
|
|
174
|
+
description: 'Retrieves the OpenAPI specification for the API',
|
|
175
|
+
tags: ['swagger'],
|
|
176
|
+
responses: {
|
|
177
|
+
'200': {
|
|
178
|
+
description: 'OpenAPI specification retrieved successfully',
|
|
179
|
+
content: {
|
|
180
|
+
'application/json': {
|
|
181
|
+
schema: {
|
|
182
|
+
type: 'object',
|
|
183
|
+
properties: {
|
|
184
|
+
openapi: { type: 'string' },
|
|
185
|
+
info: { type: 'object' },
|
|
186
|
+
paths: { type: 'object' },
|
|
187
|
+
components: { type: 'object' },
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
}),
|
|
195
|
+
__metadata("design:type", Function),
|
|
196
|
+
__metadata("design:paramtypes", [Object]),
|
|
197
|
+
__metadata("design:returntype", Promise)
|
|
198
|
+
], SwaggerController.prototype, "getSpec", null);
|
|
199
|
+
__decorate([
|
|
200
|
+
(0, core_1.Get)('/'),
|
|
201
|
+
(0, swagger_decorator_1.ApiOperation)({
|
|
202
|
+
summary: 'Get Swagger UI',
|
|
203
|
+
description: 'Serves the Swagger UI interface',
|
|
204
|
+
tags: ['swagger'],
|
|
205
|
+
responses: {
|
|
206
|
+
'200': {
|
|
207
|
+
description: 'Swagger UI HTML page',
|
|
208
|
+
content: {
|
|
209
|
+
'text/html': {
|
|
210
|
+
schema: {
|
|
211
|
+
type: 'string',
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
},
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
}),
|
|
218
|
+
__metadata("design:type", Function),
|
|
219
|
+
__metadata("design:paramtypes", [Object]),
|
|
220
|
+
__metadata("design:returntype", Promise)
|
|
221
|
+
], SwaggerController.prototype, "getDocs", null);
|
|
222
|
+
exports.SwaggerController = SwaggerController = SwaggerController_1 = __decorate([
|
|
223
|
+
(0, swagger_decorator_1.Swagger)({
|
|
224
|
+
title: 'Swagger Documentation',
|
|
225
|
+
description: 'API documentation using Swagger/OpenAPI',
|
|
226
|
+
version: '1.0.0',
|
|
227
|
+
tags: [
|
|
228
|
+
{
|
|
229
|
+
name: 'swagger',
|
|
230
|
+
description: 'Swagger documentation endpoints',
|
|
231
|
+
},
|
|
232
|
+
],
|
|
233
|
+
}),
|
|
234
|
+
(0, core_1.Controller)({
|
|
235
|
+
path: 'swagger',
|
|
236
|
+
}),
|
|
237
|
+
__metadata("design:paramtypes", [swagger_service_1.SwaggerService])
|
|
238
|
+
], SwaggerController);
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import { SwaggerOptions, SwaggerOperation } from './swagger.types';
|
|
3
|
+
export declare function Swagger(options: SwaggerOptions): ClassDecorator;
|
|
4
|
+
export declare function ApiOperation(operation: SwaggerOperation): MethodDecorator;
|
|
5
|
+
export declare function getSwaggerMetadata(target: object): SwaggerOptions | undefined;
|
|
6
|
+
export declare function getOperationMetadata(target: object, propertyKey: string | symbol): SwaggerOperation | undefined;
|
|
7
|
+
//# sourceMappingURL=swagger.decorator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swagger.decorator.d.ts","sourceRoot":"","sources":["../../src/swagger.decorator.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAKnE,wBAAgB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,cAAc,CAM/D;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,gBAAgB,GAAG,eAAe,CAIzE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAE7E;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,MAAM,GAC3B,gBAAgB,GAAG,SAAS,CAE9B"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Swagger = Swagger;
|
|
4
|
+
exports.ApiOperation = ApiOperation;
|
|
5
|
+
exports.getSwaggerMetadata = getSwaggerMetadata;
|
|
6
|
+
exports.getOperationMetadata = getOperationMetadata;
|
|
7
|
+
require("reflect-metadata");
|
|
8
|
+
const SWAGGER_METADATA_KEY = 'swagger:options';
|
|
9
|
+
const SWAGGER_OPERATION_METADATA_KEY = 'swagger:operation';
|
|
10
|
+
function Swagger(options) {
|
|
11
|
+
return (target) => {
|
|
12
|
+
const metaTarget = typeof target === 'function' ? target.prototype : target;
|
|
13
|
+
Reflect.defineMetadata(SWAGGER_METADATA_KEY, options, metaTarget);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
function ApiOperation(operation) {
|
|
17
|
+
return (target, propertyKey) => {
|
|
18
|
+
Reflect.defineMetadata(SWAGGER_OPERATION_METADATA_KEY, operation, target, propertyKey);
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function getSwaggerMetadata(target) {
|
|
22
|
+
return Reflect.getMetadata(SWAGGER_METADATA_KEY, target);
|
|
23
|
+
}
|
|
24
|
+
function getOperationMetadata(target, propertyKey) {
|
|
25
|
+
return Reflect.getMetadata(SWAGGER_OPERATION_METADATA_KEY, target, propertyKey);
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swagger.module.d.ts","sourceRoot":"","sources":["../../src/swagger.module.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAGrC,qBAKa,aAAa;IACxB,MAAM,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI;CAItD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.SwaggerModule = void 0;
|
|
13
|
+
const core_1 = require("@hazeljs/core");
|
|
14
|
+
const swagger_service_1 = require("./swagger.service");
|
|
15
|
+
const swagger_controller_1 = require("./swagger.controller");
|
|
16
|
+
const core_2 = __importDefault(require("@hazeljs/core"));
|
|
17
|
+
let SwaggerModule = class SwaggerModule {
|
|
18
|
+
static setRootModule(rootModule) {
|
|
19
|
+
core_2.default.debug('SwaggerModule: Setting root module:', rootModule.name);
|
|
20
|
+
swagger_controller_1.SwaggerController.setRootModule(rootModule);
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
exports.SwaggerModule = SwaggerModule;
|
|
24
|
+
exports.SwaggerModule = SwaggerModule = __decorate([
|
|
25
|
+
(0, core_1.HazelModule)({
|
|
26
|
+
providers: [swagger_service_1.SwaggerService],
|
|
27
|
+
controllers: [swagger_controller_1.SwaggerController],
|
|
28
|
+
exports: [swagger_service_1.SwaggerService],
|
|
29
|
+
})
|
|
30
|
+
], SwaggerModule);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { SwaggerOperation, SwaggerSchema } from './swagger.types';
|
|
2
|
+
import { Type } from '@hazeljs/core';
|
|
3
|
+
export interface SwaggerSpec {
|
|
4
|
+
openapi: string;
|
|
5
|
+
info: {
|
|
6
|
+
title?: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
version?: string;
|
|
9
|
+
};
|
|
10
|
+
paths: Record<string, Record<string, SwaggerOperation>>;
|
|
11
|
+
components: {
|
|
12
|
+
schemas: Record<string, SwaggerSchema>;
|
|
13
|
+
};
|
|
14
|
+
tags?: Array<{
|
|
15
|
+
name: string;
|
|
16
|
+
description: string;
|
|
17
|
+
}>;
|
|
18
|
+
}
|
|
19
|
+
export declare class SwaggerService {
|
|
20
|
+
private spec;
|
|
21
|
+
generateSpec(controllers: Type<unknown>[]): SwaggerSpec;
|
|
22
|
+
private normalizePath;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=swagger.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swagger.service.d.ts","sourceRoot":"","sources":["../../src/swagger.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGlE,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE;QACJ,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;IACxD,UAAU,EAAE;QACV,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;KACxC,CAAC;IACF,IAAI,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrD;AAQD,qBACa,cAAc;IACzB,OAAO,CAAC,IAAI,CAOV;IAEF,YAAY,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG,WAAW;IAkGvD,OAAO,CAAC,aAAa;CAStB"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.SwaggerService = void 0;
|
|
13
|
+
const core_1 = require("@hazeljs/core");
|
|
14
|
+
const swagger_decorator_1 = require("./swagger.decorator");
|
|
15
|
+
const core_2 = __importDefault(require("@hazeljs/core"));
|
|
16
|
+
let SwaggerService = class SwaggerService {
|
|
17
|
+
constructor() {
|
|
18
|
+
this.spec = {
|
|
19
|
+
openapi: '3.0.0',
|
|
20
|
+
info: {},
|
|
21
|
+
paths: {},
|
|
22
|
+
components: {
|
|
23
|
+
schemas: {},
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
generateSpec(controllers) {
|
|
28
|
+
try {
|
|
29
|
+
if (!Array.isArray(controllers)) {
|
|
30
|
+
throw new Error('Controllers must be an array');
|
|
31
|
+
}
|
|
32
|
+
core_2.default.debug('Generating spec for controllers:', controllers.map((c) => c?.name || 'undefined'));
|
|
33
|
+
// Reset spec
|
|
34
|
+
this.spec = {
|
|
35
|
+
openapi: '3.0.0',
|
|
36
|
+
info: {},
|
|
37
|
+
paths: {},
|
|
38
|
+
components: {
|
|
39
|
+
schemas: {},
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
// Process each controller
|
|
43
|
+
controllers.forEach((controller) => {
|
|
44
|
+
if (!controller || typeof controller !== 'function') {
|
|
45
|
+
core_2.default.warn('Invalid controller found:', controller);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
// Get Swagger metadata from the controller prototype
|
|
49
|
+
const swaggerOptions = (0, swagger_decorator_1.getSwaggerMetadata)(controller.prototype);
|
|
50
|
+
if (!swaggerOptions) {
|
|
51
|
+
core_2.default.debug(`No Swagger metadata found for controller: ${controller.name}`);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
core_2.default.debug(`Processing controller: ${controller.name}`, swaggerOptions);
|
|
55
|
+
// Update info if not already set
|
|
56
|
+
if (!this.spec.info.title) {
|
|
57
|
+
this.spec.info = {
|
|
58
|
+
title: swaggerOptions.title,
|
|
59
|
+
description: swaggerOptions.description,
|
|
60
|
+
version: swaggerOptions.version,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// Add tags if not already set
|
|
64
|
+
if (swaggerOptions.tags && !this.spec.tags) {
|
|
65
|
+
this.spec.tags = swaggerOptions.tags;
|
|
66
|
+
}
|
|
67
|
+
// Get controller path from metadata
|
|
68
|
+
const controllerMetadata = Reflect.getMetadata('hazel:controller', controller) || {};
|
|
69
|
+
const basePath = controllerMetadata.path || '';
|
|
70
|
+
// Get route metadata
|
|
71
|
+
const routes = Reflect.getMetadata('hazel:routes', controller);
|
|
72
|
+
if (!routes) {
|
|
73
|
+
core_2.default.debug(`No routes found for controller: ${controller.name}`);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
core_2.default.debug(`Found routes for ${controller.name}:`, routes);
|
|
77
|
+
// Process each route
|
|
78
|
+
routes.forEach((route) => {
|
|
79
|
+
const { path, method, propertyKey } = route;
|
|
80
|
+
const fullPath = this.normalizePath(`${basePath}${path}`);
|
|
81
|
+
const operation = (0, swagger_decorator_1.getOperationMetadata)(controller.prototype, propertyKey);
|
|
82
|
+
if (!operation) {
|
|
83
|
+
core_2.default.debug(`No operation metadata found for method: ${String(propertyKey)}`);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
core_2.default.debug(`Adding operation for ${method} ${fullPath}`);
|
|
87
|
+
// Add operation to paths
|
|
88
|
+
const pathItem = this.spec.paths[fullPath] || {};
|
|
89
|
+
pathItem[method.toLowerCase()] = {
|
|
90
|
+
...operation,
|
|
91
|
+
tags: operation.tags || [controller.name],
|
|
92
|
+
};
|
|
93
|
+
this.spec.paths[fullPath] = pathItem;
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
core_2.default.debug('Generated Swagger specification:', this.spec);
|
|
97
|
+
return this.spec;
|
|
98
|
+
}
|
|
99
|
+
catch (error) {
|
|
100
|
+
core_2.default.error('Failed to generate Swagger specification:', error);
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
normalizePath(path) {
|
|
105
|
+
// Remove trailing slash
|
|
106
|
+
let normalized = path.replace(/\/$/, '');
|
|
107
|
+
// Ensure path starts with slash
|
|
108
|
+
if (!normalized.startsWith('/')) {
|
|
109
|
+
normalized = '/' + normalized;
|
|
110
|
+
}
|
|
111
|
+
return normalized;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
exports.SwaggerService = SwaggerService;
|
|
115
|
+
exports.SwaggerService = SwaggerService = __decorate([
|
|
116
|
+
(0, core_1.Injectable)()
|
|
117
|
+
], SwaggerService);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export interface SwaggerOptions {
|
|
2
|
+
title: string;
|
|
3
|
+
description: string;
|
|
4
|
+
version: string;
|
|
5
|
+
path?: string;
|
|
6
|
+
tags?: SwaggerTag[];
|
|
7
|
+
}
|
|
8
|
+
export interface SwaggerTag {
|
|
9
|
+
name: string;
|
|
10
|
+
description: string;
|
|
11
|
+
}
|
|
12
|
+
export interface SwaggerOperation {
|
|
13
|
+
summary?: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
tags?: string[];
|
|
16
|
+
parameters?: SwaggerParameter[];
|
|
17
|
+
requestBody?: {
|
|
18
|
+
required?: boolean;
|
|
19
|
+
content: {
|
|
20
|
+
[contentType: string]: {
|
|
21
|
+
schema: SwaggerSchema;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
responses?: Record<string, SwaggerResponse>;
|
|
26
|
+
}
|
|
27
|
+
export interface SwaggerParameter {
|
|
28
|
+
name: string;
|
|
29
|
+
in: 'path' | 'query' | 'header' | 'cookie';
|
|
30
|
+
description?: string;
|
|
31
|
+
required?: boolean;
|
|
32
|
+
schema: SwaggerSchema;
|
|
33
|
+
}
|
|
34
|
+
export interface SwaggerResponse {
|
|
35
|
+
description: string;
|
|
36
|
+
content?: {
|
|
37
|
+
[contentType: string]: {
|
|
38
|
+
schema: SwaggerSchema;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export interface SwaggerSchema {
|
|
43
|
+
type: 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object';
|
|
44
|
+
format?: string;
|
|
45
|
+
items?: SwaggerSchema;
|
|
46
|
+
properties?: Record<string, SwaggerSchema>;
|
|
47
|
+
required?: string[];
|
|
48
|
+
example?: string | number | boolean | null | Record<string, unknown> | unknown[];
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=swagger.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swagger.types.d.ts","sourceRoot":"","sources":["../../src/swagger.types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,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,EAAE;YACP,CAAC,WAAW,EAAE,MAAM,GAAG;gBACrB,MAAM,EAAE,aAAa,CAAC;aACvB,CAAC;SACH,CAAC;KACH,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC7C;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC3C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE;QACR,CAAC,WAAW,EAAE,MAAM,GAAG;YACrB,MAAM,EAAE,aAAa,CAAC;SACvB,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,EAAE,CAAC;CAClF"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { SwaggerService } from './swagger.service';
|
|
2
|
+
import { RequestContext, Type } from '@hazeljs/core';
|
|
3
|
+
import { SwaggerSpec } from './swagger.service';
|
|
4
|
+
export declare class SwaggerController {
|
|
5
|
+
private swaggerService;
|
|
6
|
+
private static rootModule;
|
|
7
|
+
constructor(swaggerService: SwaggerService);
|
|
8
|
+
static setRootModule(module: Type<unknown>): void;
|
|
9
|
+
getSpec(_context: RequestContext): Promise<SwaggerSpec>;
|
|
10
|
+
getDocs(_context: RequestContext): Promise<string>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=swagger.controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"swagger.controller.d.ts","sourceRoot":"","sources":["../src/swagger.controller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAIrD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,qBAca,iBAAiB;IAGhB,OAAO,CAAC,cAAc;IAFlC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAgB;gBAErB,cAAc,EAAE,cAAc;IAElD,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,IAAI;IA6B3C,OAAO,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC;IAgHvD,OAAO,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;CA6DzD"}
|