@trapi/swagger 0.2.11 → 0.2.15

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 (58) hide show
  1. package/dist/config/utils/index.d.ts +1 -1
  2. package/dist/config/utils/validator.d.ts +2 -2
  3. package/dist/config/utils/validator.d.ts.map +1 -1
  4. package/dist/config/utils/validator.js +9 -9
  5. package/dist/config/utils/validator.js.map +1 -1
  6. package/dist/metadata.d.ts +1 -1
  7. package/dist/metadata.d.ts.map +1 -1
  8. package/dist/specification/abstract.d.ts +5 -5
  9. package/dist/specification/abstract.d.ts.map +1 -1
  10. package/dist/specification/abstract.js +23 -27
  11. package/dist/specification/abstract.js.map +1 -1
  12. package/dist/specification/index.d.ts +1 -1
  13. package/dist/specification/type.d.ts +0 -3
  14. package/dist/specification/type.d.ts.map +1 -1
  15. package/dist/specification/type.js.map +1 -1
  16. package/dist/specification/utils.d.ts +3 -3
  17. package/dist/specification/utils.d.ts.map +1 -1
  18. package/dist/specification/utils.js +1 -1
  19. package/dist/specification/utils.js.map +1 -1
  20. package/dist/specification/v2/index.d.ts +3 -3
  21. package/dist/specification/v2/index.d.ts.map +1 -1
  22. package/dist/specification/v2/index.js +48 -60
  23. package/dist/specification/v2/index.js.map +1 -1
  24. package/dist/specification/v2/type.d.ts +1 -1
  25. package/dist/specification/v2/type.d.ts.map +1 -1
  26. package/dist/specification/v3/index.d.ts +3 -3
  27. package/dist/specification/v3/index.d.ts.map +1 -1
  28. package/dist/specification/v3/index.js +28 -36
  29. package/dist/specification/v3/index.js.map +1 -1
  30. package/dist/specification/v3/type.d.ts +1 -1
  31. package/dist/specification/v3/type.d.ts.map +1 -1
  32. package/dist/utils.d.ts +3 -3
  33. package/dist/utils.d.ts.map +1 -1
  34. package/dist/utils.js +1 -1
  35. package/dist/utils.js.map +1 -1
  36. package/package.json +12 -9
  37. package/src/config/index.ts +0 -8
  38. package/src/config/utils/index.ts +0 -8
  39. package/src/config/utils/validator.ts +0 -94
  40. package/src/index.ts +0 -12
  41. package/src/metadata.ts +0 -58
  42. package/src/specification/abstract.ts +0 -250
  43. package/src/specification/index.ts +0 -11
  44. package/src/specification/type.ts +0 -328
  45. package/src/specification/utils.ts +0 -47
  46. package/src/specification/v2/index.ts +0 -463
  47. package/src/specification/v2/type.ts +0 -92
  48. package/src/specification/v3/index.ts +0 -448
  49. package/src/specification/v3/type.ts +0 -129
  50. package/src/type.ts +0 -14
  51. package/src/utils.ts +0 -28
  52. package/test/data/metadata.json +0 -1
  53. package/test/jest.config.js +0 -43
  54. package/test/tsconfig.json +0 -28
  55. package/test/unit/index.ts +0 -425
  56. package/tsconfig.build.json +0 -11
  57. package/tsconfig.json +0 -9
  58. package/writable/.gitignore +0 -3
