@riktajs/swagger 0.10.2 → 0.10.3

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.
Files changed (43) hide show
  1. package/dist/index.cjs +1253 -0
  2. package/dist/index.cjs.map +1 -0
  3. package/dist/index.d.cts +498 -0
  4. package/dist/index.d.ts +498 -7
  5. package/dist/index.js +1163 -6
  6. package/dist/index.js.map +1 -0
  7. package/package.json +13 -6
  8. package/dist/constants.d.ts +0 -11
  9. package/dist/constants.js +0 -11
  10. package/dist/decorators/api-body.decorator.d.ts +0 -4
  11. package/dist/decorators/api-body.decorator.js +0 -11
  12. package/dist/decorators/api-exclude.decorator.d.ts +0 -9
  13. package/dist/decorators/api-exclude.decorator.js +0 -31
  14. package/dist/decorators/api-header.decorator.d.ts +0 -4
  15. package/dist/decorators/api-header.decorator.js +0 -12
  16. package/dist/decorators/api-operation.decorator.d.ts +0 -4
  17. package/dist/decorators/api-operation.decorator.js +0 -11
  18. package/dist/decorators/api-param.decorator.d.ts +0 -4
  19. package/dist/decorators/api-param.decorator.js +0 -12
  20. package/dist/decorators/api-property.decorator.d.ts +0 -11
  21. package/dist/decorators/api-property.decorator.js +0 -20
  22. package/dist/decorators/api-query.decorator.d.ts +0 -4
  23. package/dist/decorators/api-query.decorator.js +0 -12
  24. package/dist/decorators/api-response.decorator.d.ts +0 -15
  25. package/dist/decorators/api-response.decorator.js +0 -45
  26. package/dist/decorators/api-security.decorator.d.ts +0 -8
  27. package/dist/decorators/api-security.decorator.js +0 -35
  28. package/dist/decorators/api-tags.decorator.d.ts +0 -3
  29. package/dist/decorators/api-tags.decorator.js +0 -22
  30. package/dist/decorators/index.d.ts +0 -10
  31. package/dist/decorators/index.js +0 -10
  32. package/dist/openapi/generator.d.ts +0 -49
  33. package/dist/openapi/generator.js +0 -409
  34. package/dist/openapi/index.d.ts +0 -2
  35. package/dist/openapi/index.js +0 -2
  36. package/dist/openapi/zod-to-openapi.d.ts +0 -5
  37. package/dist/openapi/zod-to-openapi.js +0 -115
  38. package/dist/plugin/index.d.ts +0 -1
  39. package/dist/plugin/index.js +0 -1
  40. package/dist/plugin/swagger.plugin.d.ts +0 -38
  41. package/dist/plugin/swagger.plugin.js +0 -126
  42. package/dist/types.d.ts +0 -338
  43. package/dist/types.js +0 -1
