@buenojs/bueno 0.8.4 → 0.8.5
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 +136 -16
- package/dist/cli/{index.js → bin.js} +412 -331
- package/dist/container/index.js +250 -0
- package/dist/context/index.js +219 -0
- package/dist/database/index.js +493 -0
- package/dist/frontend/index.js +7697 -0
- package/dist/health/index.js +364 -0
- package/dist/i18n/index.js +345 -0
- package/dist/index.js +11043 -6482
- package/dist/jobs/index.js +819 -0
- package/dist/lock/index.js +367 -0
- package/dist/logger/index.js +281 -0
- package/dist/metrics/index.js +289 -0
- package/dist/middleware/index.js +77 -0
- package/dist/migrations/index.js +571 -0
- package/dist/modules/index.js +3346 -0
- package/dist/notification/index.js +484 -0
- package/dist/observability/index.js +331 -0
- package/dist/openapi/index.js +776 -0
- package/dist/orm/index.js +1356 -0
- package/dist/router/index.js +886 -0
- package/dist/rpc/index.js +691 -0
- package/dist/schema/index.js +400 -0
- package/dist/telemetry/index.js +595 -0
- package/dist/template/index.js +640 -0
- package/dist/templates/index.js +640 -0
- package/dist/testing/index.js +1111 -0
- package/dist/types/index.js +60 -0
- package/package.json +121 -27
- package/src/cache/index.ts +2 -1
- package/src/cli/bin.ts +2 -2
- package/src/cli/commands/build.ts +183 -165
- package/src/cli/commands/dev.ts +96 -89
- package/src/cli/commands/generate.ts +142 -111
- package/src/cli/commands/help.ts +20 -16
- package/src/cli/commands/index.ts +3 -6
- package/src/cli/commands/migration.ts +124 -105
- package/src/cli/commands/new.ts +294 -232
- package/src/cli/commands/start.ts +81 -79
- package/src/cli/core/args.ts +68 -50
- package/src/cli/core/console.ts +89 -95
- package/src/cli/core/index.ts +4 -4
- package/src/cli/core/prompt.ts +65 -62
- package/src/cli/core/spinner.ts +23 -20
- package/src/cli/index.ts +46 -38
- package/src/cli/templates/database/index.ts +37 -18
- package/src/cli/templates/database/mysql.ts +3 -3
- package/src/cli/templates/database/none.ts +2 -2
- package/src/cli/templates/database/postgresql.ts +3 -3
- package/src/cli/templates/database/sqlite.ts +3 -3
- package/src/cli/templates/deploy.ts +29 -26
- package/src/cli/templates/docker.ts +41 -30
- package/src/cli/templates/frontend/index.ts +33 -15
- package/src/cli/templates/frontend/none.ts +2 -2
- package/src/cli/templates/frontend/react.ts +18 -18
- package/src/cli/templates/frontend/solid.ts +15 -15
- package/src/cli/templates/frontend/svelte.ts +17 -17
- package/src/cli/templates/frontend/vue.ts +15 -15
- package/src/cli/templates/generators/index.ts +29 -29
- package/src/cli/templates/generators/types.ts +21 -21
- package/src/cli/templates/index.ts +6 -6
- package/src/cli/templates/project/api.ts +37 -36
- package/src/cli/templates/project/default.ts +25 -25
- package/src/cli/templates/project/fullstack.ts +28 -26
- package/src/cli/templates/project/index.ts +55 -16
- package/src/cli/templates/project/minimal.ts +17 -12
- package/src/cli/templates/project/types.ts +10 -5
- package/src/cli/templates/project/website.ts +14 -14
- package/src/cli/utils/fs.ts +55 -41
- package/src/cli/utils/index.ts +3 -3
- package/src/cli/utils/strings.ts +47 -33
- package/src/cli/utils/version.ts +14 -8
- package/src/config/env-validation.ts +100 -0
- package/src/config/env.ts +169 -41
- package/src/config/index.ts +28 -20
- package/src/config/loader.ts +25 -16
- package/src/config/merge.ts +21 -10
- package/src/config/types.ts +545 -25
- package/src/config/validation.ts +215 -7
- package/src/container/forward-ref.ts +22 -22
- package/src/container/index.ts +34 -12
- package/src/context/index.ts +11 -1
- package/src/database/index.ts +7 -190
- package/src/database/orm/builder.ts +457 -0
- package/src/database/orm/casts/index.ts +130 -0
- package/src/database/orm/casts/types.ts +25 -0
- package/src/database/orm/compiler.ts +304 -0
- package/src/database/orm/hooks/index.ts +114 -0
- package/src/database/orm/index.ts +61 -0
- package/src/database/orm/model-registry.ts +59 -0
- package/src/database/orm/model.ts +821 -0
- package/src/database/orm/relationships/base.ts +146 -0
- package/src/database/orm/relationships/belongs-to-many.ts +179 -0
- package/src/database/orm/relationships/belongs-to.ts +56 -0
- package/src/database/orm/relationships/has-many.ts +45 -0
- package/src/database/orm/relationships/has-one.ts +41 -0
- package/src/database/orm/relationships/index.ts +11 -0
- package/src/database/orm/scopes/index.ts +55 -0
- package/src/events/__tests__/event-system.test.ts +235 -0
- package/src/events/config.ts +238 -0
- package/src/events/example-usage.ts +185 -0
- package/src/events/index.ts +278 -0
- package/src/events/manager.ts +385 -0
- package/src/events/registry.ts +182 -0
- package/src/events/types.ts +124 -0
- package/src/frontend/api-routes.ts +65 -23
- package/src/frontend/bundler.ts +76 -34
- package/src/frontend/console-client.ts +2 -2
- package/src/frontend/console-stream.ts +94 -38
- package/src/frontend/dev-server.ts +94 -46
- package/src/frontend/file-router.ts +61 -19
- package/src/frontend/frameworks/index.ts +37 -10
- package/src/frontend/frameworks/react.ts +10 -8
- package/src/frontend/frameworks/solid.ts +11 -9
- package/src/frontend/frameworks/svelte.ts +15 -9
- package/src/frontend/frameworks/vue.ts +13 -11
- package/src/frontend/hmr-client.ts +12 -10
- package/src/frontend/hmr.ts +146 -103
- package/src/frontend/index.ts +14 -5
- package/src/frontend/islands.ts +41 -22
- package/src/frontend/isr.ts +59 -37
- package/src/frontend/layout.ts +36 -21
- package/src/frontend/ssr/react.ts +74 -27
- package/src/frontend/ssr/solid.ts +54 -20
- package/src/frontend/ssr/svelte.ts +48 -14
- package/src/frontend/ssr/vue.ts +50 -18
- package/src/frontend/ssr.ts +83 -39
- package/src/frontend/types.ts +91 -56
- package/src/health/index.ts +21 -9
- package/src/i18n/engine.ts +305 -0
- package/src/i18n/index.ts +38 -0
- package/src/i18n/loader.ts +218 -0
- package/src/i18n/middleware.ts +164 -0
- package/src/i18n/negotiator.ts +162 -0
- package/src/i18n/types.ts +158 -0
- package/src/index.ts +179 -27
- package/src/jobs/drivers/memory.ts +315 -0
- package/src/jobs/drivers/redis.ts +459 -0
- package/src/jobs/index.ts +30 -0
- package/src/jobs/queue.ts +281 -0
- package/src/jobs/types.ts +295 -0
- package/src/jobs/worker.ts +380 -0
- package/src/logger/index.ts +1 -3
- package/src/logger/transports/index.ts +62 -22
- package/src/metrics/index.ts +25 -16
- package/src/migrations/index.ts +9 -0
- package/src/modules/filters.ts +13 -17
- package/src/modules/guards.ts +49 -26
- package/src/modules/index.ts +409 -298
- package/src/modules/interceptors.ts +58 -20
- package/src/modules/lazy.ts +11 -19
- package/src/modules/lifecycle.ts +15 -7
- package/src/modules/metadata.ts +15 -5
- package/src/modules/pipes.ts +94 -72
- package/src/notification/channels/base.ts +68 -0
- package/src/notification/channels/email.ts +105 -0
- package/src/notification/channels/push.ts +104 -0
- package/src/notification/channels/sms.ts +105 -0
- package/src/notification/channels/whatsapp.ts +104 -0
- package/src/notification/index.ts +48 -0
- package/src/notification/service.ts +354 -0
- package/src/notification/types.ts +344 -0
- package/src/observability/__tests__/observability.test.ts +483 -0
- package/src/observability/breadcrumbs.ts +114 -0
- package/src/observability/index.ts +136 -0
- package/src/observability/interceptor.ts +85 -0
- package/src/observability/service.ts +303 -0
- package/src/observability/trace.ts +37 -0
- package/src/observability/types.ts +196 -0
- package/src/openapi/__tests__/decorators.test.ts +335 -0
- package/src/openapi/__tests__/document-builder.test.ts +285 -0
- package/src/openapi/__tests__/route-scanner.test.ts +334 -0
- package/src/openapi/__tests__/schema-generator.test.ts +275 -0
- package/src/openapi/decorators.ts +328 -0
- package/src/openapi/document-builder.ts +274 -0
- package/src/openapi/index.ts +112 -0
- package/src/openapi/metadata.ts +112 -0
- package/src/openapi/route-scanner.ts +289 -0
- package/src/openapi/schema-generator.ts +256 -0
- package/src/openapi/swagger-module.ts +166 -0
- package/src/openapi/types.ts +398 -0
- package/src/orm/index.ts +10 -0
- package/src/rpc/index.ts +3 -1
- package/src/schema/index.ts +9 -0
- package/src/security/index.ts +15 -6
- package/src/ssg/index.ts +9 -8
- package/src/telemetry/index.ts +76 -22
- package/src/template/index.ts +7 -0
- package/src/templates/engine.ts +224 -0
- package/src/templates/index.ts +9 -0
- package/src/templates/loader.ts +331 -0
- package/src/templates/renderers/markdown.ts +212 -0
- package/src/templates/renderers/simple.ts +269 -0
- package/src/templates/types.ts +154 -0
- package/src/testing/index.ts +100 -27
- package/src/types/optional-deps.d.ts +347 -187
- package/src/validation/index.ts +92 -2
- package/src/validation/schemas.ts +536 -0
- package/tests/integration/fullstack.test.ts +4 -4
- package/tests/unit/database.test.ts +2 -72
- package/tests/unit/env-validation.test.ts +166 -0
- package/tests/unit/events.test.ts +910 -0
- package/tests/unit/i18n.test.ts +455 -0
- package/tests/unit/jobs.test.ts +493 -0
- package/tests/unit/notification.test.ts +988 -0
- package/tests/unit/observability.test.ts +453 -0
- package/tests/unit/orm/builder.test.ts +323 -0
- package/tests/unit/orm/casts.test.ts +179 -0
- package/tests/unit/orm/compiler.test.ts +220 -0
- package/tests/unit/orm/eager-loading.test.ts +285 -0
- package/tests/unit/orm/hooks.test.ts +191 -0
- package/tests/unit/orm/model.test.ts +373 -0
- package/tests/unit/orm/relationships.test.ts +303 -0
- package/tests/unit/orm/scopes.test.ts +74 -0
- package/tests/unit/templates-simple.test.ts +53 -0
- package/tests/unit/templates.test.ts +454 -0
- package/tests/unit/validation.test.ts +18 -24
- package/tsconfig.json +11 -3
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI Document Builder
|
|
3
|
+
*
|
|
4
|
+
* Fluent API for building OpenAPI 3.1 documents with configuration for
|
|
5
|
+
* servers, security schemes, tags, and other top-level metadata.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
ApiKeySecurityOptions,
|
|
10
|
+
OpenAPIComponents,
|
|
11
|
+
OpenAPIDocument,
|
|
12
|
+
OpenAPISecurityScheme,
|
|
13
|
+
OpenAPIServer,
|
|
14
|
+
OpenAPITag,
|
|
15
|
+
SecuritySchemeOptions,
|
|
16
|
+
} from './types';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* DocumentBuilder - Fluent API for constructing OpenAPI documents
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const document = new DocumentBuilder()
|
|
24
|
+
* .setTitle('My API')
|
|
25
|
+
* .setVersion('1.0.0')
|
|
26
|
+
* .setDescription('API description')
|
|
27
|
+
* .addBearerAuth()
|
|
28
|
+
* .addTag('users', 'User management endpoints')
|
|
29
|
+
* .build();
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export class DocumentBuilder {
|
|
33
|
+
private document: Partial<OpenAPIDocument> = {
|
|
34
|
+
openapi: '3.1.0',
|
|
35
|
+
info: {
|
|
36
|
+
title: 'API',
|
|
37
|
+
version: '1.0.0',
|
|
38
|
+
},
|
|
39
|
+
paths: {},
|
|
40
|
+
components: {
|
|
41
|
+
schemas: {},
|
|
42
|
+
securitySchemes: {},
|
|
43
|
+
},
|
|
44
|
+
tags: [],
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Set the API title
|
|
49
|
+
*/
|
|
50
|
+
setTitle(title: string): this {
|
|
51
|
+
if (!this.document.info) {
|
|
52
|
+
this.document.info = { title, version: '1.0.0' };
|
|
53
|
+
} else {
|
|
54
|
+
this.document.info.title = title;
|
|
55
|
+
}
|
|
56
|
+
return this;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Set the API description
|
|
61
|
+
*/
|
|
62
|
+
setDescription(description: string): this {
|
|
63
|
+
if (!this.document.info) {
|
|
64
|
+
this.document.info = { title: 'API', version: '1.0.0', description };
|
|
65
|
+
} else {
|
|
66
|
+
this.document.info.description = description;
|
|
67
|
+
}
|
|
68
|
+
return this;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Set the API version
|
|
73
|
+
*/
|
|
74
|
+
setVersion(version: string): this {
|
|
75
|
+
if (!this.document.info) {
|
|
76
|
+
this.document.info = { title: 'API', version };
|
|
77
|
+
} else {
|
|
78
|
+
this.document.info.version = version;
|
|
79
|
+
}
|
|
80
|
+
return this;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Set contact information
|
|
85
|
+
*/
|
|
86
|
+
setContact(name: string, url?: string, email?: string): this {
|
|
87
|
+
if (!this.document.info) {
|
|
88
|
+
this.document.info = { title: 'API', version: '1.0.0' };
|
|
89
|
+
}
|
|
90
|
+
this.document.info.contact = { name, url, email };
|
|
91
|
+
return this;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Set license information
|
|
96
|
+
*/
|
|
97
|
+
setLicense(name: string, url?: string): this {
|
|
98
|
+
if (!this.document.info) {
|
|
99
|
+
this.document.info = { title: 'API', version: '1.0.0' };
|
|
100
|
+
}
|
|
101
|
+
this.document.info.license = { name, url };
|
|
102
|
+
return this;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Add a server
|
|
107
|
+
*/
|
|
108
|
+
addServer(url: string, description?: string): this {
|
|
109
|
+
if (!this.document.servers) {
|
|
110
|
+
this.document.servers = [];
|
|
111
|
+
}
|
|
112
|
+
this.document.servers.push({ url, description });
|
|
113
|
+
return this;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Add Bearer token authentication
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
* ```typescript
|
|
121
|
+
* builder.addBearerAuth('JWT')
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
addBearerAuth(
|
|
125
|
+
name = 'bearer',
|
|
126
|
+
options?: SecuritySchemeOptions,
|
|
127
|
+
): this {
|
|
128
|
+
if (!this.document.components) {
|
|
129
|
+
this.document.components = { schemas: {}, securitySchemes: {} };
|
|
130
|
+
}
|
|
131
|
+
if (!this.document.components.securitySchemes) {
|
|
132
|
+
this.document.components.securitySchemes = {};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const scheme: OpenAPISecurityScheme = {
|
|
136
|
+
type: 'http',
|
|
137
|
+
scheme: 'bearer',
|
|
138
|
+
bearerFormat: options?.bearerFormat ?? 'JWT',
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
if (options?.description) {
|
|
142
|
+
scheme.description = options.description;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
this.document.components.securitySchemes[name] = scheme;
|
|
146
|
+
return this;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Add Basic authentication
|
|
151
|
+
*/
|
|
152
|
+
addBasicAuth(name = 'basic', options?: SecuritySchemeOptions): this {
|
|
153
|
+
if (!this.document.components) {
|
|
154
|
+
this.document.components = { schemas: {}, securitySchemes: {} };
|
|
155
|
+
}
|
|
156
|
+
if (!this.document.components.securitySchemes) {
|
|
157
|
+
this.document.components.securitySchemes = {};
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const scheme: OpenAPISecurityScheme = {
|
|
161
|
+
type: 'http',
|
|
162
|
+
scheme: 'basic',
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
if (options?.description) {
|
|
166
|
+
scheme.description = options.description;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
this.document.components.securitySchemes[name] = scheme;
|
|
170
|
+
return this;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Add API Key authentication
|
|
175
|
+
*/
|
|
176
|
+
addApiKey(
|
|
177
|
+
options: ApiKeySecurityOptions,
|
|
178
|
+
name = 'api_key',
|
|
179
|
+
): this {
|
|
180
|
+
if (!this.document.components) {
|
|
181
|
+
this.document.components = { schemas: {}, securitySchemes: {} };
|
|
182
|
+
}
|
|
183
|
+
if (!this.document.components.securitySchemes) {
|
|
184
|
+
this.document.components.securitySchemes = {};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const scheme: OpenAPISecurityScheme = {
|
|
188
|
+
type: 'apiKey',
|
|
189
|
+
name: options.name,
|
|
190
|
+
in: options.in,
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
if (options.description) {
|
|
194
|
+
scheme.description = options.description;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
this.document.components.securitySchemes[name] = scheme;
|
|
198
|
+
return this;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Add an OAuth2 security scheme
|
|
203
|
+
*/
|
|
204
|
+
addOAuth2(
|
|
205
|
+
name: string,
|
|
206
|
+
authorizationUrl: string,
|
|
207
|
+
tokenUrl?: string,
|
|
208
|
+
refreshUrl?: string,
|
|
209
|
+
): this {
|
|
210
|
+
if (!this.document.components) {
|
|
211
|
+
this.document.components = { schemas: {}, securitySchemes: {} };
|
|
212
|
+
}
|
|
213
|
+
if (!this.document.components.securitySchemes) {
|
|
214
|
+
this.document.components.securitySchemes = {};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
this.document.components.securitySchemes[name] = {
|
|
218
|
+
type: 'oauth2',
|
|
219
|
+
flows: {
|
|
220
|
+
authorizationCode: {
|
|
221
|
+
authorizationUrl,
|
|
222
|
+
tokenUrl: tokenUrl || '',
|
|
223
|
+
refreshUrl,
|
|
224
|
+
scopes: {},
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
return this;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Add an OpenID Connect security scheme
|
|
234
|
+
*/
|
|
235
|
+
addOpenIdConnect(name: string, url: string): this {
|
|
236
|
+
if (!this.document.components) {
|
|
237
|
+
this.document.components = { schemas: {}, securitySchemes: {} };
|
|
238
|
+
}
|
|
239
|
+
if (!this.document.components.securitySchemes) {
|
|
240
|
+
this.document.components.securitySchemes = {};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
this.document.components.securitySchemes[name] = {
|
|
244
|
+
type: 'openIdConnect',
|
|
245
|
+
openIdConnectUrl: url,
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
return this;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* Add a tag for organizing operations
|
|
253
|
+
*/
|
|
254
|
+
addTag(name: string, description?: string): this {
|
|
255
|
+
if (!this.document.tags) {
|
|
256
|
+
this.document.tags = [];
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const tag: OpenAPITag = { name };
|
|
260
|
+
if (description) {
|
|
261
|
+
tag.description = description;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
this.document.tags.push(tag);
|
|
265
|
+
return this;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Build and return the final OpenAPI document
|
|
270
|
+
*/
|
|
271
|
+
build(): OpenAPIDocument {
|
|
272
|
+
return this.document as OpenAPIDocument;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI Module
|
|
3
|
+
*
|
|
4
|
+
* Auto-generate OpenAPI 3.1 specifications from Bueno controllers and decorators.
|
|
5
|
+
* Provides decorators for documenting API endpoints and a SwaggerModule for setup.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* import {
|
|
10
|
+
* DocumentBuilder,
|
|
11
|
+
* SwaggerModule,
|
|
12
|
+
* ApiOperation,
|
|
13
|
+
* ApiResponse,
|
|
14
|
+
* ApiTags,
|
|
15
|
+
* } from '@buenojs/bueno/openapi';
|
|
16
|
+
*
|
|
17
|
+
* // 1. Document your controller
|
|
18
|
+
* @Controller('/users')
|
|
19
|
+
* @ApiTags('users')
|
|
20
|
+
* class UsersController {
|
|
21
|
+
* @Get()
|
|
22
|
+
* @ApiOperation({ summary: 'List all users' })
|
|
23
|
+
* @ApiResponse({ status: 200, description: 'Success', type: [User] })
|
|
24
|
+
* async getAll() { ... }
|
|
25
|
+
* }
|
|
26
|
+
*
|
|
27
|
+
* // 2. Create OpenAPI document
|
|
28
|
+
* const config = new DocumentBuilder()
|
|
29
|
+
* .setTitle('My API')
|
|
30
|
+
* .setVersion('1.0.0')
|
|
31
|
+
* .addBearerAuth()
|
|
32
|
+
* .build();
|
|
33
|
+
*
|
|
34
|
+
* const document = SwaggerModule.createDocument(app, config, [UsersController]);
|
|
35
|
+
*
|
|
36
|
+
* // 3. Setup Swagger UI
|
|
37
|
+
* SwaggerModule.setup('/api-docs', app, document);
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
// ============= Type Exports =============
|
|
42
|
+
|
|
43
|
+
export type {
|
|
44
|
+
OpenAPIDocument,
|
|
45
|
+
OpenAPIInfo,
|
|
46
|
+
OpenAPIContact,
|
|
47
|
+
OpenAPILicense,
|
|
48
|
+
OpenAPIServer,
|
|
49
|
+
OpenAPIPaths,
|
|
50
|
+
OpenAPIPath,
|
|
51
|
+
OpenAPIOperation,
|
|
52
|
+
OpenAPIExternalDocs,
|
|
53
|
+
OpenAPIParameter,
|
|
54
|
+
OpenAPIRequestBody,
|
|
55
|
+
OpenAPIMediaType,
|
|
56
|
+
OpenAPIExample,
|
|
57
|
+
OpenAPIResponse,
|
|
58
|
+
OpenAPIHeader,
|
|
59
|
+
OpenAPIResponses,
|
|
60
|
+
OpenAPISchema,
|
|
61
|
+
OpenAPIDiscriminator,
|
|
62
|
+
OpenAPIXML,
|
|
63
|
+
OpenAPIComponents,
|
|
64
|
+
OpenAPISecurityScheme,
|
|
65
|
+
OpenAPIOAuthFlows,
|
|
66
|
+
OpenAPIOAuthFlow,
|
|
67
|
+
OpenAPISecurity,
|
|
68
|
+
OpenAPITag,
|
|
69
|
+
SwaggerOptions,
|
|
70
|
+
ApiOperationOptions,
|
|
71
|
+
ApiResponseOptions,
|
|
72
|
+
ApiParamOptions,
|
|
73
|
+
ApiQueryOptions,
|
|
74
|
+
ApiHeaderOptions,
|
|
75
|
+
ApiBodyOptions,
|
|
76
|
+
ApiPropertyOptions,
|
|
77
|
+
SecuritySchemeOptions,
|
|
78
|
+
ApiKeySecurityOptions,
|
|
79
|
+
Constructor,
|
|
80
|
+
} from './types';
|
|
81
|
+
|
|
82
|
+
// ============= Class Exports =============
|
|
83
|
+
|
|
84
|
+
export { DocumentBuilder } from './document-builder';
|
|
85
|
+
export { SchemaGenerator } from './schema-generator';
|
|
86
|
+
export { RouteScanner } from './route-scanner';
|
|
87
|
+
export { SwaggerModule } from './swagger-module';
|
|
88
|
+
|
|
89
|
+
// ============= Decorator Exports =============
|
|
90
|
+
|
|
91
|
+
// Class-level decorators
|
|
92
|
+
export {
|
|
93
|
+
ApiTags,
|
|
94
|
+
ApiBearerAuth,
|
|
95
|
+
ApiBasicAuth,
|
|
96
|
+
ApiApiKey,
|
|
97
|
+
ApiExcludeController,
|
|
98
|
+
} from './decorators';
|
|
99
|
+
|
|
100
|
+
// Method-level decorators
|
|
101
|
+
export {
|
|
102
|
+
ApiOperation,
|
|
103
|
+
ApiResponse,
|
|
104
|
+
ApiParam,
|
|
105
|
+
ApiQuery,
|
|
106
|
+
ApiHeader,
|
|
107
|
+
ApiBody,
|
|
108
|
+
ApiExcludeEndpoint,
|
|
109
|
+
} from './decorators';
|
|
110
|
+
|
|
111
|
+
// Property-level decorators (for DTOs)
|
|
112
|
+
export { ApiProperty, ApiPropertyOptional } from './decorators';
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAPI Metadata Storage
|
|
3
|
+
*
|
|
4
|
+
* Isolated metadata storage using WeakMap, following the same pattern as src/modules/metadata.ts
|
|
5
|
+
* This avoids circular dependencies and keeps metadata separate from the core module system.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { Constructor } from './types';
|
|
9
|
+
|
|
10
|
+
// ============= Class-Level Metadata =============
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Stores metadata on class constructors (e.g., @ApiTags, @ApiBearerAuth, @ApiExcludeController)
|
|
14
|
+
*/
|
|
15
|
+
const classMetadataStore = new WeakMap<Constructor, Map<string, unknown>>();
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Set metadata on a class constructor
|
|
19
|
+
*/
|
|
20
|
+
export function setApiMetadata(
|
|
21
|
+
target: Constructor,
|
|
22
|
+
key: string,
|
|
23
|
+
value: unknown,
|
|
24
|
+
): void {
|
|
25
|
+
if (!classMetadataStore.has(target)) {
|
|
26
|
+
classMetadataStore.set(target, new Map());
|
|
27
|
+
}
|
|
28
|
+
classMetadataStore.get(target)?.set(key, value);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Get metadata from a class constructor
|
|
33
|
+
*/
|
|
34
|
+
export function getApiMetadata<T>(
|
|
35
|
+
target: Constructor,
|
|
36
|
+
key: string,
|
|
37
|
+
): T | undefined {
|
|
38
|
+
return classMetadataStore.get(target)?.get(key) as T | undefined;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// ============= Method/Prototype-Level Metadata =============
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Stores metadata on method prototypes (e.g., @ApiOperation, @ApiResponse, @ApiParam)
|
|
45
|
+
*/
|
|
46
|
+
const methodMetadataStore = new WeakMap<object, Map<string, unknown>>();
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Set metadata on a method prototype
|
|
50
|
+
*/
|
|
51
|
+
export function setApiMethodMetadata(
|
|
52
|
+
target: object,
|
|
53
|
+
key: string,
|
|
54
|
+
value: unknown,
|
|
55
|
+
): void {
|
|
56
|
+
if (!methodMetadataStore.has(target)) {
|
|
57
|
+
methodMetadataStore.set(target, new Map());
|
|
58
|
+
}
|
|
59
|
+
methodMetadataStore.get(target)?.set(key, value);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Get metadata from a method prototype
|
|
64
|
+
*/
|
|
65
|
+
export function getApiMethodMetadata<T>(
|
|
66
|
+
target: object,
|
|
67
|
+
key: string,
|
|
68
|
+
): T | undefined {
|
|
69
|
+
return methodMetadataStore.get(target)?.get(key) as T | undefined;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// ============= Property-Level Metadata =============
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Stores metadata on class properties (e.g., @ApiProperty decorators on DTO properties)
|
|
76
|
+
*/
|
|
77
|
+
const propertyMetadataStore = new WeakMap<object, Map<string, unknown>>();
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Set metadata on a property of a class prototype
|
|
81
|
+
*/
|
|
82
|
+
export function setApiPropertyMetadata(
|
|
83
|
+
target: object,
|
|
84
|
+
propertyKey: string | symbol,
|
|
85
|
+
value: unknown,
|
|
86
|
+
): void {
|
|
87
|
+
if (!propertyMetadataStore.has(target)) {
|
|
88
|
+
propertyMetadataStore.set(target, new Map());
|
|
89
|
+
}
|
|
90
|
+
const key = typeof propertyKey === 'symbol' ? propertyKey.toString() : propertyKey;
|
|
91
|
+
propertyMetadataStore.get(target)?.set(key, value);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Get metadata from a property of a class prototype
|
|
96
|
+
*/
|
|
97
|
+
export function getApiPropertyMetadata<T>(
|
|
98
|
+
target: object,
|
|
99
|
+
propertyKey: string | symbol,
|
|
100
|
+
): T | undefined {
|
|
101
|
+
const key = typeof propertyKey === 'symbol' ? propertyKey.toString() : propertyKey;
|
|
102
|
+
return propertyMetadataStore.get(target)?.get(key) as T | undefined;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Get all property metadata keys from a class prototype
|
|
107
|
+
*/
|
|
108
|
+
export function getApiPropertyKeys(target: object): (string | symbol)[] {
|
|
109
|
+
const metaMap = propertyMetadataStore.get(target);
|
|
110
|
+
if (!metaMap) return [];
|
|
111
|
+
return Array.from(metaMap.keys()) as (string | symbol)[];
|
|
112
|
+
}
|