@@ -1,448 +0,0 @@
1
- /*
2
- * Copyright (c) 2021.
3
- * Author Peter Placzek (tada5hi)
4
- * For the full copyright and license information,
5
- * view the LICENSE file that was distributed with this source code.
6
- */
7
-
8
- import {URL} from "url";
9
- import {hasOwnProperty, normalizePathParameters} from "@trapi/metadata-utils";
10
- import {Method, Parameter, Property, Resolver, Response} from "@trapi/metadata";
11
- import {Specification} from "../type";
12
- import {SpecificationV3} from "./type";
13
- import {removeFinalCharacter, removeRepeatingCharacter} from "../utils";
14
- import {AbstractSpecGenerator} from "../abstract";
15
-
16
- export class Version3SpecGenerator extends AbstractSpecGenerator<SpecificationV3.Spec, SpecificationV3.Schema> {
17
- public getSwaggerSpec(): SpecificationV3.Spec {
18
- return this.build();
19
- }
20
-
21
- public build() : SpecificationV3.Spec {
22
- if(typeof this.spec !== 'undefined') {
23
- return this.spec;
24
- }
25
-
26
- let spec: SpecificationV3.Spec = {
27
- components: this.buildComponents(),
28
- info: this.buildInfo(),
29
- openapi: '3.0.0',
30
- paths: this.buildPaths(),
31
- servers: this.buildServers(),
32
- tags: [],
33
- };
34
-
35
- if (this.config.specificationExtra) {
36
- spec = require('merge').recursive(spec, this.config.specificationExtra);
37
- }
38
-
39
- return spec;
40
- }
41
-
42
- private buildComponents() {
43
- const components = {
44
- examples: {},
45
- headers: {},
46
- parameters: {},
47
- requestBodies: {},
48
- responses: {},
49
- schemas: this.buildSchema(),
50
- securitySchemes: {},
51
- };
52
-
53
- if (this.config.securityDefinitions) {
54
- components.securitySchemes = Version3SpecGenerator.translateSecurityDefinitions(this.config.securityDefinitions);
55
- }
56
-
57
- return components;
58
- }
59
-
60
- private static translateSecurityDefinitions(securityDefinitions: Specification.SecurityDefinitions) : Record<string, SpecificationV3.Security> {
61
- const security : Record<string, SpecificationV3.Security> = {};
62
-
63
- // tslint:disable-next-line:forin
64
- for(const name in securityDefinitions) {
65
- const securityDefinition : Specification.SecurityDefinition = securityDefinitions[name];
66
-
67
- switch (securityDefinition.type) {
68
- case "http":
69
- security[name] = securityDefinition;
70
- break;
71
- case "oauth2":
72
- security[name] = securityDefinition;
73
- break;
74
- case "apiKey":
75
- security[name] = securityDefinition;
76
- break;
77
- }
78
- }
79
-
80
- return security;
81
- }
82
-
83
- private buildPaths() {
84
- const paths: { [pathName: string]: Specification.Path<SpecificationV3.Operation, SpecificationV3.Parameter> } = {};
85
-
86
- this.metadata.controllers.forEach(controller => {
87
- // construct documentation using all methods except @Hidden
88
- controller.methods
89
- .filter(method => !method.hidden)
90
- .forEach(method => {
91
- let path = removeFinalCharacter(removeRepeatingCharacter(`/${controller.path}/${method.path}`, '/'), '/');
92
- path = normalizePathParameters(path);
93
- paths[path] = paths[path] || {};
94
- this.buildMethod(controller.name, method, paths[path]);
95
- });
96
- });
97
-
98
- return paths;
99
- }
100
-
101
- private buildMethod(controllerName: string, method: Method, pathObject: any) {
102
- const pathMethod: SpecificationV3.Operation = (pathObject[method.method] = this.buildOperation(controllerName, method));
103
- pathMethod.description = method.description;
104
- pathMethod.summary = method.summary;
105
- pathMethod.tags = method.tags;
106
-
107
- // Use operationId tag otherwise fallback to generated. Warning: This doesn't check uniqueness.
108
- pathMethod.operationId = method.operationId || pathMethod.operationId;
109
-
110
- if (method.deprecated) {
111
- pathMethod.deprecated = method.deprecated;
112
- }
113
-
114
- if (method.security) {
115
- pathMethod.security = method.security as any[];
116
- }
117
-
118
- const bodyParams = method.parameters.filter(p => p.in === 'body');
119
- const formParams = method.parameters.filter(p => p.in === 'formData');
120
-
121
- pathMethod.parameters = method.parameters
122
- .filter(p => {
123
- return ['body', 'formData', 'request', 'body-prop', 'res'].indexOf(p.in) === -1;
124
- })
125
- .map(p => this.buildParameter(p));
126
-
127
- if (bodyParams.length > 1) {
128
- throw new Error('Only one body parameter allowed per controller method.');
129
- }
130
-
131
- if (bodyParams.length > 0 && formParams.length > 0) {
132
- throw new Error('Either body parameter or form parameters allowed per controller method - not both.');
133
- }
134
-
135
- if (bodyParams.length > 0) {
136
- pathMethod.requestBody = this.buildRequestBody(bodyParams[0]);
137
- } else if (formParams.length > 0) {
138
- pathMethod.requestBody = this.buildRequestBodyWithFormData(formParams);
139
- }
140
-
141
- method.extensions.forEach(ext => (pathMethod[ext.key] = ext.value));
142
- }
143
-
144
- private buildRequestBodyWithFormData(parameters: Parameter[]): SpecificationV3.RequestBody {
145
- const required: string[] = [];
146
- const properties: { [propertyName: string]: SpecificationV3.Schema } = {};
147
- for (const parameter of parameters) {
148
- const mediaType = this.buildMediaType(parameter);
149
- properties[parameter.name] = mediaType.schema!;
150
- if (parameter.required) {
151
- required.push(parameter.name);
152
- }
153
- }
154
- return {
155
- required: required.length > 0,
156
- content: {
157
- 'multipart/form-data': {
158
- schema: {
159
- type: 'object',
160
- properties: properties,
161
- // An empty list required: [] is not valid.
162
- // If all properties are optional, do not specify the required keyword.
163
- ...(required && required.length && {required: required}),
164
- },
165
- },
166
- },
167
- };
168
- }
169
-
170
- private buildRequestBody(parameter: Parameter): SpecificationV3.RequestBody {
171
- const mediaType = this.buildMediaType(parameter);
172
-
173
- return {
174
- description: parameter.description,
175
- required: parameter.required,
176
- content: {
177
- 'application/json': mediaType,
178
- },
179
- };
180
- }
181
-
182
- private buildMediaType(parameter: Parameter): SpecificationV3.MediaType {
183
- const mediaType: SpecificationV3.MediaType = {
184
- schema: this.getSwaggerType(parameter.type),
185
- };
186
-
187
- this.buildFromParameterExamples(mediaType, parameter);
188
-
189
- return mediaType;
190
- }
191
-
192
- protected buildOperation(controllerName: string, method: Method): SpecificationV3.Operation {
193
- const swaggerResponses: { [name: string]: SpecificationV3.Response } = {};
194
-
195
- method.responses.forEach((res: Response) => {
196
- const name : string = res.status ?? 'default';
197
- // no string key
198
- swaggerResponses[name] = {
199
- description: res.description,
200
- };
201
-
202
- if (res.schema && !Resolver.isVoidType(res.schema)) {
203
- const contentKey : string = 'application/json';
204
- swaggerResponses[name].content = {
205
- [contentKey]: {
206
- schema: this.getSwaggerType(res.schema) as SpecificationV3.Schema,
207
- } as SpecificationV3.Schema,
208
- };
209
-
210
- if (res.examples) {
211
- swaggerResponses[name].content[contentKey]['examples'] = {
212
- default: {
213
- value: res.examples
214
- }
215
- };
216
- }
217
- }
218
-
219
- if (res.headers) {
220
- const headers: { [name: string]: SpecificationV3.Header } = {};
221
- if (res.headers.typeName === 'refObject') {
222
- headers[res.headers.refName] = {
223
- schema: this.getSwaggerTypeForReferenceType(res.headers) as SpecificationV3.Schema,
224
- description: res.headers.description,
225
- };
226
- } else if (res.headers.typeName === 'nestedObjectLiteral') {
227
- res.headers.properties.forEach((each: Property) => {
228
- headers[each.name] = {
229
- schema: this.getSwaggerType(each.type) as SpecificationV3.Schema,
230
- description: each.description,
231
- required: each.required,
232
- };
233
- });
234
- }
235
-
236
- swaggerResponses[res.name].headers = headers;
237
- }
238
- });
239
-
240
- return {
241
- operationId: this.getOperationId(method.name),
242
- responses: swaggerResponses,
243
- };
244
- }
245
-
246
- private buildParameter(source: Parameter): SpecificationV3.Parameter {
247
- const parameter : SpecificationV3.Parameter = {
248
- description: source.description,
249
- in: source.in as Specification.ParameterInType,
250
- name: source.name,
251
- required: source.required,
252
- schema: {
253
- default: source.default,
254
- format: undefined,
255
- },
256
- };
257
-
258
- if (source.deprecated) {
259
- parameter.deprecated = true;
260
- }
261
-
262
- const parameterType = this.getSwaggerType(source.type);
263
- if (parameterType.format) {
264
- parameter.schema.format = parameterType.format;
265
- }
266
-
267
- if (
268
- hasOwnProperty(parameterType, '$ref') &&
269
- parameterType.$ref
270
- ) {
271
- parameter.schema = parameterType as SpecificationV3.Schema;
272
- return parameter;
273
- }
274
-
275
- if (source.type.typeName === 'any') {
276
- parameter.schema.type = 'string';
277
- } else {
278
- if (parameterType.type) {
279
- parameter.schema.type = parameterType.type as Specification.DataType;
280
- }
281
- parameter.schema.items = parameterType.items;
282
- parameter.schema.enum = parameterType.enum;
283
- }
284
-
285
- this.buildFromParameterExamples(parameter, source);
286
-
287
- return parameter;
288
- }
289
-
290
- private buildFromParameterExamples(
291
- parameter: SpecificationV3.Parameter | SpecificationV3.MediaType,
292
- sourceParameter: Parameter
293
- ) {
294
- if (
295
- (Array.isArray(sourceParameter.example) && sourceParameter.example.length === 1) ||
296
- typeof sourceParameter.example === 'undefined'
297
- ) {
298
- parameter.example = Array.isArray(sourceParameter.example) && sourceParameter.example.length === 1 ? sourceParameter.example[0] : undefined;
299
- } else {
300
- parameter.examples = {};
301
- sourceParameter.example.forEach((example, index) =>
302
- Object.assign(parameter.examples, {
303
- [`Example ${index + 1}`]: { value: example } as Specification.Example,
304
- }),
305
- );
306
- }
307
- return parameter;
308
- }
309
-
310
- private buildServers() : SpecificationV3.Server[] {
311
- const url = new URL(this.config.host || 'http://localhost:3000/');
312
- let host : string = (url.host + url.pathname).replace(/([^:]\/)\/+/g, "$1");
313
- host = host.substr(-1, 1) === '/' ? host.substr(0, host.length -1) : host;
314
-
315
- return [
316
- {
317
- url: host,
318
- }
319
- ];
320
- }
321
-
322
- private buildSchema() {
323
- const schema: { [name: string]: SpecificationV3.Schema } = {};
324
- Object.keys(this.metadata.referenceTypes).map(typeName => {
325
- const referenceType = this.metadata.referenceTypes[typeName];
326
-
327
- if (referenceType.typeName === 'refObject') {
328
- const required = referenceType.properties.filter(p => p.required).map(p => p.name);
329
- schema[referenceType.refName] = {
330
- description: referenceType.description,
331
- properties: this.buildProperties(referenceType.properties),
332
- required: required && required.length > 0 ? Array.from(new Set(required)) : undefined,
333
- type: 'object',
334
- };
335
-
336
- if (referenceType.additionalProperties) {
337
- schema[referenceType.refName].additionalProperties = this.getSwaggerType(referenceType.additionalProperties);
338
- }
339
-
340
- if (referenceType.example) {
341
- schema[referenceType.refName].example = referenceType.example;
342
- }
343
- } else if (referenceType.typeName === 'refEnum') {
344
- const enumTypes = this.determineTypesUsedInEnum(referenceType.members);
345
-
346
- if (enumTypes.size === 1) {
347
- schema[referenceType.refName] = {
348
- description: referenceType.description,
349
- enum: referenceType.members,
350
- type: enumTypes.has('string') ? 'string' : 'number',
351
- };
352
- if (referenceType.memberNames !== undefined && referenceType.members.length === referenceType.memberNames.length) {
353
- schema[referenceType.refName]['x-enum-varnames'] = referenceType.memberNames;
354
- }
355
- } else {
356
- schema[referenceType.refName] = {
357
- description: referenceType.description,
358
- anyOf: [
359
- {
360
- type: 'number',
361
- enum: referenceType.members.filter(e => typeof e === 'number'),
362
- },
363
- {
364
- type: 'string',
365
- enum: referenceType.members.filter(e => typeof e === 'string'),
366
- },
367
- ],
368
- };
369
- }
370
- } else if (referenceType.typeName === 'refAlias') {
371
- const swaggerType = this.getSwaggerType(referenceType.type);
372
- const format = referenceType.format as Specification.DataFormat;
373
- const validators = Object.keys(referenceType.validators)
374
- .filter(key => {
375
- return !key.startsWith('is') && key !== 'minDate' && key !== 'maxDate';
376
- })
377
- .reduce((acc, key) => {
378
- return {
379
- ...acc,
380
- [key]: referenceType.validators[key].value,
381
- };
382
- }, {});
383
-
384
- schema[referenceType.refName] = {
385
- ...(swaggerType as SpecificationV3.Schema),
386
- default: referenceType.default || swaggerType.default,
387
- example: referenceType.example,
388
- format: format || swaggerType.format,
389
- description: referenceType.description,
390
- ...validators,
391
- };
392
- }
393
-
394
- if (referenceType.deprecated) {
395
- schema[referenceType.refName].deprecated = true;
396
- }
397
- });
398
-
399
- return schema;
400
- }
401
-
402
- protected getSwaggerTypeForIntersectionType(type: Resolver.IntersectionType) : SpecificationV3.Schema {
403
- return { allOf: type.members.map((x: Resolver.Type) => this.getSwaggerType(x)) };
404
- }
405
-
406
- protected buildProperties<T>(properties: Property[]): Record<string, SpecificationV3.Schema> {
407
- const result: { [propertyName: string]: SpecificationV3.Schema } = {};
408
-
409
- properties.forEach(property => {
410
- const swaggerType = this.getSwaggerType(property.type) as SpecificationV3.Schema;
411
- const format = property.format as Specification.DataFormat;
412
- swaggerType.description = property.description;
413
- swaggerType.example = property.example;
414
- swaggerType.format = format || swaggerType.format;
415
-
416
- if (!swaggerType.$ref) {
417
- swaggerType.default = property.default;
418
- }
419
-
420
- if (property.deprecated) {
421
- swaggerType.deprecated = true;
422
- }
423
-
424
- result[property.name] = swaggerType;
425
- });
426
-
427
- return result;
428
- }
429
-
430
- protected getSwaggerTypeForEnumType(enumType: Resolver.EnumType): SpecificationV3.Schema {
431
- const types = this.determineTypesUsedInEnum(enumType.members);
432
-
433
- if (types.size === 1) {
434
- const type = types.values().next().value;
435
- const nullable = !!enumType.members.includes(null);
436
- return { type: type, enum: enumType.members.map(member => (member === null ? null : String(member))), nullable: nullable };
437
- } else {
438
- const valuesDelimited = Array.from(types).join(',');
439
- throw new Error(`Enums can only have string or number values, but enum had ${valuesDelimited}`);
440
- }
441
- }
442
-
443
- protected getSwaggerTypeForReferenceType(referenceType: Resolver.ReferenceType): SpecificationV3.Schema {
444
- return {
445
- $ref: `#/components/schemas/${referenceType.refName}`
446
- };
447
- }
448
- }
@@ -1,129 +0,0 @@
1
- /*
2
- * Copyright (c) 2021.
3
- * Author Peter Placzek (tada5hi)
4
- * For the full copyright and license information,
5
- * view the LICENSE file that was distributed with this source code.
6
- */
7
-
8
- import {Specification} from "../type";
9
-
10
- export namespace SpecificationV3 {
11
- import BaseParameter = Specification.BaseParameter;
12
-
13
- export interface Spec extends Specification.BaseSpec {
14
- openapi: '3.0.0';
15
- servers: Server[];
16
- components: Components;
17
- paths: Paths;
18
- }
19
-
20
- // Server
21
- export interface Server {
22
- url: string;
23
- description?: string;
24
- variables?: Record<string, Variable>;
25
- }
26
-
27
- export interface Variable {
28
- enum?: string[];
29
- description?: string;
30
- default: string;
31
- }
32
-
33
- // Components
34
- export interface Components {
35
- callbacks?: { [name: string]: any };
36
- examples?: { [name: string]: Specification.Example | string };
37
- headers?: { [name: string]: any };
38
- links?: { [name: string]: any };
39
- parameters?: { [name: string]: Parameter };
40
- requestBodies?: { [name: string]: any };
41
- responses?: { [name: string]: Response };
42
- schemas?: { [name: string]: Schema };
43
- securitySchemes?: { [name: string]: Security };
44
- }
45
-
46
-
47
- // Paths
48
- export interface Paths {
49
- [key: string] : Specification.Path<Operation, Parameter>;
50
- }
51
-
52
- export type Parameter = Specification.Parameter<Schema>;
53
-
54
- export interface Operation extends Specification.BaseOperation<Parameter, Response, Security> {
55
- requestBody?: RequestBody;
56
- [key: string]: unknown;
57
- }
58
-
59
- export interface Response extends Specification.BaseResponse {
60
- content?: { [name: string]: Schema & Specification.Examples };
61
- headers?: { [name: string]: Header };
62
- }
63
-
64
- export type Header = Partial<Pick<BaseParameter<Schema>, 'name' | 'in'>> & Omit<BaseParameter<Schema>, 'name' | 'in'>;
65
-
66
- export interface RequestBody {
67
- content: { [name: string]: MediaType };
68
- description?: string;
69
- required?: boolean;
70
- }
71
-
72
- export interface MediaType {
73
- schema?: Schema;
74
- example?: unknown;
75
- examples?: { [name: string]: Specification.Example | string };
76
- encoding?: { [name: string]: any };
77
- }
78
-
79
- // tslint:disable-next-line:no-shadowed-variable
80
- export interface Schema extends Specification.BaseSchema<Schema> {
81
- nullable?: boolean;
82
- anyOf?: Schema[];
83
- allOf?: Schema[];
84
- deprecated?: boolean;
85
- }
86
-
87
- // tslint:disable-next-line:no-shadowed-variable
88
- export interface BasicSecurity extends Specification.BaseSecurity {
89
- type: 'http';
90
- schema: 'basic';
91
- }
92
-
93
- export interface OAuth2Security extends Specification.BaseSecurity {
94
- type: 'oauth2';
95
- flows: {
96
- implicit?: OAuth2ImplicitFlow,
97
- password?: OAuth2PasswordFlow,
98
- authorizationCode?: OAuth2AuthorizationCodeFlow,
99
- clientCredentials?: OAuth2ClientCredentialsFlow
100
- };
101
- }
102
-
103
- export interface Oauth2BaseFlow {
104
- scopes?: Record<string, string>;
105
- refreshUrl?: string;
106
- }
107
-
108
- export interface OAuth2ImplicitFlow extends Oauth2BaseFlow{
109
- authorizationUrl: string;
110
- }
111
-
112
- export interface OAuth2PasswordFlow extends Oauth2BaseFlow{
113
- tokenUrl: string;
114
- }
115
-
116
- export interface OAuth2AuthorizationCodeFlow extends Oauth2BaseFlow{
117
- authorizationUrl: string;
118
- tokenUrl: string;
119
- }
120
-
121
- export interface OAuth2ClientCredentialsFlow extends Oauth2BaseFlow{
122
- tokenUrl: string;
123
- }
124
-
125
- export type Security =
126
- BasicSecurity |
127
- OAuth2Security |
128
- Specification.ApiKeySecurity;
129
- }
package/src/type.ts DELETED
@@ -1,14 +0,0 @@
1
- /*
2
- * Copyright (c) 2021.
3
- * Author Peter Placzek (tada5hi)
4
- * For the full copyright and license information,
5
- * view the LICENSE file that was distributed with this source code.
6
- */
7
-
8
- export type SwaggerDocFormatType = 'yaml' | 'json';
9
-
10
- export interface SwaggerDocFormatData {
11
- path: string;
12
- name: string;
13
- content?: string;
14
- }
package/src/utils.ts DELETED
@@ -1,28 +0,0 @@
1
- /*
2
- * Copyright (c) 2021.
3
- * Author Peter Placzek (tada5hi)
4
- * For the full copyright and license information,
5
- * view the LICENSE file that was distributed with this source code.
6
- */
7
-
8
- import {CompilerOptions} from 'typescript';
9
- import {Config as MetadataConfig, createMetadataGenerator} from "@trapi/metadata";
10
- import {createSpecGenerator, Specification} from "./specification";
11
- import {SwaggerDocFormatData, SwaggerDocFormatType} from "./type";
12
-
13
- export async function generateDocumentation(
14
- config: {
15
- metadata: MetadataConfig,
16
- swagger: Specification.Config
17
- },
18
- tsConfig?: CompilerOptions | boolean
19
- ): Promise<Record<SwaggerDocFormatType, SwaggerDocFormatData>> {
20
- const metadataGenerator = createMetadataGenerator(config.metadata, tsConfig);
21
-
22
- const metadata = metadataGenerator.generate();
23
-
24
- const specGenerator = createSpecGenerator(metadata, config.swagger);
25
-
26
- specGenerator.build();
27
- return await specGenerator.save();
28
- }