@@ -1,22 +0,0 @@
1
- import 'reflect-metadata';
2
- import { API_TAGS_METADATA } from '../constants.js';
3
- export function ApiTags(...tags) {
4
- return (target, propertyKey, descriptor) => {
5
- if (propertyKey !== undefined && descriptor !== undefined) {
6
- const existingTags = Reflect.getMetadata(API_TAGS_METADATA, target, propertyKey) ?? [];
7
- Reflect.defineMetadata(API_TAGS_METADATA, [...existingTags, ...tags], target, propertyKey);
8
- }
9
- else {
10
- const existingTags = Reflect.getMetadata(API_TAGS_METADATA, target) ?? [];
11
- Reflect.defineMetadata(API_TAGS_METADATA, [...existingTags, ...tags], target);
12
- }
13
- };
14
- }
15
- export function getApiTags(target, propertyKey) {
16
- if (propertyKey !== undefined) {
17
- const methodTags = Reflect.getMetadata(API_TAGS_METADATA, target.prototype, propertyKey) ?? [];
18
- const classTags = Reflect.getMetadata(API_TAGS_METADATA, target) ?? [];
19
- return [...new Set([...classTags, ...methodTags])];
20
- }
21
- return Reflect.getMetadata(API_TAGS_METADATA, target) ?? [];
22
- }
@@ -1,10 +0,0 @@
1
- export { ApiTags, getApiTags } from './api-tags.decorator.js';
2
- export { ApiOperation, getApiOperation } from './api-operation.decorator.js';
3
- export { ApiResponse, ApiOkResponse, ApiCreatedResponse, ApiAcceptedResponse, ApiNoContentResponse, ApiBadRequestResponse, ApiUnauthorizedResponse, ApiForbiddenResponse, ApiNotFoundResponse, ApiConflictResponse, ApiUnprocessableEntityResponse, ApiInternalServerErrorResponse, getApiResponses, } from './api-response.decorator.js';
4
- export { ApiBody, getApiBody } from './api-body.decorator.js';
5
- export { ApiParam, getApiParams } from './api-param.decorator.js';
6
- export { ApiQuery, getApiQueries } from './api-query.decorator.js';
7
- export { ApiHeader, getApiHeaders } from './api-header.decorator.js';
8
- export { ApiSecurity, ApiBearerAuth, ApiBasicAuth, ApiOAuth2, ApiCookieAuth, getApiSecurity, } from './api-security.decorator.js';
9
- export { ApiProperty, ApiPropertyOptional, ApiHideProperty, getApiProperties, } from './api-property.decorator.js';
10
- export { ApiExcludeEndpoint, ApiExcludeController, isApiExcluded, ApiDeprecated, getApiDeprecated, } from './api-exclude.decorator.js';
@@ -1,10 +0,0 @@
1
- export { ApiTags, getApiTags } from './api-tags.decorator.js';
2
- export { ApiOperation, getApiOperation } from './api-operation.decorator.js';
3
- export { ApiResponse, ApiOkResponse, ApiCreatedResponse, ApiAcceptedResponse, ApiNoContentResponse, ApiBadRequestResponse, ApiUnauthorizedResponse, ApiForbiddenResponse, ApiNotFoundResponse, ApiConflictResponse, ApiUnprocessableEntityResponse, ApiInternalServerErrorResponse, getApiResponses, } from './api-response.decorator.js';
4
- export { ApiBody, getApiBody } from './api-body.decorator.js';
5
- export { ApiParam, getApiParams } from './api-param.decorator.js';
6
- export { ApiQuery, getApiQueries } from './api-query.decorator.js';
7
- export { ApiHeader, getApiHeaders } from './api-header.decorator.js';
8
- export { ApiSecurity, ApiBearerAuth, ApiBasicAuth, ApiOAuth2, ApiCookieAuth, getApiSecurity, } from './api-security.decorator.js';
9
- export { ApiProperty, ApiPropertyOptional, ApiHideProperty, getApiProperties, } from './api-property.decorator.js';
10
- export { ApiExcludeEndpoint, ApiExcludeController, isApiExcluded, ApiDeprecated, getApiDeprecated, } from './api-exclude.decorator.js';
@@ -1,49 +0,0 @@
1
- import 'reflect-metadata';
2
- import type { SwaggerConfig, OpenApiDocument, OpenApiSecurityScheme, OpenApiInfoObject } from '../types.js';
3
- type Constructor<T = unknown> = new (...args: any[]) => T;
4
- interface OpenApiGeneratorConfig extends Omit<SwaggerConfig, 'info'> {
5
- title?: string;
6
- version?: string;
7
- description?: string;
8
- contact?: OpenApiInfoObject['contact'];
9
- license?: OpenApiInfoObject['license'];
10
- termsOfService?: string;
11
- info?: OpenApiInfoObject;
12
- }
13
- export declare class OpenApiGenerator {
14
- private config;
15
- private controllers;
16
- private globalSecuritySchemes;
17
- constructor(config?: OpenApiGeneratorConfig);
18
- addController(controller: Constructor): this;
19
- addControllers(controllers: Constructor[]): this;
20
- addSecurityScheme(name: string, scheme: OpenApiSecurityScheme): this;
21
- generate(): OpenApiDocument;
22
- private getControllerMeta;
23
- private getControllerRoutes;
24
- private getControllerTags;
25
- private isControllerExcluded;
26
- private isControllerDeprecated;
27
- private isEndpointExcluded;
28
- private isEndpointDeprecated;
29
- private getOperationMetadata;
30
- private getResponseMetadata;
31
- private getBodyMetadata;
32
- private getSwaggerParamMetadata;
33
- private getQueryMetadata;
34
- private getHeaderMetadata;
35
- private getSecurityMetadata;
36
- private getMethodTags;
37
- private getHttpStatusCode;
38
- private getCoreParams;
39
- private normalizePath;
40
- private buildOperation;
41
- private buildParameters;
42
- private extractPathParams;
43
- private buildRequestBody;
44
- private buildResponses;
45
- private getDefaultStatusDescription;
46
- private buildSecuritySchemes;
47
- }
48
- export declare function createOpenApiGenerator(config?: Partial<SwaggerConfig>): OpenApiGenerator;
49
- export {};
@@ -1,409 +0,0 @@
1
- import 'reflect-metadata';
2
- import { ParamType, getControllerMetadata, getRoutes, getParamMetadata as getCoreParamMetadata, getHttpCode, getClassMetadata, getMethodMetadata, } from '@riktajs/core';
3
- import { API_TAGS_METADATA, API_OPERATION_METADATA, API_RESPONSE_METADATA, API_BODY_METADATA, API_PARAM_METADATA, API_QUERY_METADATA, API_HEADER_METADATA, API_SECURITY_METADATA, API_EXCLUDE_METADATA, API_DEPRECATED_METADATA, } from '../constants.js';
4
- import { zodToOpenApi, toOpenApiSchema } from './zod-to-openapi.js';
5
- const DEFAULT_SWAGGER_CONFIG = {
6
- info: {
7
- title: 'API Documentation',
8
- version: '1.0.0',
9
- },
10
- };
11
- export class OpenApiGenerator {
12
- config;
13
- controllers = [];
14
- globalSecuritySchemes = new Map();
15
- constructor(config = {}) {
16
- const info = config.info ?? {
17
- title: config.title ?? DEFAULT_SWAGGER_CONFIG.info?.title ?? 'API Documentation',
18
- version: config.version ?? DEFAULT_SWAGGER_CONFIG.info?.version ?? '1.0.0',
19
- description: config.description,
20
- contact: config.contact,
21
- license: config.license,
22
- termsOfService: config.termsOfService,
23
- };
24
- const { title, version, description, contact, license, termsOfService, ...restConfig } = config;
25
- this.config = {
26
- ...DEFAULT_SWAGGER_CONFIG,
27
- ...restConfig,
28
- info,
29
- };
30
- }
31
- addController(controller) {
32
- this.controllers.push(controller);
33
- return this;
34
- }
35
- addControllers(controllers) {
36
- this.controllers.push(...controllers);
37
- return this;
38
- }
39
- addSecurityScheme(name, scheme) {
40
- this.globalSecuritySchemes.set(name, scheme);
41
- return this;
42
- }
43
- generate() {
44
- const paths = {};
45
- const tags = [];
46
- const seenTags = new Set();
47
- for (const controller of this.controllers) {
48
- if (this.isControllerExcluded(controller)) {
49
- continue;
50
- }
51
- const controllerMeta = this.getControllerMeta(controller);
52
- if (!controllerMeta)
53
- continue;
54
- const controllerTags = this.getControllerTags(controller);
55
- const controllerDeprecated = this.isControllerDeprecated(controller);
56
- for (const tag of controllerTags) {
57
- if (!seenTags.has(tag)) {
58
- seenTags.add(tag);
59
- tags.push({ name: tag });
60
- }
61
- }
62
- const routes = this.getControllerRoutes(controller);
63
- for (const route of routes) {
64
- if (this.isEndpointExcluded(controller, route.handlerName)) {
65
- continue;
66
- }
67
- const fullPath = this.normalizePath(controllerMeta.prefix, route.path);
68
- const method = route.method.toLowerCase();
69
- if (!paths[fullPath]) {
70
- paths[fullPath] = {};
71
- }
72
- const operation = this.buildOperation(controller, route, controllerTags, controllerDeprecated);
73
- paths[fullPath][method] = operation;
74
- }
75
- }
76
- const securitySchemes = this.buildSecuritySchemes();
77
- const document = {
78
- openapi: '3.0.3',
79
- info: this.config.info,
80
- paths,
81
- };
82
- if (tags.length > 0) {
83
- document.tags = tags;
84
- }
85
- if (this.config.servers && this.config.servers.length > 0) {
86
- document.servers = this.config.servers;
87
- }
88
- if (Object.keys(securitySchemes).length > 0) {
89
- document.components = {
90
- ...document.components,
91
- securitySchemes,
92
- };
93
- }
94
- if (this.config.externalDocs) {
95
- document.externalDocs = this.config.externalDocs;
96
- }
97
- return document;
98
- }
99
- getControllerMeta(controller) {
100
- return getControllerMetadata(controller);
101
- }
102
- getControllerRoutes(controller) {
103
- return getRoutes(controller);
104
- }
105
- getControllerTags(controller) {
106
- return getClassMetadata(API_TAGS_METADATA, controller) || [];
107
- }
108
- isControllerExcluded(controller) {
109
- return getClassMetadata(API_EXCLUDE_METADATA, controller) === true;
110
- }
111
- isControllerDeprecated(controller) {
112
- return getClassMetadata(API_DEPRECATED_METADATA, controller) === true;
113
- }
114
- isEndpointExcluded(controller, handlerName) {
115
- return getMethodMetadata(API_EXCLUDE_METADATA, controller, handlerName) === true;
116
- }
117
- isEndpointDeprecated(controller, handlerName) {
118
- const controllerLevel = getClassMetadata(API_DEPRECATED_METADATA, controller);
119
- const methodLevel = getMethodMetadata(API_DEPRECATED_METADATA, controller, handlerName);
120
- return controllerLevel?.deprecated === true || methodLevel?.deprecated === true;
121
- }
122
- getOperationMetadata(controller, handlerName) {
123
- return getMethodMetadata(API_OPERATION_METADATA, controller, handlerName);
124
- }
125
- getResponseMetadata(controller, handlerName) {
126
- return getMethodMetadata(API_RESPONSE_METADATA, controller, handlerName) || [];
127
- }
128
- getBodyMetadata(controller, handlerName) {
129
- return getMethodMetadata(API_BODY_METADATA, controller, handlerName);
130
- }
131
- getSwaggerParamMetadata(controller, handlerName) {
132
- return getMethodMetadata(API_PARAM_METADATA, controller, handlerName) || [];
133
- }
134
- getQueryMetadata(controller, handlerName) {
135
- return getMethodMetadata(API_QUERY_METADATA, controller, handlerName) || [];
136
- }
137
- getHeaderMetadata(controller, handlerName) {
138
- return getMethodMetadata(API_HEADER_METADATA, controller, handlerName) || [];
139
- }
140
- getSecurityMetadata(controller, handlerName) {
141
- const controllerLevel = getClassMetadata(API_SECURITY_METADATA, controller);
142
- const methodLevel = getMethodMetadata(API_SECURITY_METADATA, controller, handlerName);
143
- const result = [];
144
- if (controllerLevel && typeof controllerLevel === 'object' && 'name' in controllerLevel) {
145
- result.push(controllerLevel);
146
- }
147
- else if (Array.isArray(controllerLevel)) {
148
- result.push(...controllerLevel);
149
- }
150
- if (methodLevel && typeof methodLevel === 'object' && 'name' in methodLevel) {
151
- result.push(methodLevel);
152
- }
153
- else if (Array.isArray(methodLevel)) {
154
- result.push(...methodLevel);
155
- }
156
- return result;
157
- }
158
- getMethodTags(controller, handlerName) {
159
- const operation = this.getOperationMetadata(controller, handlerName);
160
- return operation?.tags;
161
- }
162
- getHttpStatusCode(controller, handlerName) {
163
- return getHttpCode(controller, handlerName);
164
- }
165
- getCoreParams(controller, handlerName) {
166
- return getCoreParamMetadata(controller, handlerName);
167
- }
168
- normalizePath(prefix, path) {
169
- let fullPath = '';
170
- if (prefix) {
171
- fullPath = prefix.startsWith('/') ? prefix : `/${prefix}`;
172
- }
173
- if (path) {
174
- const cleanPath = path.startsWith('/') ? path : `/${path}`;
175
- fullPath = fullPath + cleanPath;
176
- }
177
- if (!fullPath) {
178
- fullPath = '/';
179
- }
180
- fullPath = fullPath.replace(/:([^/]+)/g, '{$1}');
181
- if (fullPath !== '/' && fullPath.endsWith('/')) {
182
- fullPath = fullPath.slice(0, -1);
183
- }
184
- return fullPath;
185
- }
186
- buildOperation(controller, route, controllerTags, controllerDeprecated) {
187
- const handlerName = route.handlerName;
188
- const operationMeta = this.getOperationMetadata(controller, handlerName);
189
- const methodTags = this.getMethodTags(controller, handlerName);
190
- const operation = {
191
- responses: {},
192
- };
193
- const tags = methodTags || controllerTags;
194
- if (tags.length > 0) {
195
- operation.tags = tags;
196
- }
197
- if (operationMeta?.summary) {
198
- operation.summary = operationMeta.summary;
199
- }
200
- if (operationMeta?.description) {
201
- operation.description = operationMeta.description;
202
- }
203
- if (operationMeta?.operationId) {
204
- operation.operationId = operationMeta.operationId;
205
- }
206
- if (controllerDeprecated || operationMeta?.deprecated || this.isEndpointDeprecated(controller, handlerName)) {
207
- operation.deprecated = true;
208
- }
209
- const parameters = this.buildParameters(controller, handlerName, route.path);
210
- if (parameters.length > 0) {
211
- operation.parameters = parameters;
212
- }
213
- if (['POST', 'PUT', 'PATCH'].includes(route.method)) {
214
- const requestBody = this.buildRequestBody(controller, handlerName);
215
- if (requestBody) {
216
- operation.requestBody = requestBody;
217
- }
218
- }
219
- operation.responses = this.buildResponses(controller, handlerName, route.statusCode);
220
- const security = this.getSecurityMetadata(controller, handlerName);
221
- if (security.length > 0) {
222
- operation.security = security.map(s => ({ [s.name]: s.scopes || [] }));
223
- }
224
- return operation;
225
- }
226
- buildParameters(controller, handlerName, routePath) {
227
- const parameters = [];
228
- const pathParams = this.extractPathParams(routePath);
229
- const paramDecorators = this.getSwaggerParamMetadata(controller, handlerName);
230
- const queryDecorators = this.getQueryMetadata(controller, handlerName);
231
- const headerDecorators = this.getHeaderMetadata(controller, handlerName);
232
- const coreParams = this.getCoreParams(controller, handlerName);
233
- const usedPathParams = new Set();
234
- for (const param of paramDecorators) {
235
- usedPathParams.add(param.name);
236
- const baseSchema = toOpenApiSchema(param.schema);
237
- const fallbackSchema = {
238
- type: param.type || 'string'
239
- };
240
- if (param.format) {
241
- fallbackSchema.format = param.format;
242
- }
243
- parameters.push({
244
- name: param.name,
245
- in: 'path',
246
- required: true,
247
- deprecated: param.deprecated,
248
- description: param.description,
249
- schema: baseSchema || fallbackSchema,
250
- example: param.example,
251
- });
252
- }
253
- for (const paramName of pathParams) {
254
- if (!usedPathParams.has(paramName)) {
255
- const coreParam = coreParams.find(p => p.type === ParamType.PARAM && p.key === paramName);
256
- const schema = coreParam?.zodSchema ? zodToOpenApi(coreParam.zodSchema) : { type: 'string' };
257
- parameters.push({
258
- name: paramName,
259
- in: 'path',
260
- required: true,
261
- schema,
262
- });
263
- }
264
- }
265
- for (const query of queryDecorators) {
266
- const baseSchema = toOpenApiSchema(query.schema);
267
- const fallbackSchema = {
268
- type: query.type || 'string'
269
- };
270
- if (query.format) {
271
- fallbackSchema.format = query.format;
272
- }
273
- parameters.push({
274
- name: query.name,
275
- in: 'query',
276
- required: query.required,
277
- deprecated: query.deprecated,
278
- description: query.description,
279
- schema: baseSchema || fallbackSchema,
280
- example: query.example,
281
- });
282
- }
283
- for (const header of headerDecorators) {
284
- parameters.push({
285
- name: header.name,
286
- in: 'header',
287
- required: header.required,
288
- deprecated: header.deprecated,
289
- description: header.description,
290
- schema: toOpenApiSchema(header.schema) || {
291
- type: header.type || 'string'
292
- },
293
- example: header.example,
294
- });
295
- }
296
- return parameters;
297
- }
298
- extractPathParams(path) {
299
- const params = [];
300
- const regex = /:([^/]+)|{([^}]+)}/g;
301
- let match;
302
- while ((match = regex.exec(path)) !== null) {
303
- const paramName = match[1] ?? match[2];
304
- if (paramName) {
305
- params.push(paramName);
306
- }
307
- }
308
- return params;
309
- }
310
- buildRequestBody(controller, handlerName) {
311
- const bodyMeta = this.getBodyMetadata(controller, handlerName);
312
- const coreParams = this.getCoreParams(controller, handlerName);
313
- if (bodyMeta) {
314
- const schema = toOpenApiSchema(bodyMeta.schema);
315
- return {
316
- description: bodyMeta.description,
317
- required: bodyMeta.required ?? true,
318
- content: {
319
- [bodyMeta.type || 'application/json']: {
320
- schema: bodyMeta.isArray && schema ? { type: 'array', items: schema } : schema,
321
- example: bodyMeta.example,
322
- },
323
- },
324
- };
325
- }
326
- const bodyParam = coreParams.find(p => p.type === ParamType.BODY);
327
- if (bodyParam?.zodSchema) {
328
- return {
329
- required: true,
330
- content: {
331
- 'application/json': {
332
- schema: zodToOpenApi(bodyParam.zodSchema),
333
- },
334
- },
335
- };
336
- }
337
- return undefined;
338
- }
339
- buildResponses(controller, handlerName, defaultStatusCode) {
340
- const responses = {};
341
- const responseMeta = this.getResponseMetadata(controller, handlerName);
342
- const httpCode = this.getHttpStatusCode(controller, handlerName);
343
- if (responseMeta.length > 0) {
344
- for (const response of responseMeta) {
345
- const statusCode = response.status.toString();
346
- const schema = toOpenApiSchema(response.schema);
347
- responses[statusCode] = {
348
- description: response.description || this.getDefaultStatusDescription(response.status),
349
- };
350
- if (schema || response.example) {
351
- responses[statusCode].content = {
352
- [response.type || 'application/json']: {
353
- schema: response.isArray && schema ? { type: 'array', items: schema } : schema,
354
- example: response.example,
355
- },
356
- };
357
- }
358
- }
359
- }
360
- else {
361
- const status = (httpCode || defaultStatusCode || 200).toString();
362
- responses[status] = {
363
- description: this.getDefaultStatusDescription(Number(status)),
364
- };
365
- }
366
- return responses;
367
- }
368
- getDefaultStatusDescription(status) {
369
- const descriptions = {
370
- 200: 'Successful response',
371
- 201: 'Resource created successfully',
372
- 204: 'No content',
373
- 400: 'Bad request',
374
- 401: 'Unauthorized',
375
- 403: 'Forbidden',
376
- 404: 'Not found',
377
- 409: 'Conflict',
378
- 422: 'Unprocessable entity',
379
- 500: 'Internal server error',
380
- };
381
- return descriptions[status] || 'Response';
382
- }
383
- buildSecuritySchemes() {
384
- const schemes = {};
385
- for (const [name, options] of this.globalSecuritySchemes) {
386
- schemes[name] = {
387
- type: options.type,
388
- description: options.description,
389
- };
390
- if (options.type === 'apiKey') {
391
- schemes[name].name = options.name;
392
- schemes[name].in = options.in;
393
- }
394
- else if (options.type === 'http') {
395
- schemes[name].scheme = options.scheme;
396
- if (options.bearerFormat) {
397
- schemes[name].bearerFormat = options.bearerFormat;
398
- }
399
- }
400
- else if (options.type === 'oauth2' && options.flows) {
401
- schemes[name].flows = options.flows;
402
- }
403
- }
404
- return schemes;
405
- }
406
- }
407
- export function createOpenApiGenerator(config) {
408
- return new OpenApiGenerator(config);
409
- }
@@ -1,2 +0,0 @@
1
- export { zodToOpenApi, isZodSchema, toOpenApiSchema } from './zod-to-openapi.js';
2
- export { OpenApiGenerator, createOpenApiGenerator } from './generator.js';
@@ -1,2 +0,0 @@
1
- export { zodToOpenApi, isZodSchema, toOpenApiSchema } from './zod-to-openapi.js';
2
- export { OpenApiGenerator, createOpenApiGenerator } from './generator.js';
@@ -1,5 +0,0 @@
1
- import { type ZodType } from 'zod';
2
- import type { OpenApiSchemaObject } from '../types.js';
3
- export declare function isZodSchema(value: unknown): value is ZodType<unknown>;
4
- export declare function zodToOpenApi(schema: ZodType): OpenApiSchemaObject;
5
- export declare function toOpenApiSchema(schemaOrOpenApi: ZodType | OpenApiSchemaObject | undefined): OpenApiSchemaObject | undefined;
@@ -1,115 +0,0 @@
1
- import { z } from 'zod';
2
- export function isZodSchema(value) {
3
- return (value !== null &&
4
- typeof value === 'object' &&
5
- ('_zod' in value || '_def' in value) &&
6
- 'safeParse' in value &&
7
- typeof value.safeParse === 'function');
8
- }
9
- function jsonSchemaToOpenApi(jsonSchema) {
10
- if (typeof jsonSchema === 'boolean') {
11
- return jsonSchema ? {} : { not: {} };
12
- }
13
- const result = {};
14
- const schema = jsonSchema;
15
- if (Array.isArray(schema.type)) {
16
- const types = schema.type;
17
- const nullIndex = types.indexOf('null');
18
- if (nullIndex !== -1) {
19
- result.nullable = true;
20
- const nonNullTypes = types.filter(t => t !== 'null');
21
- if (nonNullTypes.length === 1) {
22
- result.type = nonNullTypes[0];
23
- }
24
- else if (nonNullTypes.length > 1) {
25
- result.oneOf = nonNullTypes.map(t => ({ type: t }));
26
- }
27
- }
28
- else if (types.length === 1) {
29
- result.type = types[0];
30
- }
31
- }
32
- else if (schema.type) {
33
- result.type = schema.type;
34
- }
35
- const simpleProps = [
36
- 'format', 'description', 'default', 'example', 'enum',
37
- 'minimum', 'maximum', 'exclusiveMinimum', 'exclusiveMaximum',
38
- 'minLength', 'maxLength', 'pattern',
39
- 'minItems', 'maxItems', 'uniqueItems',
40
- 'minProperties', 'maxProperties',
41
- 'required', 'readOnly', 'writeOnly', 'deprecated',
42
- ];
43
- for (const prop of simpleProps) {
44
- if (schema[prop] !== undefined) {
45
- result[prop] = schema[prop];
46
- }
47
- }
48
- if (schema.items) {
49
- if (Array.isArray(schema.items)) {
50
- result.items = { oneOf: schema.items.map(jsonSchemaToOpenApi) };
51
- }
52
- else {
53
- result.items = jsonSchemaToOpenApi(schema.items);
54
- }
55
- }
56
- if (schema.properties) {
57
- result.properties = {};
58
- for (const [key, value] of Object.entries(schema.properties)) {
59
- result.properties[key] = jsonSchemaToOpenApi(value);
60
- }
61
- }
62
- if (schema.additionalProperties !== undefined) {
63
- if (typeof schema.additionalProperties === 'boolean') {
64
- result.additionalProperties = schema.additionalProperties;
65
- }
66
- else {
67
- result.additionalProperties = jsonSchemaToOpenApi(schema.additionalProperties);
68
- }
69
- }
70
- if (schema.allOf) {
71
- result.allOf = schema.allOf.map(jsonSchemaToOpenApi);
72
- }
73
- if (schema.oneOf) {
74
- result.oneOf = schema.oneOf.map(jsonSchemaToOpenApi);
75
- }
76
- if (schema.anyOf) {
77
- result.anyOf = schema.anyOf.map(jsonSchemaToOpenApi);
78
- }
79
- if (schema.not) {
80
- result.not = jsonSchemaToOpenApi(schema.not);
81
- }
82
- if (schema.const !== undefined) {
83
- result.enum = [schema.const];
84
- }
85
- return result;
86
- }
87
- export function zodToOpenApi(schema) {
88
- const jsonSchema = z.toJSONSchema(schema, {
89
- target: 'openapi-3.0',
90
- unrepresentable: 'any',
91
- override: (ctx) => {
92
- const def = ctx.zodSchema._zod?.def;
93
- if (!def)
94
- return;
95
- if (def.type === 'date') {
96
- ctx.jsonSchema.type = 'string';
97
- ctx.jsonSchema.format = 'date-time';
98
- }
99
- if (def.type === 'bigint') {
100
- ctx.jsonSchema.type = 'integer';
101
- ctx.jsonSchema.format = 'int64';
102
- }
103
- },
104
- });
105
- return jsonSchemaToOpenApi(jsonSchema);
106
- }
107
- export function toOpenApiSchema(schemaOrOpenApi) {
108
- if (!schemaOrOpenApi) {
109
- return undefined;
110
- }
111
- if (isZodSchema(schemaOrOpenApi)) {
112
- return zodToOpenApi(schemaOrOpenApi);
113
- }
114
- return schemaOrOpenApi;
115
- }
@@ -1 +0,0 @@
1
- export { swaggerPlugin, registerSwagger, createSwaggerConfig, type SwaggerPluginOptions, } from './swagger.plugin.js';
@@ -1 +0,0 @@
1
- export { swaggerPlugin, registerSwagger, createSwaggerConfig, } from './swagger.plugin.js';
@@ -1,38 +0,0 @@
1
- import type { FastifyInstance, FastifyPluginAsync } from 'fastify';
2
- import { type FastifySwaggerUiOptions } from '@fastify/swagger-ui';
3
- import type { SwaggerConfig, OpenApiDocument, OpenApiInfoObject } from '../types.js';
4
- type Constructor<T = unknown> = new (...args: any[]) => T;
5
- export interface SwaggerPluginOptions {
6
- config?: SwaggerConfig;
7
- info?: OpenApiInfoObject;
8
- controllers?: Constructor[];
9
- jsonPath?: string;
10
- uiPath?: string;
11
- exposeUI?: boolean;
12
- exposeSpec?: boolean;
13
- logo?: {
14
- url: string;
15
- altText?: string;
16
- backgroundColor?: string;
17
- };
18
- theme?: 'default' | 'dark';
19
- transform?: (spec: OpenApiDocument) => OpenApiDocument | Promise<OpenApiDocument>;
20
- }
21
- declare module 'fastify' {
22
- interface FastifyInstance {
23
- openApiSpec?: OpenApiDocument;
24
- }
25
- }
26
- export declare const swaggerPlugin: FastifyPluginAsync<SwaggerPluginOptions>;
27
- export declare function registerSwagger(app: FastifyInstance, options?: SwaggerPluginOptions): Promise<void>;
28
- export declare function createSwaggerConfig(options?: SwaggerPluginOptions): {
29
- swaggerOptions: {
30
- mode: 'static';
31
- specification: {
32
- document: OpenApiDocument;
33
- };
34
- };
35
- swaggerUIOptions: FastifySwaggerUiOptions;
36
- specification: OpenApiDocument;
37
- };
38
- export {};