@visulima/jsdoc-open-api 1.0.0
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/CHANGELOG.md +19 -0
- package/LICENSE.md +0 -0
- package/README.md +226 -0
- package/bin/index.js +188 -0
- package/dist/index.d.ts +303 -0
- package/dist/index.js +633 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +633 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +135 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,633 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }// src/util/object-merge.ts
|
|
2
|
+
function objectMerge(a, b) {
|
|
3
|
+
Object.keys(b).forEach((key) => {
|
|
4
|
+
if (a[key] === void 0) {
|
|
5
|
+
a[key] = {
|
|
6
|
+
...b[key]
|
|
7
|
+
};
|
|
8
|
+
} else {
|
|
9
|
+
Object.keys(b[key]).forEach((subKey) => {
|
|
10
|
+
a[key][subKey] = {
|
|
11
|
+
...a[key][subKey],
|
|
12
|
+
...b[key][subKey]
|
|
13
|
+
};
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
var object_merge_default = objectMerge;
|
|
19
|
+
|
|
20
|
+
// src/spec-builder.ts
|
|
21
|
+
var SpecBuilder = class {
|
|
22
|
+
constructor(baseDefinition) {
|
|
23
|
+
this.openapi = baseDefinition.openapi;
|
|
24
|
+
this.info = baseDefinition.info;
|
|
25
|
+
this.servers = baseDefinition.servers;
|
|
26
|
+
this.paths = baseDefinition.paths || {};
|
|
27
|
+
this.components = baseDefinition.components;
|
|
28
|
+
this.security = baseDefinition.security;
|
|
29
|
+
this.tags = baseDefinition.tags;
|
|
30
|
+
this.externalDocs = baseDefinition.externalDocs;
|
|
31
|
+
}
|
|
32
|
+
addData(parsedFile) {
|
|
33
|
+
parsedFile.forEach((file) => {
|
|
34
|
+
const { paths, components, ...rest } = file;
|
|
35
|
+
object_merge_default(this, {
|
|
36
|
+
paths,
|
|
37
|
+
components
|
|
38
|
+
});
|
|
39
|
+
Object.entries(rest).forEach(([key, value]) => {
|
|
40
|
+
this[key] = value;
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
var spec_builder_default = SpecBuilder;
|
|
46
|
+
|
|
47
|
+
// src/parse-file.ts
|
|
48
|
+
var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs);
|
|
49
|
+
var _path = require('path'); var _path2 = _interopRequireDefault(_path);
|
|
50
|
+
var _yaml = require('yaml'); var _yaml2 = _interopRequireDefault(_yaml);
|
|
51
|
+
|
|
52
|
+
// src/util/yaml-loc.ts
|
|
53
|
+
function yamlLoc(string) {
|
|
54
|
+
const split = string.split(/\r\n|\r|\n/);
|
|
55
|
+
const filtered = split.filter((line) => {
|
|
56
|
+
if (/^\s*(#\s*.*)?$/.test(line)) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
return line.trim().length > 0;
|
|
60
|
+
});
|
|
61
|
+
return filtered.length;
|
|
62
|
+
}
|
|
63
|
+
var yaml_loc_default = yamlLoc;
|
|
64
|
+
|
|
65
|
+
// src/parse-file.ts
|
|
66
|
+
var ALLOWED_KEYS = /* @__PURE__ */ new Set(["openapi", "info", "servers", "security", "tags", "externalDocs", "components", "paths"]);
|
|
67
|
+
var ParseError = class extends Error {
|
|
68
|
+
};
|
|
69
|
+
var parseFile = (file, commentsToOpenApi3, verbose) => {
|
|
70
|
+
const fileContent = _fs2.default.readFileSync(file, { encoding: "utf8" });
|
|
71
|
+
const extension = _path2.default.extname(file);
|
|
72
|
+
if (extension === ".yaml" || extension === ".yml") {
|
|
73
|
+
const spec = _yaml2.default.parse(fileContent);
|
|
74
|
+
const invalidKeys = Object.keys(spec).filter((key) => !ALLOWED_KEYS.has(key));
|
|
75
|
+
if (invalidKeys.length > 0) {
|
|
76
|
+
const error = new ParseError(`Unexpected keys: ${invalidKeys.join(", ")}`);
|
|
77
|
+
error.filePath = file;
|
|
78
|
+
throw error;
|
|
79
|
+
}
|
|
80
|
+
if (Object.keys(spec).some((key) => ALLOWED_KEYS.has(key))) {
|
|
81
|
+
const loc = yaml_loc_default(fileContent);
|
|
82
|
+
return [{ spec, loc }];
|
|
83
|
+
}
|
|
84
|
+
return [];
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
return commentsToOpenApi3(fileContent, verbose);
|
|
88
|
+
} catch (error) {
|
|
89
|
+
error.filePath = file;
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
var parse_file_default = parseFile;
|
|
94
|
+
|
|
95
|
+
// src/webpack/swagger-compiler-plugin.ts
|
|
96
|
+
var _swaggerparser = require('@apidevtools/swagger-parser'); var _swaggerparser2 = _interopRequireDefault(_swaggerparser);
|
|
97
|
+
var _readdir = require('@visulima/readdir');
|
|
98
|
+
var _debug2 = require('debug'); var _debug3 = _interopRequireDefault(_debug2);
|
|
99
|
+
var _process = require('process');
|
|
100
|
+
|
|
101
|
+
// src/jsdoc/comments-to-open-api.ts
|
|
102
|
+
var _commentparser = require('comment-parser');
|
|
103
|
+
var _lodashmergewith = require('lodash.mergewith'); var _lodashmergewith2 = _interopRequireDefault(_lodashmergewith);
|
|
104
|
+
|
|
105
|
+
// src/util/customizer.ts
|
|
106
|
+
var customizer = (objectValue, sourceValue) => {
|
|
107
|
+
if (Array.isArray(objectValue)) {
|
|
108
|
+
return [...objectValue, ...sourceValue];
|
|
109
|
+
}
|
|
110
|
+
return void 0;
|
|
111
|
+
};
|
|
112
|
+
var customizer_default = customizer;
|
|
113
|
+
|
|
114
|
+
// src/jsdoc/comments-to-open-api.ts
|
|
115
|
+
function fixSecurityObject(thing) {
|
|
116
|
+
if (thing.security) {
|
|
117
|
+
thing.security = Object.keys(thing.security).map((s) => {
|
|
118
|
+
return {
|
|
119
|
+
[s]: thing.security[s]
|
|
120
|
+
};
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
var primitiveTypes = /* @__PURE__ */ new Set(["integer", "number", "string", "boolean", "object", "array"]);
|
|
125
|
+
var formatMap = {
|
|
126
|
+
int32: "integer",
|
|
127
|
+
int64: "integer",
|
|
128
|
+
float: "number",
|
|
129
|
+
double: "number",
|
|
130
|
+
date: "string",
|
|
131
|
+
"date-time": "string",
|
|
132
|
+
password: "string",
|
|
133
|
+
byte: "string",
|
|
134
|
+
binary: "string"
|
|
135
|
+
};
|
|
136
|
+
function parseDescription(tag) {
|
|
137
|
+
const rawType = tag.type;
|
|
138
|
+
const isArray = rawType && rawType.endsWith("[]");
|
|
139
|
+
let parsedType;
|
|
140
|
+
if (rawType) {
|
|
141
|
+
parsedType = rawType.replace(/\[]$/, "");
|
|
142
|
+
}
|
|
143
|
+
const isPrimitive = primitiveTypes.has(parsedType);
|
|
144
|
+
const isFormat = Object.keys(formatMap).includes(parsedType);
|
|
145
|
+
let defaultValue;
|
|
146
|
+
if (tag.default) {
|
|
147
|
+
switch (parsedType) {
|
|
148
|
+
case "integer":
|
|
149
|
+
case "int32":
|
|
150
|
+
case "int64": {
|
|
151
|
+
defaultValue = Number.parseInt(tag.default, 10);
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
case "number":
|
|
155
|
+
case "double":
|
|
156
|
+
case "float": {
|
|
157
|
+
defaultValue = Number.parseFloat(tag.default);
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
default: {
|
|
161
|
+
defaultValue = tag.default;
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
let rootType;
|
|
167
|
+
if (isPrimitive) {
|
|
168
|
+
rootType = { type: parsedType, default: defaultValue };
|
|
169
|
+
} else if (isFormat) {
|
|
170
|
+
rootType = {
|
|
171
|
+
type: formatMap[parsedType],
|
|
172
|
+
format: parsedType,
|
|
173
|
+
default: defaultValue
|
|
174
|
+
};
|
|
175
|
+
} else {
|
|
176
|
+
rootType = { $ref: `#/components/schemas/${parsedType}` };
|
|
177
|
+
}
|
|
178
|
+
let schema = isArray ? {
|
|
179
|
+
type: "array",
|
|
180
|
+
items: {
|
|
181
|
+
...rootType
|
|
182
|
+
}
|
|
183
|
+
} : {
|
|
184
|
+
...rootType
|
|
185
|
+
};
|
|
186
|
+
if (parsedType === void 0) {
|
|
187
|
+
schema = void 0;
|
|
188
|
+
}
|
|
189
|
+
let description = tag.description.trim().replace(/^- /, "");
|
|
190
|
+
if (description === "") {
|
|
191
|
+
description = void 0;
|
|
192
|
+
}
|
|
193
|
+
return {
|
|
194
|
+
name: tag.name,
|
|
195
|
+
description,
|
|
196
|
+
required: !tag.optional,
|
|
197
|
+
schema,
|
|
198
|
+
rawType
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
function tagsToObjects(tags, verbose) {
|
|
202
|
+
return tags.map((tag) => {
|
|
203
|
+
const parsedResponse = parseDescription(tag);
|
|
204
|
+
let nameAndDescription = "";
|
|
205
|
+
if (parsedResponse.name) {
|
|
206
|
+
nameAndDescription += parsedResponse.name;
|
|
207
|
+
}
|
|
208
|
+
if (parsedResponse.description) {
|
|
209
|
+
nameAndDescription += ` ${parsedResponse.description.trim()}`;
|
|
210
|
+
}
|
|
211
|
+
switch (tag.tag) {
|
|
212
|
+
case "operationId":
|
|
213
|
+
case "summary":
|
|
214
|
+
case "description": {
|
|
215
|
+
return { [tag.tag]: nameAndDescription };
|
|
216
|
+
}
|
|
217
|
+
case "deprecated": {
|
|
218
|
+
return { deprecated: true };
|
|
219
|
+
}
|
|
220
|
+
case "externalDocs": {
|
|
221
|
+
return {
|
|
222
|
+
externalDocs: {
|
|
223
|
+
url: parsedResponse.name,
|
|
224
|
+
description: parsedResponse.description
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
case "server": {
|
|
229
|
+
return {
|
|
230
|
+
servers: [
|
|
231
|
+
{
|
|
232
|
+
url: parsedResponse.name,
|
|
233
|
+
description: parsedResponse.description
|
|
234
|
+
}
|
|
235
|
+
]
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
case "tag": {
|
|
239
|
+
return { tags: [nameAndDescription] };
|
|
240
|
+
}
|
|
241
|
+
case "cookieParam":
|
|
242
|
+
case "headerParam":
|
|
243
|
+
case "queryParam":
|
|
244
|
+
case "pathParam": {
|
|
245
|
+
return {
|
|
246
|
+
parameters: [
|
|
247
|
+
{
|
|
248
|
+
name: parsedResponse.name,
|
|
249
|
+
in: tag.tag.replace(/Param$/, ""),
|
|
250
|
+
description: parsedResponse.description,
|
|
251
|
+
required: parsedResponse.required,
|
|
252
|
+
schema: parsedResponse.schema
|
|
253
|
+
}
|
|
254
|
+
]
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
case "bodyContent": {
|
|
258
|
+
return {
|
|
259
|
+
requestBody: {
|
|
260
|
+
content: {
|
|
261
|
+
[parsedResponse.name.replace("*\\/*", "*/*")]: {
|
|
262
|
+
schema: parsedResponse.schema
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
case "bodyExample": {
|
|
269
|
+
const [contentType, example] = parsedResponse.name.split(".");
|
|
270
|
+
return {
|
|
271
|
+
requestBody: {
|
|
272
|
+
content: {
|
|
273
|
+
[contentType]: {
|
|
274
|
+
examples: {
|
|
275
|
+
[example]: {
|
|
276
|
+
$ref: `#/components/examples/${parsedResponse.rawType}`
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
case "bodyDescription": {
|
|
285
|
+
return { requestBody: { description: nameAndDescription } };
|
|
286
|
+
}
|
|
287
|
+
case "bodyRequired": {
|
|
288
|
+
return { requestBody: { required: true } };
|
|
289
|
+
}
|
|
290
|
+
case "response": {
|
|
291
|
+
return {
|
|
292
|
+
responses: {
|
|
293
|
+
[parsedResponse.name]: {
|
|
294
|
+
description: parsedResponse.description
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
case "callback": {
|
|
300
|
+
return {
|
|
301
|
+
callbacks: {
|
|
302
|
+
[parsedResponse.name]: {
|
|
303
|
+
$ref: `#/components/callbacks/${parsedResponse.rawType}`
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
case "responseContent": {
|
|
309
|
+
const [status, contentType] = parsedResponse.name.split(".");
|
|
310
|
+
return {
|
|
311
|
+
responses: {
|
|
312
|
+
[status]: {
|
|
313
|
+
content: {
|
|
314
|
+
[contentType]: {
|
|
315
|
+
schema: parsedResponse.schema
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
case "responseHeaderComponent": {
|
|
323
|
+
const [status, header] = parsedResponse.name.split(".");
|
|
324
|
+
return {
|
|
325
|
+
responses: {
|
|
326
|
+
[status]: {
|
|
327
|
+
headers: {
|
|
328
|
+
[header]: {
|
|
329
|
+
$ref: `#/components/headers/${parsedResponse.rawType}`
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
case "responseHeader": {
|
|
337
|
+
const [status, header] = parsedResponse.name.split(".");
|
|
338
|
+
return {
|
|
339
|
+
responses: {
|
|
340
|
+
[status]: {
|
|
341
|
+
headers: {
|
|
342
|
+
[header]: {
|
|
343
|
+
description: parsedResponse.description,
|
|
344
|
+
schema: parsedResponse.schema
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
case "responseExample": {
|
|
352
|
+
const [status, contentType, example] = parsedResponse.name.split(".");
|
|
353
|
+
return {
|
|
354
|
+
responses: {
|
|
355
|
+
[status]: {
|
|
356
|
+
content: {
|
|
357
|
+
[contentType]: {
|
|
358
|
+
examples: {
|
|
359
|
+
[example]: {
|
|
360
|
+
$ref: `#/components/examples/${parsedResponse.rawType}`
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
}
|
|
369
|
+
case "responseLink": {
|
|
370
|
+
const [status, link] = parsedResponse.name.split(".");
|
|
371
|
+
return {
|
|
372
|
+
responses: {
|
|
373
|
+
[status]: {
|
|
374
|
+
links: {
|
|
375
|
+
[link]: {
|
|
376
|
+
$ref: `#/components/links/${parsedResponse.rawType}`
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
case "bodyComponent": {
|
|
384
|
+
return {
|
|
385
|
+
requestBody: {
|
|
386
|
+
$ref: `#/components/requestBodies/${parsedResponse.rawType}`
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
case "responseComponent": {
|
|
391
|
+
return {
|
|
392
|
+
responses: {
|
|
393
|
+
[parsedResponse.name]: {
|
|
394
|
+
$ref: `#/components/responses/${parsedResponse.rawType}`
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
case "paramComponent": {
|
|
400
|
+
return {
|
|
401
|
+
parameters: [{ $ref: `#/components/parameters/${parsedResponse.rawType}` }]
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
case "security": {
|
|
405
|
+
const [security, scopeItem] = parsedResponse.name.split(".");
|
|
406
|
+
let scope = [];
|
|
407
|
+
if (scopeItem) {
|
|
408
|
+
scope = [scopeItem];
|
|
409
|
+
}
|
|
410
|
+
return {
|
|
411
|
+
security: { [security]: scope }
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
default: {
|
|
415
|
+
return {};
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
var commentsToOpenApi = (fileContents, verbose) => {
|
|
421
|
+
const openAPIRegex = /^(GET|PUT|POST|DELETE|OPTIONS|HEAD|PATCH|TRACE) \/.*$/;
|
|
422
|
+
const jsDocumentComments = _commentparser.parse.call(void 0, fileContents, { spacing: "preserve" });
|
|
423
|
+
return jsDocumentComments.filter((comment) => openAPIRegex.test(comment.description.trim())).map((comment) => {
|
|
424
|
+
const loc = comment.tags.length + 1;
|
|
425
|
+
const result = _lodashmergewith2.default.call(void 0, {}, ...tagsToObjects(comment.tags, verbose), customizer_default);
|
|
426
|
+
fixSecurityObject(result);
|
|
427
|
+
const [method, path2] = comment.description.split(" ");
|
|
428
|
+
const pathsObject = {
|
|
429
|
+
[path2.trim()]: {
|
|
430
|
+
[method.toLowerCase().trim()]: {
|
|
431
|
+
...result
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
const spec = JSON.parse(JSON.stringify({ paths: pathsObject }));
|
|
436
|
+
return {
|
|
437
|
+
spec,
|
|
438
|
+
loc
|
|
439
|
+
};
|
|
440
|
+
});
|
|
441
|
+
};
|
|
442
|
+
var comments_to_open_api_default = commentsToOpenApi;
|
|
443
|
+
|
|
444
|
+
// src/swagger-jsdoc/comments-to-open-api.ts
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
|
|
449
|
+
// src/swagger-jsdoc/utils.ts
|
|
450
|
+
|
|
451
|
+
var mergeDeep = (first, second) => _lodashmergewith2.default.call(void 0, {}, first, second, (a, b) => b === null ? a : void 0);
|
|
452
|
+
var hasEmptyProperty = (object) => Object.keys(object).map((key) => object[key]).every((keyObject) => typeof keyObject === "object" && Object.keys(keyObject).every((key) => !(key in keyObject)));
|
|
453
|
+
var isTagPresentInTags = (tag, tags) => tags.some((targetTag) => tag.name === targetTag.name);
|
|
454
|
+
var getSwaggerVersionFromSpec = (tag) => {
|
|
455
|
+
switch (tag.tag) {
|
|
456
|
+
case "openapi": {
|
|
457
|
+
return "v3";
|
|
458
|
+
}
|
|
459
|
+
case "asyncapi": {
|
|
460
|
+
return "v4";
|
|
461
|
+
}
|
|
462
|
+
case "swagger": {
|
|
463
|
+
return "v2";
|
|
464
|
+
}
|
|
465
|
+
default: {
|
|
466
|
+
return "v2";
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
// src/swagger-jsdoc/organize-swagger-object.ts
|
|
472
|
+
var organizeSwaggerObject = (swaggerObject, annotation, property) => {
|
|
473
|
+
if (property === "x-webhooks") {
|
|
474
|
+
swaggerObject[property] = annotation[property];
|
|
475
|
+
}
|
|
476
|
+
if (property.startsWith("x-")) {
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
const commonProperties = [
|
|
480
|
+
"components",
|
|
481
|
+
"consumes",
|
|
482
|
+
"produces",
|
|
483
|
+
"paths",
|
|
484
|
+
"schemas",
|
|
485
|
+
"securityDefinitions",
|
|
486
|
+
"responses",
|
|
487
|
+
"parameters",
|
|
488
|
+
"definitions",
|
|
489
|
+
"channels"
|
|
490
|
+
];
|
|
491
|
+
if (commonProperties.includes(property)) {
|
|
492
|
+
Object.keys(annotation[property]).forEach((definition) => {
|
|
493
|
+
swaggerObject[property][definition] = mergeDeep(swaggerObject[property][definition], annotation[property][definition]);
|
|
494
|
+
});
|
|
495
|
+
} else if (property === "tags") {
|
|
496
|
+
const { tags } = annotation;
|
|
497
|
+
if (Array.isArray(tags)) {
|
|
498
|
+
tags.forEach((tag) => {
|
|
499
|
+
if (!isTagPresentInTags(tag, swaggerObject.tags)) {
|
|
500
|
+
swaggerObject.tags.push(tag);
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
} else if (!isTagPresentInTags(tags, swaggerObject.tags)) {
|
|
504
|
+
swaggerObject.tags.push(tags);
|
|
505
|
+
}
|
|
506
|
+
} else if (property === "security") {
|
|
507
|
+
const { security } = annotation;
|
|
508
|
+
swaggerObject.security = security;
|
|
509
|
+
} else if (property.startsWith("/")) {
|
|
510
|
+
swaggerObject.paths[property] = mergeDeep(swaggerObject.paths[property], annotation[property]);
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
var organize_swagger_object_default = organizeSwaggerObject;
|
|
514
|
+
|
|
515
|
+
// src/swagger-jsdoc/comments-to-open-api.ts
|
|
516
|
+
var specificationTemplate = {
|
|
517
|
+
v2: ["paths", "definitions", "responses", "parameters", "securityDefinitions"],
|
|
518
|
+
v3: ["paths", "definitions", "responses", "parameters", "securityDefinitions", "components"],
|
|
519
|
+
v4: ["components", "channels"]
|
|
520
|
+
};
|
|
521
|
+
var tagsToObjects2 = (specs, verbose) => specs.map((spec) => {
|
|
522
|
+
if ((spec.tag === "openapi" || spec.tag === "swagger" || spec.tag === "asyncapi") && spec.description !== "") {
|
|
523
|
+
const parsed = _yaml2.default.parseDocument(spec.description);
|
|
524
|
+
if (parsed.errors && parsed.errors.length > 0) {
|
|
525
|
+
parsed.errors.map((error) => {
|
|
526
|
+
const newError = error;
|
|
527
|
+
newError.annotation = spec.description;
|
|
528
|
+
return newError;
|
|
529
|
+
});
|
|
530
|
+
let errorString = "Error parsing YAML in @openapi spec:";
|
|
531
|
+
errorString += verbose ? parsed.errors.map((error) => {
|
|
532
|
+
var _a;
|
|
533
|
+
return `${error.toString()}
|
|
534
|
+
Imbedded within:
|
|
535
|
+
\`\`\`
|
|
536
|
+
${(_a = error == null ? void 0 : error.annotation) == null ? void 0 : _a.replace(/\n/g, "\n ")}
|
|
537
|
+
\`\`\``;
|
|
538
|
+
}).join("\n") : parsed.errors.map((error) => error.toString()).join("\n");
|
|
539
|
+
throw new Error(errorString);
|
|
540
|
+
}
|
|
541
|
+
const parsedDocument = parsed.toJSON();
|
|
542
|
+
const specification = {
|
|
543
|
+
tags: []
|
|
544
|
+
};
|
|
545
|
+
specificationTemplate[getSwaggerVersionFromSpec(spec)].forEach((property) => {
|
|
546
|
+
specification[property] = specification[property] || {};
|
|
547
|
+
});
|
|
548
|
+
Object.keys(parsedDocument).forEach((property) => {
|
|
549
|
+
organize_swagger_object_default(specification, parsedDocument, property);
|
|
550
|
+
});
|
|
551
|
+
return specification;
|
|
552
|
+
}
|
|
553
|
+
return {};
|
|
554
|
+
});
|
|
555
|
+
var commentsToOpenApi2 = (fileContents, verbose) => {
|
|
556
|
+
const jsDocumentComments = _commentparser.parse.call(void 0, fileContents, { spacing: "preserve" });
|
|
557
|
+
return jsDocumentComments.map((comment) => {
|
|
558
|
+
const loc = comment.tags.length + 1;
|
|
559
|
+
const result = _lodashmergewith2.default.call(void 0, {}, ...tagsToObjects2(comment.tags, verbose), customizer_default);
|
|
560
|
+
["definitions", "responses", "parameters", "securityDefinitions", "components", "tags"].forEach((property) => {
|
|
561
|
+
if (typeof result[property] !== "undefined" && hasEmptyProperty(result[property])) {
|
|
562
|
+
delete result[property];
|
|
563
|
+
}
|
|
564
|
+
});
|
|
565
|
+
const spec = JSON.parse(JSON.stringify(result));
|
|
566
|
+
return {
|
|
567
|
+
spec,
|
|
568
|
+
loc
|
|
569
|
+
};
|
|
570
|
+
});
|
|
571
|
+
};
|
|
572
|
+
var comments_to_open_api_default2 = commentsToOpenApi2;
|
|
573
|
+
|
|
574
|
+
// src/webpack/swagger-compiler-plugin.ts
|
|
575
|
+
var debug = _debug3.default.call(void 0, "visulima:jsdoc-open-api:swagger-compiler-plugin");
|
|
576
|
+
var SwaggerCompilerPlugin = class {
|
|
577
|
+
constructor(assetsPath, sources, swaggerDefinition, options) {
|
|
578
|
+
this.assetsPath = assetsPath;
|
|
579
|
+
this.swaggerDefinition = swaggerDefinition;
|
|
580
|
+
this.sources = sources;
|
|
581
|
+
this.verbose = options.verbose || false;
|
|
582
|
+
this.ignore = options.ignore || [];
|
|
583
|
+
}
|
|
584
|
+
apply(compiler) {
|
|
585
|
+
compiler.hooks.make.tapAsync("SwaggerCompilerPlugin", async (compilation, callback) => {
|
|
586
|
+
console.log("Build paused");
|
|
587
|
+
console.log("switching to swagger build");
|
|
588
|
+
const spec = new spec_builder_default(this.swaggerDefinition);
|
|
589
|
+
for await (const dir of this.sources) {
|
|
590
|
+
const files = await _readdir.collect.call(void 0, dir, {
|
|
591
|
+
skip: [...this.ignore, "node_modules/**"]
|
|
592
|
+
});
|
|
593
|
+
if (this.verbose) {
|
|
594
|
+
console.log(`Found ${files.length} files in ${dir}`);
|
|
595
|
+
console.log(files);
|
|
596
|
+
}
|
|
597
|
+
files.forEach((file) => {
|
|
598
|
+
debug(`Parsing file ${file}`);
|
|
599
|
+
const parsedJsDocumentFile = parse_file_default(file, comments_to_open_api_default, this.verbose);
|
|
600
|
+
spec.addData(parsedJsDocumentFile.map((item) => item.spec));
|
|
601
|
+
const parsedSwaggerJsDocumentFile = parse_file_default(file, comments_to_open_api_default2, this.verbose);
|
|
602
|
+
spec.addData(parsedSwaggerJsDocumentFile.map((item) => item.spec));
|
|
603
|
+
});
|
|
604
|
+
}
|
|
605
|
+
try {
|
|
606
|
+
await _swaggerparser2.default.validate(JSON.parse(JSON.stringify(spec)));
|
|
607
|
+
} catch (error) {
|
|
608
|
+
console.error(error.toJSON());
|
|
609
|
+
_process.exit.call(void 0, 1);
|
|
610
|
+
}
|
|
611
|
+
compilation.assets[this.assetsPath] = {
|
|
612
|
+
source() {
|
|
613
|
+
return JSON.stringify(spec, null, 2);
|
|
614
|
+
},
|
|
615
|
+
size() {
|
|
616
|
+
return Object.keys(spec).length;
|
|
617
|
+
}
|
|
618
|
+
};
|
|
619
|
+
console.log("switching back to normal build");
|
|
620
|
+
callback();
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
var swagger_compiler_plugin_default = SwaggerCompilerPlugin;
|
|
625
|
+
|
|
626
|
+
|
|
627
|
+
|
|
628
|
+
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
exports.SpecBuilder = spec_builder_default; exports.SwaggerCompilerPlugin = swagger_compiler_plugin_default; exports.jsDocumentCommentsToOpenApi = comments_to_open_api_default; exports.parseFile = parse_file_default; exports.swaggerJsDocumentCommentsToOpenApi = comments_to_open_api_default2; exports.yamlLoc = yaml_loc_default;
|
|
633
|
+
//# sourceMappingURL=index.js.map
|