@riktajs/swagger 0.3.0 → 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.
- package/dist/index.cjs +1253 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +498 -0
- package/dist/index.d.ts +498 -7
- package/dist/index.js +1163 -6
- package/dist/index.js.map +1 -0
- package/package.json +75 -68
- package/dist/constants.d.ts +0 -11
- package/dist/constants.js +0 -11
- package/dist/decorators/api-body.decorator.d.ts +0 -4
- package/dist/decorators/api-body.decorator.js +0 -11
- package/dist/decorators/api-exclude.decorator.d.ts +0 -9
- package/dist/decorators/api-exclude.decorator.js +0 -31
- package/dist/decorators/api-header.decorator.d.ts +0 -4
- package/dist/decorators/api-header.decorator.js +0 -12
- package/dist/decorators/api-operation.decorator.d.ts +0 -4
- package/dist/decorators/api-operation.decorator.js +0 -11
- package/dist/decorators/api-param.decorator.d.ts +0 -4
- package/dist/decorators/api-param.decorator.js +0 -12
- package/dist/decorators/api-property.decorator.d.ts +0 -11
- package/dist/decorators/api-property.decorator.js +0 -20
- package/dist/decorators/api-query.decorator.d.ts +0 -4
- package/dist/decorators/api-query.decorator.js +0 -12
- package/dist/decorators/api-response.decorator.d.ts +0 -15
- package/dist/decorators/api-response.decorator.js +0 -45
- package/dist/decorators/api-security.decorator.d.ts +0 -8
- package/dist/decorators/api-security.decorator.js +0 -35
- package/dist/decorators/api-tags.decorator.d.ts +0 -3
- package/dist/decorators/api-tags.decorator.js +0 -22
- package/dist/decorators/index.d.ts +0 -10
- package/dist/decorators/index.js +0 -10
- package/dist/openapi/generator.d.ts +0 -49
- package/dist/openapi/generator.js +0 -409
- package/dist/openapi/index.d.ts +0 -2
- package/dist/openapi/index.js +0 -2
- package/dist/openapi/zod-to-openapi.d.ts +0 -5
- package/dist/openapi/zod-to-openapi.js +0 -115
- package/dist/plugin/index.d.ts +0 -1
- package/dist/plugin/index.js +0 -1
- package/dist/plugin/swagger.plugin.d.ts +0 -38
- package/dist/plugin/swagger.plugin.js +0 -126
- package/dist/types.d.ts +0 -338
- package/dist/types.js +0 -1
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1253 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
9
|
+
var __export = (target, all) => {
|
|
10
|
+
for (var name in all)
|
|
11
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
12
|
+
};
|
|
13
|
+
var __copyProps = (to, from, except, desc) => {
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (let key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
17
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
18
|
+
}
|
|
19
|
+
return to;
|
|
20
|
+
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
29
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
30
|
+
|
|
31
|
+
// src/index.ts
|
|
32
|
+
var index_exports = {};
|
|
33
|
+
__export(index_exports, {
|
|
34
|
+
API_BODY_METADATA: () => API_BODY_METADATA,
|
|
35
|
+
API_DEPRECATED_METADATA: () => API_DEPRECATED_METADATA,
|
|
36
|
+
API_EXCLUDE_METADATA: () => API_EXCLUDE_METADATA,
|
|
37
|
+
API_HEADER_METADATA: () => API_HEADER_METADATA,
|
|
38
|
+
API_OPERATION_METADATA: () => API_OPERATION_METADATA,
|
|
39
|
+
API_PARAM_METADATA: () => API_PARAM_METADATA,
|
|
40
|
+
API_PROPERTY_METADATA: () => API_PROPERTY_METADATA,
|
|
41
|
+
API_QUERY_METADATA: () => API_QUERY_METADATA,
|
|
42
|
+
API_RESPONSE_METADATA: () => API_RESPONSE_METADATA,
|
|
43
|
+
API_SECURITY_METADATA: () => API_SECURITY_METADATA,
|
|
44
|
+
API_TAGS_METADATA: () => API_TAGS_METADATA,
|
|
45
|
+
ApiAcceptedResponse: () => ApiAcceptedResponse,
|
|
46
|
+
ApiBadRequestResponse: () => ApiBadRequestResponse,
|
|
47
|
+
ApiBasicAuth: () => ApiBasicAuth,
|
|
48
|
+
ApiBearerAuth: () => ApiBearerAuth,
|
|
49
|
+
ApiBody: () => ApiBody,
|
|
50
|
+
ApiConflictResponse: () => ApiConflictResponse,
|
|
51
|
+
ApiCookieAuth: () => ApiCookieAuth,
|
|
52
|
+
ApiCreatedResponse: () => ApiCreatedResponse,
|
|
53
|
+
ApiDeprecated: () => ApiDeprecated,
|
|
54
|
+
ApiExcludeController: () => ApiExcludeController,
|
|
55
|
+
ApiExcludeEndpoint: () => ApiExcludeEndpoint,
|
|
56
|
+
ApiForbiddenResponse: () => ApiForbiddenResponse,
|
|
57
|
+
ApiHeader: () => ApiHeader,
|
|
58
|
+
ApiHideProperty: () => ApiHideProperty,
|
|
59
|
+
ApiInternalServerErrorResponse: () => ApiInternalServerErrorResponse,
|
|
60
|
+
ApiNoContentResponse: () => ApiNoContentResponse,
|
|
61
|
+
ApiNotFoundResponse: () => ApiNotFoundResponse,
|
|
62
|
+
ApiOAuth2: () => ApiOAuth2,
|
|
63
|
+
ApiOkResponse: () => ApiOkResponse,
|
|
64
|
+
ApiOperation: () => ApiOperation,
|
|
65
|
+
ApiParam: () => ApiParam,
|
|
66
|
+
ApiProperty: () => ApiProperty,
|
|
67
|
+
ApiPropertyOptional: () => ApiPropertyOptional,
|
|
68
|
+
ApiQuery: () => ApiQuery,
|
|
69
|
+
ApiResponse: () => ApiResponse,
|
|
70
|
+
ApiSecurity: () => ApiSecurity,
|
|
71
|
+
ApiTags: () => ApiTags,
|
|
72
|
+
ApiUnauthorizedResponse: () => ApiUnauthorizedResponse,
|
|
73
|
+
ApiUnprocessableEntityResponse: () => ApiUnprocessableEntityResponse,
|
|
74
|
+
CONTROLLER_METADATA: () => import_core3.CONTROLLER_METADATA,
|
|
75
|
+
GUARDS_METADATA: () => import_core3.GUARDS_METADATA,
|
|
76
|
+
HTTP_CODE_METADATA: () => import_core3.HTTP_CODE_METADATA,
|
|
77
|
+
OpenApiGenerator: () => OpenApiGenerator,
|
|
78
|
+
PARAM_METADATA: () => import_core3.PARAM_METADATA,
|
|
79
|
+
ROUTES_METADATA: () => import_core3.ROUTES_METADATA,
|
|
80
|
+
ZOD_SCHEMA_METADATA: () => import_core3.ZOD_SCHEMA_METADATA,
|
|
81
|
+
createSwaggerConfig: () => createSwaggerConfig,
|
|
82
|
+
getApiBody: () => getApiBody,
|
|
83
|
+
getApiDeprecated: () => getApiDeprecated,
|
|
84
|
+
getApiHeaders: () => getApiHeaders,
|
|
85
|
+
getApiOperation: () => getApiOperation,
|
|
86
|
+
getApiParams: () => getApiParams,
|
|
87
|
+
getApiProperties: () => getApiProperties,
|
|
88
|
+
getApiQueries: () => getApiQueries,
|
|
89
|
+
getApiResponses: () => getApiResponses,
|
|
90
|
+
getApiSecurity: () => getApiSecurity,
|
|
91
|
+
getApiTags: () => getApiTags,
|
|
92
|
+
isApiExcluded: () => isApiExcluded,
|
|
93
|
+
isZodSchema: () => isZodSchema,
|
|
94
|
+
registerSwagger: () => registerSwagger,
|
|
95
|
+
swaggerPlugin: () => swaggerPlugin,
|
|
96
|
+
toOpenApiSchema: () => toOpenApiSchema,
|
|
97
|
+
zodToOpenApi: () => zodToOpenApi
|
|
98
|
+
});
|
|
99
|
+
module.exports = __toCommonJS(index_exports);
|
|
100
|
+
|
|
101
|
+
// src/constants.ts
|
|
102
|
+
var API_TAGS_METADATA = /* @__PURE__ */ Symbol.for("rikta:swagger:apiTags");
|
|
103
|
+
var API_OPERATION_METADATA = /* @__PURE__ */ Symbol.for("rikta:swagger:apiOperation");
|
|
104
|
+
var API_RESPONSE_METADATA = /* @__PURE__ */ Symbol.for("rikta:swagger:apiResponse");
|
|
105
|
+
var API_PROPERTY_METADATA = /* @__PURE__ */ Symbol.for("rikta:swagger:apiProperty");
|
|
106
|
+
var API_BODY_METADATA = /* @__PURE__ */ Symbol.for("rikta:swagger:apiBody");
|
|
107
|
+
var API_PARAM_METADATA = /* @__PURE__ */ Symbol.for("rikta:swagger:apiParam");
|
|
108
|
+
var API_QUERY_METADATA = /* @__PURE__ */ Symbol.for("rikta:swagger:apiQuery");
|
|
109
|
+
var API_HEADER_METADATA = /* @__PURE__ */ Symbol.for("rikta:swagger:apiHeader");
|
|
110
|
+
var API_SECURITY_METADATA = /* @__PURE__ */ Symbol.for("rikta:swagger:apiSecurity");
|
|
111
|
+
var API_EXCLUDE_METADATA = /* @__PURE__ */ Symbol.for("rikta:swagger:apiExclude");
|
|
112
|
+
var API_DEPRECATED_METADATA = /* @__PURE__ */ Symbol.for("rikta:swagger:apiDeprecated");
|
|
113
|
+
|
|
114
|
+
// src/index.ts
|
|
115
|
+
var import_core3 = require("@riktajs/core");
|
|
116
|
+
|
|
117
|
+
// src/decorators/api-tags.decorator.ts
|
|
118
|
+
var import_reflect_metadata = require("reflect-metadata");
|
|
119
|
+
function ApiTags(...tags) {
|
|
120
|
+
return (target, propertyKey, descriptor) => {
|
|
121
|
+
if (propertyKey !== void 0 && descriptor !== void 0) {
|
|
122
|
+
const existingTags = Reflect.getMetadata(API_TAGS_METADATA, target, propertyKey) ?? [];
|
|
123
|
+
Reflect.defineMetadata(API_TAGS_METADATA, [
|
|
124
|
+
...existingTags,
|
|
125
|
+
...tags
|
|
126
|
+
], target, propertyKey);
|
|
127
|
+
} else {
|
|
128
|
+
const existingTags = Reflect.getMetadata(API_TAGS_METADATA, target) ?? [];
|
|
129
|
+
Reflect.defineMetadata(API_TAGS_METADATA, [
|
|
130
|
+
...existingTags,
|
|
131
|
+
...tags
|
|
132
|
+
], target);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
__name(ApiTags, "ApiTags");
|
|
137
|
+
function getApiTags(target, propertyKey) {
|
|
138
|
+
if (propertyKey !== void 0) {
|
|
139
|
+
const methodTags = Reflect.getMetadata(API_TAGS_METADATA, target.prototype, propertyKey) ?? [];
|
|
140
|
+
const classTags = Reflect.getMetadata(API_TAGS_METADATA, target) ?? [];
|
|
141
|
+
return [
|
|
142
|
+
.../* @__PURE__ */ new Set([
|
|
143
|
+
...classTags,
|
|
144
|
+
...methodTags
|
|
145
|
+
])
|
|
146
|
+
];
|
|
147
|
+
}
|
|
148
|
+
return Reflect.getMetadata(API_TAGS_METADATA, target) ?? [];
|
|
149
|
+
}
|
|
150
|
+
__name(getApiTags, "getApiTags");
|
|
151
|
+
|
|
152
|
+
// src/decorators/api-operation.decorator.ts
|
|
153
|
+
var import_reflect_metadata2 = require("reflect-metadata");
|
|
154
|
+
function ApiOperation(options) {
|
|
155
|
+
return (target, propertyKey, descriptor) => {
|
|
156
|
+
Reflect.defineMetadata(API_OPERATION_METADATA, options, target, propertyKey);
|
|
157
|
+
return descriptor;
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
__name(ApiOperation, "ApiOperation");
|
|
161
|
+
function getApiOperation(target, propertyKey) {
|
|
162
|
+
return Reflect.getMetadata(API_OPERATION_METADATA, target.prototype, propertyKey);
|
|
163
|
+
}
|
|
164
|
+
__name(getApiOperation, "getApiOperation");
|
|
165
|
+
|
|
166
|
+
// src/decorators/api-response.decorator.ts
|
|
167
|
+
var import_reflect_metadata3 = require("reflect-metadata");
|
|
168
|
+
function ApiResponse(options) {
|
|
169
|
+
return (target, propertyKey, descriptor) => {
|
|
170
|
+
const existingResponses = Reflect.getMetadata(API_RESPONSE_METADATA, target, propertyKey) ?? [];
|
|
171
|
+
Reflect.defineMetadata(API_RESPONSE_METADATA, [
|
|
172
|
+
...existingResponses,
|
|
173
|
+
options
|
|
174
|
+
], target, propertyKey);
|
|
175
|
+
return descriptor;
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
__name(ApiResponse, "ApiResponse");
|
|
179
|
+
function ApiOkResponse(options = {}) {
|
|
180
|
+
return ApiResponse({
|
|
181
|
+
...options,
|
|
182
|
+
status: 200
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
__name(ApiOkResponse, "ApiOkResponse");
|
|
186
|
+
function ApiCreatedResponse(options = {}) {
|
|
187
|
+
return ApiResponse({
|
|
188
|
+
...options,
|
|
189
|
+
status: 201
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
__name(ApiCreatedResponse, "ApiCreatedResponse");
|
|
193
|
+
function ApiAcceptedResponse(options = {}) {
|
|
194
|
+
return ApiResponse({
|
|
195
|
+
...options,
|
|
196
|
+
status: 202
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
__name(ApiAcceptedResponse, "ApiAcceptedResponse");
|
|
200
|
+
function ApiNoContentResponse(options = {}) {
|
|
201
|
+
return ApiResponse({
|
|
202
|
+
...options,
|
|
203
|
+
status: 204
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
__name(ApiNoContentResponse, "ApiNoContentResponse");
|
|
207
|
+
function ApiBadRequestResponse(options = {}) {
|
|
208
|
+
return ApiResponse({
|
|
209
|
+
...options,
|
|
210
|
+
status: 400,
|
|
211
|
+
description: options.description ?? "Bad Request"
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
__name(ApiBadRequestResponse, "ApiBadRequestResponse");
|
|
215
|
+
function ApiUnauthorizedResponse(options = {}) {
|
|
216
|
+
return ApiResponse({
|
|
217
|
+
...options,
|
|
218
|
+
status: 401,
|
|
219
|
+
description: options.description ?? "Unauthorized"
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
__name(ApiUnauthorizedResponse, "ApiUnauthorizedResponse");
|
|
223
|
+
function ApiForbiddenResponse(options = {}) {
|
|
224
|
+
return ApiResponse({
|
|
225
|
+
...options,
|
|
226
|
+
status: 403,
|
|
227
|
+
description: options.description ?? "Forbidden"
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
__name(ApiForbiddenResponse, "ApiForbiddenResponse");
|
|
231
|
+
function ApiNotFoundResponse(options = {}) {
|
|
232
|
+
return ApiResponse({
|
|
233
|
+
...options,
|
|
234
|
+
status: 404,
|
|
235
|
+
description: options.description ?? "Not Found"
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
__name(ApiNotFoundResponse, "ApiNotFoundResponse");
|
|
239
|
+
function ApiConflictResponse(options = {}) {
|
|
240
|
+
return ApiResponse({
|
|
241
|
+
...options,
|
|
242
|
+
status: 409,
|
|
243
|
+
description: options.description ?? "Conflict"
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
__name(ApiConflictResponse, "ApiConflictResponse");
|
|
247
|
+
function ApiUnprocessableEntityResponse(options = {}) {
|
|
248
|
+
return ApiResponse({
|
|
249
|
+
...options,
|
|
250
|
+
status: 422,
|
|
251
|
+
description: options.description ?? "Unprocessable Entity"
|
|
252
|
+
});
|
|
253
|
+
}
|
|
254
|
+
__name(ApiUnprocessableEntityResponse, "ApiUnprocessableEntityResponse");
|
|
255
|
+
function ApiInternalServerErrorResponse(options = {}) {
|
|
256
|
+
return ApiResponse({
|
|
257
|
+
...options,
|
|
258
|
+
status: 500,
|
|
259
|
+
description: options.description ?? "Internal Server Error"
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
__name(ApiInternalServerErrorResponse, "ApiInternalServerErrorResponse");
|
|
263
|
+
function getApiResponses(target, propertyKey) {
|
|
264
|
+
return Reflect.getMetadata(API_RESPONSE_METADATA, target.prototype, propertyKey) ?? [];
|
|
265
|
+
}
|
|
266
|
+
__name(getApiResponses, "getApiResponses");
|
|
267
|
+
|
|
268
|
+
// src/decorators/api-body.decorator.ts
|
|
269
|
+
var import_reflect_metadata4 = require("reflect-metadata");
|
|
270
|
+
function ApiBody(options) {
|
|
271
|
+
return (target, propertyKey, descriptor) => {
|
|
272
|
+
Reflect.defineMetadata(API_BODY_METADATA, {
|
|
273
|
+
...options,
|
|
274
|
+
required: options.required ?? true
|
|
275
|
+
}, target, propertyKey);
|
|
276
|
+
return descriptor;
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
__name(ApiBody, "ApiBody");
|
|
280
|
+
function getApiBody(target, propertyKey) {
|
|
281
|
+
return Reflect.getMetadata(API_BODY_METADATA, target.prototype, propertyKey);
|
|
282
|
+
}
|
|
283
|
+
__name(getApiBody, "getApiBody");
|
|
284
|
+
|
|
285
|
+
// src/decorators/api-param.decorator.ts
|
|
286
|
+
var import_reflect_metadata5 = require("reflect-metadata");
|
|
287
|
+
function ApiParam(options) {
|
|
288
|
+
return (target, propertyKey, descriptor) => {
|
|
289
|
+
const existingParams = Reflect.getMetadata(API_PARAM_METADATA, target, propertyKey) ?? [];
|
|
290
|
+
Reflect.defineMetadata(API_PARAM_METADATA, [
|
|
291
|
+
...existingParams,
|
|
292
|
+
{
|
|
293
|
+
...options,
|
|
294
|
+
required: options.required ?? true
|
|
295
|
+
}
|
|
296
|
+
], target, propertyKey);
|
|
297
|
+
return descriptor;
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
__name(ApiParam, "ApiParam");
|
|
301
|
+
function getApiParams(target, propertyKey) {
|
|
302
|
+
return Reflect.getMetadata(API_PARAM_METADATA, target.prototype, propertyKey) ?? [];
|
|
303
|
+
}
|
|
304
|
+
__name(getApiParams, "getApiParams");
|
|
305
|
+
|
|
306
|
+
// src/decorators/api-query.decorator.ts
|
|
307
|
+
var import_reflect_metadata6 = require("reflect-metadata");
|
|
308
|
+
function ApiQuery(options) {
|
|
309
|
+
return (target, propertyKey, descriptor) => {
|
|
310
|
+
const existingQueries = Reflect.getMetadata(API_QUERY_METADATA, target, propertyKey) ?? [];
|
|
311
|
+
Reflect.defineMetadata(API_QUERY_METADATA, [
|
|
312
|
+
...existingQueries,
|
|
313
|
+
{
|
|
314
|
+
...options,
|
|
315
|
+
required: options.required ?? false
|
|
316
|
+
}
|
|
317
|
+
], target, propertyKey);
|
|
318
|
+
return descriptor;
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
__name(ApiQuery, "ApiQuery");
|
|
322
|
+
function getApiQueries(target, propertyKey) {
|
|
323
|
+
return Reflect.getMetadata(API_QUERY_METADATA, target.prototype, propertyKey) ?? [];
|
|
324
|
+
}
|
|
325
|
+
__name(getApiQueries, "getApiQueries");
|
|
326
|
+
|
|
327
|
+
// src/decorators/api-header.decorator.ts
|
|
328
|
+
var import_reflect_metadata7 = require("reflect-metadata");
|
|
329
|
+
function ApiHeader(options) {
|
|
330
|
+
return (target, propertyKey, descriptor) => {
|
|
331
|
+
const existingHeaders = Reflect.getMetadata(API_HEADER_METADATA, target, propertyKey) ?? [];
|
|
332
|
+
Reflect.defineMetadata(API_HEADER_METADATA, [
|
|
333
|
+
...existingHeaders,
|
|
334
|
+
options
|
|
335
|
+
], target, propertyKey);
|
|
336
|
+
return descriptor;
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
__name(ApiHeader, "ApiHeader");
|
|
340
|
+
function getApiHeaders(target, propertyKey) {
|
|
341
|
+
return Reflect.getMetadata(API_HEADER_METADATA, target.prototype, propertyKey) ?? [];
|
|
342
|
+
}
|
|
343
|
+
__name(getApiHeaders, "getApiHeaders");
|
|
344
|
+
|
|
345
|
+
// src/decorators/api-security.decorator.ts
|
|
346
|
+
var import_reflect_metadata8 = require("reflect-metadata");
|
|
347
|
+
function ApiSecurity(name, scopes = []) {
|
|
348
|
+
return (target, propertyKey, descriptor) => {
|
|
349
|
+
const security = name ? {
|
|
350
|
+
name,
|
|
351
|
+
scopes
|
|
352
|
+
} : null;
|
|
353
|
+
if (propertyKey !== void 0 && descriptor !== void 0) {
|
|
354
|
+
Reflect.defineMetadata(API_SECURITY_METADATA, security, target, propertyKey);
|
|
355
|
+
} else {
|
|
356
|
+
Reflect.defineMetadata(API_SECURITY_METADATA, security, target);
|
|
357
|
+
}
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
__name(ApiSecurity, "ApiSecurity");
|
|
361
|
+
function ApiBearerAuth(name = "bearerAuth") {
|
|
362
|
+
return ApiSecurity(name);
|
|
363
|
+
}
|
|
364
|
+
__name(ApiBearerAuth, "ApiBearerAuth");
|
|
365
|
+
function ApiBasicAuth(name = "basicAuth") {
|
|
366
|
+
return ApiSecurity(name);
|
|
367
|
+
}
|
|
368
|
+
__name(ApiBasicAuth, "ApiBasicAuth");
|
|
369
|
+
function ApiOAuth2(scopes = [], name = "oauth2") {
|
|
370
|
+
return ApiSecurity(name, scopes);
|
|
371
|
+
}
|
|
372
|
+
__name(ApiOAuth2, "ApiOAuth2");
|
|
373
|
+
function ApiCookieAuth(name = "cookieAuth") {
|
|
374
|
+
return ApiSecurity(name);
|
|
375
|
+
}
|
|
376
|
+
__name(ApiCookieAuth, "ApiCookieAuth");
|
|
377
|
+
function getApiSecurity(target, propertyKey) {
|
|
378
|
+
if (propertyKey !== void 0) {
|
|
379
|
+
const methodSecurity = Reflect.getMetadata(API_SECURITY_METADATA, target.prototype, propertyKey);
|
|
380
|
+
if (methodSecurity !== void 0) {
|
|
381
|
+
return methodSecurity;
|
|
382
|
+
}
|
|
383
|
+
return Reflect.getMetadata(API_SECURITY_METADATA, target);
|
|
384
|
+
}
|
|
385
|
+
return Reflect.getMetadata(API_SECURITY_METADATA, target);
|
|
386
|
+
}
|
|
387
|
+
__name(getApiSecurity, "getApiSecurity");
|
|
388
|
+
|
|
389
|
+
// src/decorators/api-property.decorator.ts
|
|
390
|
+
var import_reflect_metadata9 = require("reflect-metadata");
|
|
391
|
+
function ApiProperty(options = {}) {
|
|
392
|
+
return (target, propertyKey) => {
|
|
393
|
+
const existingProperties = Reflect.getMetadata(API_PROPERTY_METADATA, target.constructor) ?? [];
|
|
394
|
+
Reflect.defineMetadata(API_PROPERTY_METADATA, [
|
|
395
|
+
...existingProperties,
|
|
396
|
+
{
|
|
397
|
+
propertyKey,
|
|
398
|
+
options
|
|
399
|
+
}
|
|
400
|
+
], target.constructor);
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
__name(ApiProperty, "ApiProperty");
|
|
404
|
+
function ApiPropertyOptional(options = {}) {
|
|
405
|
+
return ApiProperty({
|
|
406
|
+
...options,
|
|
407
|
+
required: false
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
__name(ApiPropertyOptional, "ApiPropertyOptional");
|
|
411
|
+
function ApiHideProperty() {
|
|
412
|
+
return (target, propertyKey) => {
|
|
413
|
+
const existingProperties = Reflect.getMetadata(API_PROPERTY_METADATA, target.constructor) ?? [];
|
|
414
|
+
Reflect.defineMetadata(API_PROPERTY_METADATA, [
|
|
415
|
+
...existingProperties,
|
|
416
|
+
{
|
|
417
|
+
propertyKey,
|
|
418
|
+
options: {
|
|
419
|
+
_hidden: true
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
], target.constructor);
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
__name(ApiHideProperty, "ApiHideProperty");
|
|
426
|
+
function getApiProperties(target) {
|
|
427
|
+
return Reflect.getMetadata(API_PROPERTY_METADATA, target) ?? [];
|
|
428
|
+
}
|
|
429
|
+
__name(getApiProperties, "getApiProperties");
|
|
430
|
+
|
|
431
|
+
// src/decorators/api-exclude.decorator.ts
|
|
432
|
+
var import_reflect_metadata10 = require("reflect-metadata");
|
|
433
|
+
function ApiExcludeEndpoint() {
|
|
434
|
+
return (target, propertyKey, descriptor) => {
|
|
435
|
+
Reflect.defineMetadata(API_EXCLUDE_METADATA, true, target, propertyKey);
|
|
436
|
+
return descriptor;
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
__name(ApiExcludeEndpoint, "ApiExcludeEndpoint");
|
|
440
|
+
function ApiExcludeController() {
|
|
441
|
+
return (target) => {
|
|
442
|
+
Reflect.defineMetadata(API_EXCLUDE_METADATA, true, target);
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
__name(ApiExcludeController, "ApiExcludeController");
|
|
446
|
+
function isApiExcluded(target, propertyKey) {
|
|
447
|
+
if (Reflect.getMetadata(API_EXCLUDE_METADATA, target) === true) {
|
|
448
|
+
return true;
|
|
449
|
+
}
|
|
450
|
+
if (propertyKey !== void 0) {
|
|
451
|
+
return Reflect.getMetadata(API_EXCLUDE_METADATA, target.prototype, propertyKey) === true;
|
|
452
|
+
}
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
455
|
+
__name(isApiExcluded, "isApiExcluded");
|
|
456
|
+
function ApiDeprecated(message) {
|
|
457
|
+
return (target, propertyKey, descriptor) => {
|
|
458
|
+
Reflect.defineMetadata(API_DEPRECATED_METADATA, {
|
|
459
|
+
deprecated: true,
|
|
460
|
+
message
|
|
461
|
+
}, target, propertyKey);
|
|
462
|
+
return descriptor;
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
__name(ApiDeprecated, "ApiDeprecated");
|
|
466
|
+
function getApiDeprecated(target, propertyKey) {
|
|
467
|
+
return Reflect.getMetadata(API_DEPRECATED_METADATA, target.prototype, propertyKey);
|
|
468
|
+
}
|
|
469
|
+
__name(getApiDeprecated, "getApiDeprecated");
|
|
470
|
+
|
|
471
|
+
// src/openapi/generator.ts
|
|
472
|
+
var import_reflect_metadata11 = require("reflect-metadata");
|
|
473
|
+
var import_core = require("@riktajs/core");
|
|
474
|
+
|
|
475
|
+
// src/openapi/zod-to-openapi.ts
|
|
476
|
+
var import_zod = require("zod");
|
|
477
|
+
function isZodSchema(value) {
|
|
478
|
+
return value !== null && typeof value === "object" && ("_zod" in value || "_def" in value) && "safeParse" in value && typeof value.safeParse === "function";
|
|
479
|
+
}
|
|
480
|
+
__name(isZodSchema, "isZodSchema");
|
|
481
|
+
function jsonSchemaToOpenApi(jsonSchema) {
|
|
482
|
+
if (typeof jsonSchema === "boolean") {
|
|
483
|
+
return jsonSchema ? {} : {
|
|
484
|
+
not: {}
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
const result = {};
|
|
488
|
+
const schema = jsonSchema;
|
|
489
|
+
if (Array.isArray(schema.type)) {
|
|
490
|
+
const types = schema.type;
|
|
491
|
+
const nullIndex = types.indexOf("null");
|
|
492
|
+
if (nullIndex !== -1) {
|
|
493
|
+
result.nullable = true;
|
|
494
|
+
const nonNullTypes = types.filter((t) => t !== "null");
|
|
495
|
+
if (nonNullTypes.length === 1) {
|
|
496
|
+
result.type = nonNullTypes[0];
|
|
497
|
+
} else if (nonNullTypes.length > 1) {
|
|
498
|
+
result.oneOf = nonNullTypes.map((t) => ({
|
|
499
|
+
type: t
|
|
500
|
+
}));
|
|
501
|
+
}
|
|
502
|
+
} else if (types.length === 1) {
|
|
503
|
+
result.type = types[0];
|
|
504
|
+
}
|
|
505
|
+
} else if (schema.type) {
|
|
506
|
+
result.type = schema.type;
|
|
507
|
+
}
|
|
508
|
+
const simpleProps = [
|
|
509
|
+
"format",
|
|
510
|
+
"description",
|
|
511
|
+
"default",
|
|
512
|
+
"example",
|
|
513
|
+
"enum",
|
|
514
|
+
"minimum",
|
|
515
|
+
"maximum",
|
|
516
|
+
"exclusiveMinimum",
|
|
517
|
+
"exclusiveMaximum",
|
|
518
|
+
"minLength",
|
|
519
|
+
"maxLength",
|
|
520
|
+
"pattern",
|
|
521
|
+
"minItems",
|
|
522
|
+
"maxItems",
|
|
523
|
+
"uniqueItems",
|
|
524
|
+
"minProperties",
|
|
525
|
+
"maxProperties",
|
|
526
|
+
"required",
|
|
527
|
+
"readOnly",
|
|
528
|
+
"writeOnly",
|
|
529
|
+
"deprecated"
|
|
530
|
+
];
|
|
531
|
+
for (const prop of simpleProps) {
|
|
532
|
+
if (schema[prop] !== void 0) {
|
|
533
|
+
result[prop] = schema[prop];
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
if (schema.items) {
|
|
537
|
+
if (Array.isArray(schema.items)) {
|
|
538
|
+
result.items = {
|
|
539
|
+
oneOf: schema.items.map(jsonSchemaToOpenApi)
|
|
540
|
+
};
|
|
541
|
+
} else {
|
|
542
|
+
result.items = jsonSchemaToOpenApi(schema.items);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
if (schema.properties) {
|
|
546
|
+
result.properties = {};
|
|
547
|
+
for (const [key, value] of Object.entries(schema.properties)) {
|
|
548
|
+
result.properties[key] = jsonSchemaToOpenApi(value);
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
if (schema.additionalProperties !== void 0) {
|
|
552
|
+
if (typeof schema.additionalProperties === "boolean") {
|
|
553
|
+
result.additionalProperties = schema.additionalProperties;
|
|
554
|
+
} else {
|
|
555
|
+
result.additionalProperties = jsonSchemaToOpenApi(schema.additionalProperties);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
if (schema.allOf) {
|
|
559
|
+
result.allOf = schema.allOf.map(jsonSchemaToOpenApi);
|
|
560
|
+
}
|
|
561
|
+
if (schema.oneOf) {
|
|
562
|
+
result.oneOf = schema.oneOf.map(jsonSchemaToOpenApi);
|
|
563
|
+
}
|
|
564
|
+
if (schema.anyOf) {
|
|
565
|
+
result.anyOf = schema.anyOf.map(jsonSchemaToOpenApi);
|
|
566
|
+
}
|
|
567
|
+
if (schema.not) {
|
|
568
|
+
result.not = jsonSchemaToOpenApi(schema.not);
|
|
569
|
+
}
|
|
570
|
+
if (schema.const !== void 0) {
|
|
571
|
+
result.enum = [
|
|
572
|
+
schema.const
|
|
573
|
+
];
|
|
574
|
+
}
|
|
575
|
+
return result;
|
|
576
|
+
}
|
|
577
|
+
__name(jsonSchemaToOpenApi, "jsonSchemaToOpenApi");
|
|
578
|
+
function zodToOpenApi(schema) {
|
|
579
|
+
const jsonSchema = import_zod.z.toJSONSchema(schema, {
|
|
580
|
+
// Target OpenAPI 3.0 Schema Object format
|
|
581
|
+
target: "openapi-3.0",
|
|
582
|
+
// Allow unrepresentable types to be converted to {} instead of throwing
|
|
583
|
+
unrepresentable: "any",
|
|
584
|
+
// Custom override for types that need special handling
|
|
585
|
+
override: /* @__PURE__ */ __name((ctx) => {
|
|
586
|
+
const def = ctx.zodSchema._zod?.def;
|
|
587
|
+
if (!def) return;
|
|
588
|
+
if (def.type === "date") {
|
|
589
|
+
ctx.jsonSchema.type = "string";
|
|
590
|
+
ctx.jsonSchema.format = "date-time";
|
|
591
|
+
}
|
|
592
|
+
if (def.type === "bigint") {
|
|
593
|
+
ctx.jsonSchema.type = "integer";
|
|
594
|
+
ctx.jsonSchema.format = "int64";
|
|
595
|
+
}
|
|
596
|
+
}, "override")
|
|
597
|
+
});
|
|
598
|
+
return jsonSchemaToOpenApi(jsonSchema);
|
|
599
|
+
}
|
|
600
|
+
__name(zodToOpenApi, "zodToOpenApi");
|
|
601
|
+
function toOpenApiSchema(schemaOrOpenApi) {
|
|
602
|
+
if (!schemaOrOpenApi) {
|
|
603
|
+
return void 0;
|
|
604
|
+
}
|
|
605
|
+
if (isZodSchema(schemaOrOpenApi)) {
|
|
606
|
+
return zodToOpenApi(schemaOrOpenApi);
|
|
607
|
+
}
|
|
608
|
+
return schemaOrOpenApi;
|
|
609
|
+
}
|
|
610
|
+
__name(toOpenApiSchema, "toOpenApiSchema");
|
|
611
|
+
|
|
612
|
+
// src/openapi/generator.ts
|
|
613
|
+
var DEFAULT_SWAGGER_CONFIG = {
|
|
614
|
+
info: {
|
|
615
|
+
title: "API Documentation",
|
|
616
|
+
version: "1.0.0"
|
|
617
|
+
}
|
|
618
|
+
};
|
|
619
|
+
var OpenApiGenerator = class {
|
|
620
|
+
static {
|
|
621
|
+
__name(this, "OpenApiGenerator");
|
|
622
|
+
}
|
|
623
|
+
config;
|
|
624
|
+
controllers = [];
|
|
625
|
+
globalSecuritySchemes = /* @__PURE__ */ new Map();
|
|
626
|
+
constructor(config = {}) {
|
|
627
|
+
const info = config.info ?? {
|
|
628
|
+
title: config.title ?? DEFAULT_SWAGGER_CONFIG.info?.title ?? "API Documentation",
|
|
629
|
+
version: config.version ?? DEFAULT_SWAGGER_CONFIG.info?.version ?? "1.0.0",
|
|
630
|
+
description: config.description,
|
|
631
|
+
contact: config.contact,
|
|
632
|
+
license: config.license,
|
|
633
|
+
termsOfService: config.termsOfService
|
|
634
|
+
};
|
|
635
|
+
const { title, version, description, contact, license, termsOfService, ...restConfig } = config;
|
|
636
|
+
this.config = {
|
|
637
|
+
...DEFAULT_SWAGGER_CONFIG,
|
|
638
|
+
...restConfig,
|
|
639
|
+
info
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
/**
|
|
643
|
+
* Add a controller to be documented
|
|
644
|
+
*/
|
|
645
|
+
addController(controller) {
|
|
646
|
+
this.controllers.push(controller);
|
|
647
|
+
return this;
|
|
648
|
+
}
|
|
649
|
+
/**
|
|
650
|
+
* Add multiple controllers
|
|
651
|
+
*/
|
|
652
|
+
addControllers(controllers) {
|
|
653
|
+
this.controllers.push(...controllers);
|
|
654
|
+
return this;
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* Add a global security scheme
|
|
658
|
+
*/
|
|
659
|
+
addSecurityScheme(name, scheme) {
|
|
660
|
+
this.globalSecuritySchemes.set(name, scheme);
|
|
661
|
+
return this;
|
|
662
|
+
}
|
|
663
|
+
/**
|
|
664
|
+
* Generate the OpenAPI specification document
|
|
665
|
+
*/
|
|
666
|
+
generate() {
|
|
667
|
+
const paths = {};
|
|
668
|
+
const tags = [];
|
|
669
|
+
const seenTags = /* @__PURE__ */ new Set();
|
|
670
|
+
for (const controller of this.controllers) {
|
|
671
|
+
if (this.isControllerExcluded(controller)) {
|
|
672
|
+
continue;
|
|
673
|
+
}
|
|
674
|
+
const controllerMeta = this.getControllerMeta(controller);
|
|
675
|
+
if (!controllerMeta) continue;
|
|
676
|
+
const controllerTags = this.getControllerTags(controller);
|
|
677
|
+
const controllerDeprecated = this.isControllerDeprecated(controller);
|
|
678
|
+
for (const tag of controllerTags) {
|
|
679
|
+
if (!seenTags.has(tag)) {
|
|
680
|
+
seenTags.add(tag);
|
|
681
|
+
tags.push({
|
|
682
|
+
name: tag
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
const routes = this.getControllerRoutes(controller);
|
|
687
|
+
for (const route of routes) {
|
|
688
|
+
if (this.isEndpointExcluded(controller, route.handlerName)) {
|
|
689
|
+
continue;
|
|
690
|
+
}
|
|
691
|
+
const fullPath = this.normalizePath(controllerMeta.prefix, route.path);
|
|
692
|
+
const method = route.method.toLowerCase();
|
|
693
|
+
if (!paths[fullPath]) {
|
|
694
|
+
paths[fullPath] = {};
|
|
695
|
+
}
|
|
696
|
+
const operation = this.buildOperation(controller, route, controllerTags, controllerDeprecated);
|
|
697
|
+
paths[fullPath][method] = operation;
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
const securitySchemes = this.buildSecuritySchemes();
|
|
701
|
+
const document = {
|
|
702
|
+
openapi: "3.0.3",
|
|
703
|
+
info: this.config.info,
|
|
704
|
+
paths
|
|
705
|
+
};
|
|
706
|
+
if (tags.length > 0) {
|
|
707
|
+
document.tags = tags;
|
|
708
|
+
}
|
|
709
|
+
if (this.config.servers && this.config.servers.length > 0) {
|
|
710
|
+
document.servers = this.config.servers;
|
|
711
|
+
}
|
|
712
|
+
if (Object.keys(securitySchemes).length > 0) {
|
|
713
|
+
document.components = {
|
|
714
|
+
...document.components,
|
|
715
|
+
securitySchemes
|
|
716
|
+
};
|
|
717
|
+
}
|
|
718
|
+
if (this.config.externalDocs) {
|
|
719
|
+
document.externalDocs = this.config.externalDocs;
|
|
720
|
+
}
|
|
721
|
+
return document;
|
|
722
|
+
}
|
|
723
|
+
// ============================================================================
|
|
724
|
+
// Private: Metadata Getters (using core helpers)
|
|
725
|
+
// ============================================================================
|
|
726
|
+
getControllerMeta(controller) {
|
|
727
|
+
return (0, import_core.getControllerMetadata)(controller);
|
|
728
|
+
}
|
|
729
|
+
getControllerRoutes(controller) {
|
|
730
|
+
return (0, import_core.getRoutes)(controller);
|
|
731
|
+
}
|
|
732
|
+
getControllerTags(controller) {
|
|
733
|
+
return (0, import_core.getClassMetadata)(API_TAGS_METADATA, controller) || [];
|
|
734
|
+
}
|
|
735
|
+
isControllerExcluded(controller) {
|
|
736
|
+
return (0, import_core.getClassMetadata)(API_EXCLUDE_METADATA, controller) === true;
|
|
737
|
+
}
|
|
738
|
+
isControllerDeprecated(controller) {
|
|
739
|
+
return (0, import_core.getClassMetadata)(API_DEPRECATED_METADATA, controller) === true;
|
|
740
|
+
}
|
|
741
|
+
isEndpointExcluded(controller, handlerName) {
|
|
742
|
+
return (0, import_core.getMethodMetadata)(API_EXCLUDE_METADATA, controller, handlerName) === true;
|
|
743
|
+
}
|
|
744
|
+
isEndpointDeprecated(controller, handlerName) {
|
|
745
|
+
const controllerLevel = (0, import_core.getClassMetadata)(API_DEPRECATED_METADATA, controller);
|
|
746
|
+
const methodLevel = (0, import_core.getMethodMetadata)(API_DEPRECATED_METADATA, controller, handlerName);
|
|
747
|
+
return controllerLevel?.deprecated === true || methodLevel?.deprecated === true;
|
|
748
|
+
}
|
|
749
|
+
getOperationMetadata(controller, handlerName) {
|
|
750
|
+
return (0, import_core.getMethodMetadata)(API_OPERATION_METADATA, controller, handlerName);
|
|
751
|
+
}
|
|
752
|
+
getResponseMetadata(controller, handlerName) {
|
|
753
|
+
return (0, import_core.getMethodMetadata)(API_RESPONSE_METADATA, controller, handlerName) || [];
|
|
754
|
+
}
|
|
755
|
+
getBodyMetadata(controller, handlerName) {
|
|
756
|
+
return (0, import_core.getMethodMetadata)(API_BODY_METADATA, controller, handlerName);
|
|
757
|
+
}
|
|
758
|
+
getSwaggerParamMetadata(controller, handlerName) {
|
|
759
|
+
return (0, import_core.getMethodMetadata)(API_PARAM_METADATA, controller, handlerName) || [];
|
|
760
|
+
}
|
|
761
|
+
getQueryMetadata(controller, handlerName) {
|
|
762
|
+
return (0, import_core.getMethodMetadata)(API_QUERY_METADATA, controller, handlerName) || [];
|
|
763
|
+
}
|
|
764
|
+
getHeaderMetadata(controller, handlerName) {
|
|
765
|
+
return (0, import_core.getMethodMetadata)(API_HEADER_METADATA, controller, handlerName) || [];
|
|
766
|
+
}
|
|
767
|
+
getSecurityMetadata(controller, handlerName) {
|
|
768
|
+
const controllerLevel = (0, import_core.getClassMetadata)(API_SECURITY_METADATA, controller);
|
|
769
|
+
const methodLevel = (0, import_core.getMethodMetadata)(API_SECURITY_METADATA, controller, handlerName);
|
|
770
|
+
const result = [];
|
|
771
|
+
if (controllerLevel && typeof controllerLevel === "object" && "name" in controllerLevel) {
|
|
772
|
+
result.push(controllerLevel);
|
|
773
|
+
} else if (Array.isArray(controllerLevel)) {
|
|
774
|
+
result.push(...controllerLevel);
|
|
775
|
+
}
|
|
776
|
+
if (methodLevel && typeof methodLevel === "object" && "name" in methodLevel) {
|
|
777
|
+
result.push(methodLevel);
|
|
778
|
+
} else if (Array.isArray(methodLevel)) {
|
|
779
|
+
result.push(...methodLevel);
|
|
780
|
+
}
|
|
781
|
+
return result;
|
|
782
|
+
}
|
|
783
|
+
getMethodTags(controller, handlerName) {
|
|
784
|
+
const operation = this.getOperationMetadata(controller, handlerName);
|
|
785
|
+
return operation?.tags;
|
|
786
|
+
}
|
|
787
|
+
getHttpStatusCode(controller, handlerName) {
|
|
788
|
+
return (0, import_core.getHttpCode)(controller, handlerName);
|
|
789
|
+
}
|
|
790
|
+
getCoreParams(controller, handlerName) {
|
|
791
|
+
return (0, import_core.getParamMetadata)(controller, handlerName);
|
|
792
|
+
}
|
|
793
|
+
// ============================================================================
|
|
794
|
+
// Private: Path Utilities
|
|
795
|
+
// ============================================================================
|
|
796
|
+
normalizePath(prefix, path) {
|
|
797
|
+
let fullPath = "";
|
|
798
|
+
if (prefix) {
|
|
799
|
+
fullPath = prefix.startsWith("/") ? prefix : `/${prefix}`;
|
|
800
|
+
}
|
|
801
|
+
if (path) {
|
|
802
|
+
const cleanPath = path.startsWith("/") ? path : `/${path}`;
|
|
803
|
+
fullPath = fullPath + cleanPath;
|
|
804
|
+
}
|
|
805
|
+
if (!fullPath) {
|
|
806
|
+
fullPath = "/";
|
|
807
|
+
}
|
|
808
|
+
fullPath = fullPath.replace(/:([^/]+)/g, "{$1}");
|
|
809
|
+
if (fullPath !== "/" && fullPath.endsWith("/")) {
|
|
810
|
+
fullPath = fullPath.slice(0, -1);
|
|
811
|
+
}
|
|
812
|
+
return fullPath;
|
|
813
|
+
}
|
|
814
|
+
// ============================================================================
|
|
815
|
+
// Private: Operation Builder
|
|
816
|
+
// ============================================================================
|
|
817
|
+
buildOperation(controller, route, controllerTags, controllerDeprecated) {
|
|
818
|
+
const handlerName = route.handlerName;
|
|
819
|
+
const operationMeta = this.getOperationMetadata(controller, handlerName);
|
|
820
|
+
const methodTags = this.getMethodTags(controller, handlerName);
|
|
821
|
+
const operation = {
|
|
822
|
+
responses: {}
|
|
823
|
+
};
|
|
824
|
+
const tags = methodTags || controllerTags;
|
|
825
|
+
if (tags.length > 0) {
|
|
826
|
+
operation.tags = tags;
|
|
827
|
+
}
|
|
828
|
+
if (operationMeta?.summary) {
|
|
829
|
+
operation.summary = operationMeta.summary;
|
|
830
|
+
}
|
|
831
|
+
if (operationMeta?.description) {
|
|
832
|
+
operation.description = operationMeta.description;
|
|
833
|
+
}
|
|
834
|
+
if (operationMeta?.operationId) {
|
|
835
|
+
operation.operationId = operationMeta.operationId;
|
|
836
|
+
}
|
|
837
|
+
if (controllerDeprecated || operationMeta?.deprecated || this.isEndpointDeprecated(controller, handlerName)) {
|
|
838
|
+
operation.deprecated = true;
|
|
839
|
+
}
|
|
840
|
+
const parameters = this.buildParameters(controller, handlerName, route.path);
|
|
841
|
+
if (parameters.length > 0) {
|
|
842
|
+
operation.parameters = parameters;
|
|
843
|
+
}
|
|
844
|
+
if ([
|
|
845
|
+
"POST",
|
|
846
|
+
"PUT",
|
|
847
|
+
"PATCH"
|
|
848
|
+
].includes(route.method)) {
|
|
849
|
+
const requestBody = this.buildRequestBody(controller, handlerName);
|
|
850
|
+
if (requestBody) {
|
|
851
|
+
operation.requestBody = requestBody;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
operation.responses = this.buildResponses(controller, handlerName, route.statusCode);
|
|
855
|
+
const security = this.getSecurityMetadata(controller, handlerName);
|
|
856
|
+
if (security.length > 0) {
|
|
857
|
+
operation.security = security.map((s) => ({
|
|
858
|
+
[s.name]: s.scopes || []
|
|
859
|
+
}));
|
|
860
|
+
}
|
|
861
|
+
return operation;
|
|
862
|
+
}
|
|
863
|
+
buildParameters(controller, handlerName, routePath) {
|
|
864
|
+
const parameters = [];
|
|
865
|
+
const pathParams = this.extractPathParams(routePath);
|
|
866
|
+
const paramDecorators = this.getSwaggerParamMetadata(controller, handlerName);
|
|
867
|
+
const queryDecorators = this.getQueryMetadata(controller, handlerName);
|
|
868
|
+
const headerDecorators = this.getHeaderMetadata(controller, handlerName);
|
|
869
|
+
const coreParams = this.getCoreParams(controller, handlerName);
|
|
870
|
+
const usedPathParams = /* @__PURE__ */ new Set();
|
|
871
|
+
for (const param of paramDecorators) {
|
|
872
|
+
usedPathParams.add(param.name);
|
|
873
|
+
const baseSchema = toOpenApiSchema(param.schema);
|
|
874
|
+
const fallbackSchema = {
|
|
875
|
+
type: param.type || "string"
|
|
876
|
+
};
|
|
877
|
+
if (param.format) {
|
|
878
|
+
fallbackSchema.format = param.format;
|
|
879
|
+
}
|
|
880
|
+
parameters.push({
|
|
881
|
+
name: param.name,
|
|
882
|
+
in: "path",
|
|
883
|
+
required: true,
|
|
884
|
+
deprecated: param.deprecated,
|
|
885
|
+
description: param.description,
|
|
886
|
+
schema: baseSchema || fallbackSchema,
|
|
887
|
+
example: param.example
|
|
888
|
+
});
|
|
889
|
+
}
|
|
890
|
+
for (const paramName of pathParams) {
|
|
891
|
+
if (!usedPathParams.has(paramName)) {
|
|
892
|
+
const coreParam = coreParams.find((p) => p.type === import_core.ParamType.PARAM && p.key === paramName);
|
|
893
|
+
const schema = coreParam?.zodSchema ? zodToOpenApi(coreParam.zodSchema) : {
|
|
894
|
+
type: "string"
|
|
895
|
+
};
|
|
896
|
+
parameters.push({
|
|
897
|
+
name: paramName,
|
|
898
|
+
in: "path",
|
|
899
|
+
required: true,
|
|
900
|
+
schema
|
|
901
|
+
});
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
for (const query of queryDecorators) {
|
|
905
|
+
const baseSchema = toOpenApiSchema(query.schema);
|
|
906
|
+
const fallbackSchema = {
|
|
907
|
+
type: query.type || "string"
|
|
908
|
+
};
|
|
909
|
+
if (query.format) {
|
|
910
|
+
fallbackSchema.format = query.format;
|
|
911
|
+
}
|
|
912
|
+
parameters.push({
|
|
913
|
+
name: query.name,
|
|
914
|
+
in: "query",
|
|
915
|
+
required: query.required,
|
|
916
|
+
deprecated: query.deprecated,
|
|
917
|
+
description: query.description,
|
|
918
|
+
schema: baseSchema || fallbackSchema,
|
|
919
|
+
example: query.example
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
for (const header of headerDecorators) {
|
|
923
|
+
parameters.push({
|
|
924
|
+
name: header.name,
|
|
925
|
+
in: "header",
|
|
926
|
+
required: header.required,
|
|
927
|
+
deprecated: header.deprecated,
|
|
928
|
+
description: header.description,
|
|
929
|
+
schema: toOpenApiSchema(header.schema) || {
|
|
930
|
+
type: header.type || "string"
|
|
931
|
+
},
|
|
932
|
+
example: header.example
|
|
933
|
+
});
|
|
934
|
+
}
|
|
935
|
+
return parameters;
|
|
936
|
+
}
|
|
937
|
+
extractPathParams(path) {
|
|
938
|
+
const params = [];
|
|
939
|
+
const regex = /:([^/]+)|{([^}]+)}/g;
|
|
940
|
+
let match;
|
|
941
|
+
while ((match = regex.exec(path)) !== null) {
|
|
942
|
+
const paramName = match[1] ?? match[2];
|
|
943
|
+
if (paramName) {
|
|
944
|
+
params.push(paramName);
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
return params;
|
|
948
|
+
}
|
|
949
|
+
buildRequestBody(controller, handlerName) {
|
|
950
|
+
const bodyMeta = this.getBodyMetadata(controller, handlerName);
|
|
951
|
+
const coreParams = this.getCoreParams(controller, handlerName);
|
|
952
|
+
if (bodyMeta) {
|
|
953
|
+
const schema = toOpenApiSchema(bodyMeta.schema);
|
|
954
|
+
return {
|
|
955
|
+
description: bodyMeta.description,
|
|
956
|
+
required: bodyMeta.required ?? true,
|
|
957
|
+
content: {
|
|
958
|
+
[bodyMeta.type || "application/json"]: {
|
|
959
|
+
schema: bodyMeta.isArray && schema ? {
|
|
960
|
+
type: "array",
|
|
961
|
+
items: schema
|
|
962
|
+
} : schema,
|
|
963
|
+
example: bodyMeta.example
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
const bodyParam = coreParams.find((p) => p.type === import_core.ParamType.BODY);
|
|
969
|
+
if (bodyParam?.zodSchema) {
|
|
970
|
+
return {
|
|
971
|
+
required: true,
|
|
972
|
+
content: {
|
|
973
|
+
"application/json": {
|
|
974
|
+
schema: zodToOpenApi(bodyParam.zodSchema)
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
};
|
|
978
|
+
}
|
|
979
|
+
return void 0;
|
|
980
|
+
}
|
|
981
|
+
buildResponses(controller, handlerName, defaultStatusCode) {
|
|
982
|
+
const responses = {};
|
|
983
|
+
const responseMeta = this.getResponseMetadata(controller, handlerName);
|
|
984
|
+
const httpCode = this.getHttpStatusCode(controller, handlerName);
|
|
985
|
+
if (responseMeta.length > 0) {
|
|
986
|
+
for (const response of responseMeta) {
|
|
987
|
+
const statusCode = response.status.toString();
|
|
988
|
+
const schema = toOpenApiSchema(response.schema);
|
|
989
|
+
responses[statusCode] = {
|
|
990
|
+
description: response.description || this.getDefaultStatusDescription(response.status)
|
|
991
|
+
};
|
|
992
|
+
if (schema || response.example) {
|
|
993
|
+
responses[statusCode].content = {
|
|
994
|
+
[response.type || "application/json"]: {
|
|
995
|
+
schema: response.isArray && schema ? {
|
|
996
|
+
type: "array",
|
|
997
|
+
items: schema
|
|
998
|
+
} : schema,
|
|
999
|
+
example: response.example
|
|
1000
|
+
}
|
|
1001
|
+
};
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
} else {
|
|
1005
|
+
const status = (httpCode || defaultStatusCode || 200).toString();
|
|
1006
|
+
responses[status] = {
|
|
1007
|
+
description: this.getDefaultStatusDescription(Number(status))
|
|
1008
|
+
};
|
|
1009
|
+
}
|
|
1010
|
+
return responses;
|
|
1011
|
+
}
|
|
1012
|
+
getDefaultStatusDescription(status) {
|
|
1013
|
+
const descriptions = {
|
|
1014
|
+
200: "Successful response",
|
|
1015
|
+
201: "Resource created successfully",
|
|
1016
|
+
204: "No content",
|
|
1017
|
+
400: "Bad request",
|
|
1018
|
+
401: "Unauthorized",
|
|
1019
|
+
403: "Forbidden",
|
|
1020
|
+
404: "Not found",
|
|
1021
|
+
409: "Conflict",
|
|
1022
|
+
422: "Unprocessable entity",
|
|
1023
|
+
500: "Internal server error"
|
|
1024
|
+
};
|
|
1025
|
+
return descriptions[status] || "Response";
|
|
1026
|
+
}
|
|
1027
|
+
buildSecuritySchemes() {
|
|
1028
|
+
const schemes = {};
|
|
1029
|
+
for (const [name, options] of this.globalSecuritySchemes) {
|
|
1030
|
+
schemes[name] = {
|
|
1031
|
+
type: options.type,
|
|
1032
|
+
description: options.description
|
|
1033
|
+
};
|
|
1034
|
+
if (options.type === "apiKey") {
|
|
1035
|
+
schemes[name].name = options.name;
|
|
1036
|
+
schemes[name].in = options.in;
|
|
1037
|
+
} else if (options.type === "http") {
|
|
1038
|
+
schemes[name].scheme = options.scheme;
|
|
1039
|
+
if (options.bearerFormat) {
|
|
1040
|
+
schemes[name].bearerFormat = options.bearerFormat;
|
|
1041
|
+
}
|
|
1042
|
+
} else if (options.type === "oauth2" && options.flows) {
|
|
1043
|
+
schemes[name].flows = options.flows;
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
return schemes;
|
|
1047
|
+
}
|
|
1048
|
+
};
|
|
1049
|
+
|
|
1050
|
+
// src/plugin/swagger.plugin.ts
|
|
1051
|
+
var import_fastify_plugin = __toESM(require("fastify-plugin"), 1);
|
|
1052
|
+
var import_swagger = __toESM(require("@fastify/swagger"), 1);
|
|
1053
|
+
var import_swagger_ui = __toESM(require("@fastify/swagger-ui"), 1);
|
|
1054
|
+
var import_core2 = require("@riktajs/core");
|
|
1055
|
+
var DEFAULT_OPTIONS = {
|
|
1056
|
+
jsonPath: "/docs/json",
|
|
1057
|
+
uiPath: "/docs",
|
|
1058
|
+
exposeUI: true,
|
|
1059
|
+
exposeSpec: true
|
|
1060
|
+
};
|
|
1061
|
+
async function swaggerPluginImpl(fastify, options) {
|
|
1062
|
+
const mergedOptions = {
|
|
1063
|
+
...DEFAULT_OPTIONS,
|
|
1064
|
+
...options
|
|
1065
|
+
};
|
|
1066
|
+
const { jsonPath, uiPath, exposeUI, exposeSpec, controllers, config, info, transform } = mergedOptions;
|
|
1067
|
+
const apiInfo = info || config?.info || {
|
|
1068
|
+
title: "API Documentation",
|
|
1069
|
+
version: "1.0.0"
|
|
1070
|
+
};
|
|
1071
|
+
const generator = new OpenApiGenerator({
|
|
1072
|
+
...config,
|
|
1073
|
+
info: apiInfo
|
|
1074
|
+
});
|
|
1075
|
+
const controllersToDocument = controllers || import_core2.registry.getControllers();
|
|
1076
|
+
for (const controller of controllersToDocument) {
|
|
1077
|
+
generator.addController(controller);
|
|
1078
|
+
}
|
|
1079
|
+
if (config?.securitySchemes) {
|
|
1080
|
+
for (const [name, scheme] of Object.entries(config.securitySchemes)) {
|
|
1081
|
+
generator.addSecurityScheme(name, scheme);
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
let spec = generator.generate();
|
|
1085
|
+
if (transform) {
|
|
1086
|
+
spec = await transform(spec);
|
|
1087
|
+
}
|
|
1088
|
+
await fastify.register(import_swagger.default, {
|
|
1089
|
+
mode: "static",
|
|
1090
|
+
specification: {
|
|
1091
|
+
document: spec
|
|
1092
|
+
}
|
|
1093
|
+
});
|
|
1094
|
+
if (exposeUI) {
|
|
1095
|
+
const uiOptions = {
|
|
1096
|
+
routePrefix: uiPath,
|
|
1097
|
+
uiConfig: {
|
|
1098
|
+
docExpansion: "list",
|
|
1099
|
+
deepLinking: true,
|
|
1100
|
+
displayRequestDuration: true,
|
|
1101
|
+
filter: true,
|
|
1102
|
+
syntaxHighlight: {
|
|
1103
|
+
activate: true,
|
|
1104
|
+
theme: mergedOptions.theme === "dark" ? "monokai" : "agate"
|
|
1105
|
+
}
|
|
1106
|
+
},
|
|
1107
|
+
staticCSP: true,
|
|
1108
|
+
transformStaticCSP: /* @__PURE__ */ __name((header) => header, "transformStaticCSP")
|
|
1109
|
+
};
|
|
1110
|
+
if (mergedOptions.logo) {
|
|
1111
|
+
uiOptions.logo = {
|
|
1112
|
+
type: "image/png",
|
|
1113
|
+
content: mergedOptions.logo.url,
|
|
1114
|
+
href: mergedOptions.logo.url
|
|
1115
|
+
};
|
|
1116
|
+
}
|
|
1117
|
+
await fastify.register(import_swagger_ui.default, uiOptions);
|
|
1118
|
+
}
|
|
1119
|
+
const defaultSwaggerUIJsonPath = `${uiPath}/json`;
|
|
1120
|
+
const shouldRegisterCustomJsonRoute = exposeSpec && (!exposeUI || jsonPath !== defaultSwaggerUIJsonPath && jsonPath !== "/docs/json");
|
|
1121
|
+
if (shouldRegisterCustomJsonRoute) {
|
|
1122
|
+
fastify.get(jsonPath, {
|
|
1123
|
+
schema: {
|
|
1124
|
+
hide: true
|
|
1125
|
+
}
|
|
1126
|
+
}, async () => {
|
|
1127
|
+
return spec;
|
|
1128
|
+
});
|
|
1129
|
+
}
|
|
1130
|
+
fastify.decorate("openApiSpec", spec);
|
|
1131
|
+
}
|
|
1132
|
+
__name(swaggerPluginImpl, "swaggerPluginImpl");
|
|
1133
|
+
var swaggerPlugin = (0, import_fastify_plugin.default)(swaggerPluginImpl, {
|
|
1134
|
+
fastify: ">=4.0.0",
|
|
1135
|
+
name: "@riktajs/swagger",
|
|
1136
|
+
dependencies: []
|
|
1137
|
+
});
|
|
1138
|
+
async function registerSwagger(app, options = {}) {
|
|
1139
|
+
await app.register(swaggerPlugin, options);
|
|
1140
|
+
}
|
|
1141
|
+
__name(registerSwagger, "registerSwagger");
|
|
1142
|
+
function createSwaggerConfig(options = {}) {
|
|
1143
|
+
const mergedOptions = {
|
|
1144
|
+
...DEFAULT_OPTIONS,
|
|
1145
|
+
...options
|
|
1146
|
+
};
|
|
1147
|
+
const { uiPath, controllers, config, info } = mergedOptions;
|
|
1148
|
+
const apiInfo = info || config?.info || {
|
|
1149
|
+
title: "API Documentation",
|
|
1150
|
+
version: "1.0.0"
|
|
1151
|
+
};
|
|
1152
|
+
const generator = new OpenApiGenerator({
|
|
1153
|
+
...config,
|
|
1154
|
+
info: apiInfo
|
|
1155
|
+
});
|
|
1156
|
+
const controllersToDocument = controllers || import_core2.registry.getControllers();
|
|
1157
|
+
for (const controller of controllersToDocument) {
|
|
1158
|
+
generator.addController(controller);
|
|
1159
|
+
}
|
|
1160
|
+
if (config?.securitySchemes) {
|
|
1161
|
+
for (const [name, scheme] of Object.entries(config.securitySchemes)) {
|
|
1162
|
+
generator.addSecurityScheme(name, scheme);
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
const specification = generator.generate();
|
|
1166
|
+
return {
|
|
1167
|
+
swaggerOptions: {
|
|
1168
|
+
mode: "static",
|
|
1169
|
+
specification: {
|
|
1170
|
+
document: specification
|
|
1171
|
+
}
|
|
1172
|
+
},
|
|
1173
|
+
swaggerUIOptions: {
|
|
1174
|
+
routePrefix: uiPath,
|
|
1175
|
+
uiConfig: {
|
|
1176
|
+
docExpansion: "list",
|
|
1177
|
+
deepLinking: true,
|
|
1178
|
+
displayRequestDuration: true,
|
|
1179
|
+
filter: true
|
|
1180
|
+
}
|
|
1181
|
+
},
|
|
1182
|
+
specification
|
|
1183
|
+
};
|
|
1184
|
+
}
|
|
1185
|
+
__name(createSwaggerConfig, "createSwaggerConfig");
|
|
1186
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
1187
|
+
0 && (module.exports = {
|
|
1188
|
+
API_BODY_METADATA,
|
|
1189
|
+
API_DEPRECATED_METADATA,
|
|
1190
|
+
API_EXCLUDE_METADATA,
|
|
1191
|
+
API_HEADER_METADATA,
|
|
1192
|
+
API_OPERATION_METADATA,
|
|
1193
|
+
API_PARAM_METADATA,
|
|
1194
|
+
API_PROPERTY_METADATA,
|
|
1195
|
+
API_QUERY_METADATA,
|
|
1196
|
+
API_RESPONSE_METADATA,
|
|
1197
|
+
API_SECURITY_METADATA,
|
|
1198
|
+
API_TAGS_METADATA,
|
|
1199
|
+
ApiAcceptedResponse,
|
|
1200
|
+
ApiBadRequestResponse,
|
|
1201
|
+
ApiBasicAuth,
|
|
1202
|
+
ApiBearerAuth,
|
|
1203
|
+
ApiBody,
|
|
1204
|
+
ApiConflictResponse,
|
|
1205
|
+
ApiCookieAuth,
|
|
1206
|
+
ApiCreatedResponse,
|
|
1207
|
+
ApiDeprecated,
|
|
1208
|
+
ApiExcludeController,
|
|
1209
|
+
ApiExcludeEndpoint,
|
|
1210
|
+
ApiForbiddenResponse,
|
|
1211
|
+
ApiHeader,
|
|
1212
|
+
ApiHideProperty,
|
|
1213
|
+
ApiInternalServerErrorResponse,
|
|
1214
|
+
ApiNoContentResponse,
|
|
1215
|
+
ApiNotFoundResponse,
|
|
1216
|
+
ApiOAuth2,
|
|
1217
|
+
ApiOkResponse,
|
|
1218
|
+
ApiOperation,
|
|
1219
|
+
ApiParam,
|
|
1220
|
+
ApiProperty,
|
|
1221
|
+
ApiPropertyOptional,
|
|
1222
|
+
ApiQuery,
|
|
1223
|
+
ApiResponse,
|
|
1224
|
+
ApiSecurity,
|
|
1225
|
+
ApiTags,
|
|
1226
|
+
ApiUnauthorizedResponse,
|
|
1227
|
+
ApiUnprocessableEntityResponse,
|
|
1228
|
+
CONTROLLER_METADATA,
|
|
1229
|
+
GUARDS_METADATA,
|
|
1230
|
+
HTTP_CODE_METADATA,
|
|
1231
|
+
OpenApiGenerator,
|
|
1232
|
+
PARAM_METADATA,
|
|
1233
|
+
ROUTES_METADATA,
|
|
1234
|
+
ZOD_SCHEMA_METADATA,
|
|
1235
|
+
createSwaggerConfig,
|
|
1236
|
+
getApiBody,
|
|
1237
|
+
getApiDeprecated,
|
|
1238
|
+
getApiHeaders,
|
|
1239
|
+
getApiOperation,
|
|
1240
|
+
getApiParams,
|
|
1241
|
+
getApiProperties,
|
|
1242
|
+
getApiQueries,
|
|
1243
|
+
getApiResponses,
|
|
1244
|
+
getApiSecurity,
|
|
1245
|
+
getApiTags,
|
|
1246
|
+
isApiExcluded,
|
|
1247
|
+
isZodSchema,
|
|
1248
|
+
registerSwagger,
|
|
1249
|
+
swaggerPlugin,
|
|
1250
|
+
toOpenApiSchema,
|
|
1251
|
+
zodToOpenApi
|
|
1252
|
+
});
|
|
1253
|
+
//# sourceMappingURL=index.cjs.map
|