@visulima/jsdoc-open-api 2.0.95 → 3.0.0-alpha.10

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 (111) hide show
  1. package/CHANGELOG.md +158 -0
  2. package/LICENSE.md +1 -1
  3. package/README.md +33 -28
  4. package/dist/cli/command/generate-command.d.cts +7 -0
  5. package/dist/cli/command/generate-command.d.mts +7 -0
  6. package/dist/cli/command/generate-command.d.ts +7 -0
  7. package/dist/cli/command/init-command.d.cts +2 -0
  8. package/dist/cli/command/init-command.d.mts +2 -0
  9. package/dist/cli/command/init-command.d.ts +2 -0
  10. package/dist/cli/commander/command/generate-command.d.cts +3 -0
  11. package/dist/cli/commander/command/generate-command.d.mts +3 -0
  12. package/dist/cli/commander/command/generate-command.d.ts +3 -0
  13. package/dist/cli/commander/command/init-command.d.cts +3 -0
  14. package/dist/cli/commander/command/init-command.d.mts +3 -0
  15. package/dist/cli/commander/command/init-command.d.ts +3 -0
  16. package/dist/cli/commander/index.cjs +11 -0
  17. package/dist/cli/commander/index.d.cts +2 -0
  18. package/dist/cli/commander/index.d.mts +2 -7
  19. package/dist/cli/commander/index.d.ts +2 -7
  20. package/dist/cli/commander/index.mjs +2 -30
  21. package/dist/cli/index.cjs +11 -0
  22. package/dist/cli/index.d.cts +2 -0
  23. package/dist/cli/index.d.mts +2 -10
  24. package/dist/cli/index.d.ts +2 -10
  25. package/dist/cli/index.mjs +2 -4
  26. package/dist/constants.d.cts +1 -0
  27. package/dist/constants.d.mts +1 -0
  28. package/dist/constants.d.ts +1 -0
  29. package/dist/exported.d.cts +198 -0
  30. package/dist/exported.d.mts +198 -0
  31. package/dist/exported.d.ts +198 -0
  32. package/dist/index.cjs +19 -0
  33. package/dist/index.d.cts +7 -0
  34. package/dist/index.d.mts +7 -248
  35. package/dist/index.d.ts +7 -248
  36. package/dist/index.mjs +6 -85
  37. package/dist/jsdoc/comments-to-open-api.d.cts +6 -0
  38. package/dist/jsdoc/comments-to-open-api.d.mts +6 -0
  39. package/dist/jsdoc/comments-to-open-api.d.ts +6 -0
  40. package/dist/packem_shared/SpecBuilder-B7YiF7zR.mjs +61 -0
  41. package/dist/packem_shared/SpecBuilder-CCESkmm5.cjs +63 -0
  42. package/dist/packem_shared/SwaggerCompilerPlugin-BkYJzU4f.cjs +88 -0
  43. package/dist/packem_shared/SwaggerCompilerPlugin-DZ7tIJ8x.mjs +86 -0
  44. package/dist/packem_shared/customizer-CoMXMU7a.mjs +8 -0
  45. package/dist/packem_shared/customizer-DDFwFqJl.cjs +10 -0
  46. package/dist/packem_shared/generateCommand-DRMkfIle.mjs +15 -0
  47. package/dist/packem_shared/generateCommand-MwnCNgEE.cjs +82 -0
  48. package/dist/packem_shared/generateCommand-RY4QFtm7.cjs +17 -0
  49. package/dist/packem_shared/generateCommand-a9_RAbug.mjs +80 -0
  50. package/dist/packem_shared/initCommand-B6Z9EXHP.mjs +15 -0
  51. package/dist/packem_shared/initCommand-Ch-72dKZ.cjs +65 -0
  52. package/dist/packem_shared/initCommand-D3yVEMwO.cjs +17 -0
  53. package/dist/packem_shared/initCommand-zE4VRDGW.mjs +63 -0
  54. package/dist/packem_shared/jsDocumentCommentsToOpenApi-C7yMeXJ5.cjs +337 -0
  55. package/dist/packem_shared/jsDocumentCommentsToOpenApi-DtrIZ2lK.mjs +331 -0
  56. package/dist/packem_shared/parseFile-BE-sKiRK.mjs +35 -0
  57. package/dist/packem_shared/parseFile-Dk7Bw7lt.cjs +42 -0
  58. package/dist/packem_shared/swaggerJsDocumentCommentsToOpenApi-B7g9rVr5.mjs +131 -0
  59. package/dist/packem_shared/swaggerJsDocumentCommentsToOpenApi-BuB7eE94.cjs +138 -0
  60. package/dist/packem_shared/validate-DZHaKH07.mjs +30 -0
  61. package/dist/packem_shared/validate-FKieC3ln.cjs +37 -0
  62. package/dist/packem_shared/yamlLoc-C7iHWvdq.mjs +14 -0
  63. package/dist/packem_shared/yamlLoc-CEvBiR4K.cjs +16 -0
  64. package/dist/parse-file.d.cts +9 -0
  65. package/dist/parse-file.d.mts +9 -0
  66. package/dist/parse-file.d.ts +9 -0
  67. package/dist/spec-builder.d.cts +14 -0
  68. package/dist/spec-builder.d.mts +14 -0
  69. package/dist/spec-builder.d.ts +14 -0
  70. package/dist/swagger-jsdoc/comments-to-open-api.d.cts +6 -0
  71. package/dist/swagger-jsdoc/comments-to-open-api.d.mts +6 -0
  72. package/dist/swagger-jsdoc/comments-to-open-api.d.ts +6 -0
  73. package/dist/swagger-jsdoc/organize-swagger-object.d.cts +7 -0
  74. package/dist/swagger-jsdoc/organize-swagger-object.d.mts +7 -0
  75. package/dist/swagger-jsdoc/organize-swagger-object.d.ts +7 -0
  76. package/dist/swagger-jsdoc/utils.d.cts +22 -0
  77. package/dist/swagger-jsdoc/utils.d.mts +22 -0
  78. package/dist/swagger-jsdoc/utils.d.ts +22 -0
  79. package/dist/util/customizer.d.cts +2 -0
  80. package/dist/util/customizer.d.mts +2 -0
  81. package/dist/util/customizer.d.ts +2 -0
  82. package/dist/util/object-merge.d.cts +2 -0
  83. package/dist/util/object-merge.d.mts +2 -0
  84. package/dist/util/object-merge.d.ts +2 -0
  85. package/dist/util/yaml-loc.d.cts +2 -0
  86. package/dist/util/yaml-loc.d.mts +2 -0
  87. package/dist/util/yaml-loc.d.ts +2 -0
  88. package/dist/validate.d.cts +2 -0
  89. package/dist/validate.d.mts +2 -0
  90. package/dist/validate.d.ts +2 -0
  91. package/dist/webpack/swagger-compiler-plugin.d.cts +15 -0
  92. package/dist/webpack/swagger-compiler-plugin.d.mts +15 -0
  93. package/dist/webpack/swagger-compiler-plugin.d.ts +15 -0
  94. package/package.json +35 -23
  95. package/dist/chunk-CZO3NX7C.js +0 -149
  96. package/dist/chunk-CZO3NX7C.js.map +0 -1
  97. package/dist/chunk-LOXRB2QY.js +0 -1223
  98. package/dist/chunk-LOXRB2QY.js.map +0 -1
  99. package/dist/chunk-WUINTXB7.mjs +0 -1205
  100. package/dist/chunk-WUINTXB7.mjs.map +0 -1
  101. package/dist/chunk-Z53EXE6B.mjs +0 -142
  102. package/dist/chunk-Z53EXE6B.mjs.map +0 -1
  103. package/dist/cli/commander/index.js +0 -33
  104. package/dist/cli/commander/index.js.map +0 -1
  105. package/dist/cli/commander/index.mjs.map +0 -1
  106. package/dist/cli/index.js +0 -17
  107. package/dist/cli/index.js.map +0 -1
  108. package/dist/cli/index.mjs.map +0 -1
  109. package/dist/index.js +0 -106
  110. package/dist/index.js.map +0 -1
  111. package/dist/index.mjs.map +0 -1
@@ -0,0 +1,337 @@
1
+ 'use strict';
2
+
3
+ const commentParser = require('comment-parser');
4
+ const mergeWith = require('lodash.mergewith');
5
+ const customizer = require('./customizer-DDFwFqJl.cjs');
6
+
7
+ const _interopDefaultCompat = e => e && typeof e === 'object' && 'default' in e ? e.default : e;
8
+
9
+ const mergeWith__default = /*#__PURE__*/_interopDefaultCompat(mergeWith);
10
+
11
+ const ARRAY_SUFFIX_REGEX = /\[\]$/;
12
+ const DESCRIPTION_DASH_REGEX = /^- /u;
13
+ const PARAM_SUFFIX_REGEX = /Param$/u;
14
+ const OPEN_API_REGEX = /^(GET|PUT|POST|DELETE|OPTIONS|HEAD|PATCH|TRACE) \/.*$/;
15
+ const fixSecurityObject = (thing) => {
16
+ if (thing.security) {
17
+ thing.security = Object.keys(thing.security).map((s) => {
18
+ return {
19
+ [s]: thing.security[s]
20
+ };
21
+ });
22
+ }
23
+ };
24
+ const primitiveTypes = /* @__PURE__ */ new Set(["array", "boolean", "integer", "number", "object", "string"]);
25
+ const formatMap = {
26
+ binary: "string",
27
+ byte: "string",
28
+ date: "string",
29
+ "date-time": "string",
30
+ double: "number",
31
+ float: "number",
32
+ int32: "integer",
33
+ int64: "integer",
34
+ password: "string"
35
+ };
36
+ const parseDescription = (tag) => {
37
+ const rawType = tag.type;
38
+ const isArray = rawType.endsWith("[]");
39
+ const parsedType = rawType.replace(ARRAY_SUFFIX_REGEX, "");
40
+ const isPrimitive = primitiveTypes.has(parsedType);
41
+ const isFormat = Object.keys(formatMap).includes(parsedType);
42
+ let defaultValue;
43
+ if (tag.default) {
44
+ switch (parsedType) {
45
+ case "double":
46
+ case "float":
47
+ case "number": {
48
+ defaultValue = Number.parseFloat(tag.default);
49
+ break;
50
+ }
51
+ case "int32":
52
+ case "int64":
53
+ case "integer": {
54
+ defaultValue = Number.parseInt(tag.default, 10);
55
+ break;
56
+ }
57
+ default: {
58
+ defaultValue = tag.default;
59
+ break;
60
+ }
61
+ }
62
+ }
63
+ let rootType;
64
+ if (isPrimitive) {
65
+ rootType = { default: defaultValue, type: parsedType };
66
+ } else if (isFormat) {
67
+ rootType = {
68
+ default: defaultValue,
69
+ format: parsedType,
70
+ type: formatMap[parsedType]
71
+ };
72
+ } else {
73
+ rootType = { $ref: `#/components/schemas/${parsedType}` };
74
+ }
75
+ let schema = isArray ? {
76
+ items: {
77
+ ...rootType
78
+ },
79
+ type: "array"
80
+ } : {
81
+ ...rootType
82
+ };
83
+ if (parsedType === "") {
84
+ schema = void 0;
85
+ }
86
+ let description = tag.description.trim().replace(DESCRIPTION_DASH_REGEX, "");
87
+ if (description === "") {
88
+ description = void 0;
89
+ }
90
+ return {
91
+ description,
92
+ name: tag.name,
93
+ rawType,
94
+ required: !tag.optional,
95
+ schema
96
+ };
97
+ };
98
+ const tagsToObjects = (tags, _verbose) => tags.map((tag) => {
99
+ const parsedResponse = parseDescription(tag);
100
+ let nameAndDescription = "";
101
+ if (parsedResponse.name) {
102
+ nameAndDescription += parsedResponse.name;
103
+ }
104
+ if (parsedResponse.description) {
105
+ nameAndDescription += ` ${parsedResponse.description.trim()}`;
106
+ }
107
+ switch (tag.tag) {
108
+ case "bodyComponent": {
109
+ return {
110
+ requestBody: {
111
+ $ref: `#/components/requestBodies/${parsedResponse.rawType}`
112
+ }
113
+ };
114
+ }
115
+ case "bodyContent": {
116
+ return {
117
+ requestBody: {
118
+ content: {
119
+ [parsedResponse.name.replace(String.raw`*\/*`, "*/*")]: {
120
+ schema: parsedResponse.schema
121
+ }
122
+ }
123
+ }
124
+ };
125
+ }
126
+ case "bodyDescription": {
127
+ return { requestBody: { description: nameAndDescription } };
128
+ }
129
+ case "bodyExample": {
130
+ const [contentType, example] = parsedResponse.name.split(".");
131
+ return {
132
+ requestBody: {
133
+ content: {
134
+ [contentType]: {
135
+ examples: {
136
+ [example]: {
137
+ $ref: `#/components/examples/${parsedResponse.rawType}`
138
+ }
139
+ }
140
+ }
141
+ }
142
+ }
143
+ };
144
+ }
145
+ case "bodyRequired": {
146
+ return { requestBody: { required: true } };
147
+ }
148
+ case "callback": {
149
+ return {
150
+ callbacks: {
151
+ [parsedResponse.name]: {
152
+ $ref: `#/components/callbacks/${parsedResponse.rawType}`
153
+ }
154
+ }
155
+ };
156
+ }
157
+ case "cookieParam":
158
+ case "headerParam":
159
+ case "pathParam":
160
+ case "queryParam": {
161
+ return {
162
+ parameters: [
163
+ {
164
+ description: parsedResponse.description,
165
+ in: tag.tag.replace(PARAM_SUFFIX_REGEX, ""),
166
+ name: parsedResponse.name,
167
+ required: parsedResponse.required,
168
+ schema: parsedResponse.schema
169
+ }
170
+ ]
171
+ };
172
+ }
173
+ case "deprecated": {
174
+ return { deprecated: true };
175
+ }
176
+ case "description":
177
+ case "operationId":
178
+ case "summary": {
179
+ return { [tag.tag]: nameAndDescription };
180
+ }
181
+ case "externalDocs": {
182
+ return {
183
+ externalDocs: {
184
+ description: parsedResponse.description,
185
+ url: parsedResponse.name
186
+ }
187
+ };
188
+ }
189
+ case "paramComponent": {
190
+ return {
191
+ parameters: [{ $ref: `#/components/parameters/${parsedResponse.rawType}` }]
192
+ };
193
+ }
194
+ case "response": {
195
+ return {
196
+ responses: {
197
+ [parsedResponse.name]: {
198
+ description: parsedResponse.description
199
+ }
200
+ }
201
+ };
202
+ }
203
+ case "responseComponent": {
204
+ return {
205
+ responses: {
206
+ [parsedResponse.name]: {
207
+ $ref: `#/components/responses/${parsedResponse.rawType}`
208
+ }
209
+ }
210
+ };
211
+ }
212
+ case "responseContent": {
213
+ const [status, contentType] = parsedResponse.name.split(".");
214
+ return {
215
+ responses: {
216
+ [status]: {
217
+ content: {
218
+ [contentType]: {
219
+ schema: parsedResponse.schema
220
+ }
221
+ }
222
+ }
223
+ }
224
+ };
225
+ }
226
+ case "responseExample": {
227
+ const [status, contentType, example] = parsedResponse.name.split(".");
228
+ return {
229
+ responses: {
230
+ [status]: {
231
+ content: {
232
+ [contentType]: {
233
+ examples: {
234
+ [example]: {
235
+ $ref: `#/components/examples/${parsedResponse.rawType}`
236
+ }
237
+ }
238
+ }
239
+ }
240
+ }
241
+ }
242
+ };
243
+ }
244
+ case "responseHeader": {
245
+ const [status, header] = parsedResponse.name.split(".");
246
+ return {
247
+ responses: {
248
+ [status]: {
249
+ headers: {
250
+ [header]: {
251
+ description: parsedResponse.description,
252
+ schema: parsedResponse.schema
253
+ }
254
+ }
255
+ }
256
+ }
257
+ };
258
+ }
259
+ case "responseHeaderComponent": {
260
+ const [status, header] = parsedResponse.name.split(".");
261
+ return {
262
+ responses: {
263
+ [status]: {
264
+ headers: {
265
+ [header]: {
266
+ $ref: `#/components/headers/${parsedResponse.rawType}`
267
+ }
268
+ }
269
+ }
270
+ }
271
+ };
272
+ }
273
+ case "responseLink": {
274
+ const [status, link] = parsedResponse.name.split(".");
275
+ return {
276
+ responses: {
277
+ [status]: {
278
+ links: {
279
+ [link]: {
280
+ $ref: `#/components/links/${parsedResponse.rawType}`
281
+ }
282
+ }
283
+ }
284
+ }
285
+ };
286
+ }
287
+ case "security": {
288
+ const [security, scopeItem] = parsedResponse.name.split(".");
289
+ let scope = [];
290
+ if (scopeItem) {
291
+ scope = [scopeItem];
292
+ }
293
+ return {
294
+ security: { [security]: scope }
295
+ };
296
+ }
297
+ case "server": {
298
+ return {
299
+ servers: [
300
+ {
301
+ description: parsedResponse.description,
302
+ url: parsedResponse.name
303
+ }
304
+ ]
305
+ };
306
+ }
307
+ case "tag": {
308
+ return { tags: [nameAndDescription] };
309
+ }
310
+ default: {
311
+ return {};
312
+ }
313
+ }
314
+ });
315
+ const commentsToOpenApi = (fileContents, verbose) => {
316
+ const jsDocumentComments = commentParser.parse(fileContents, { spacing: "preserve" });
317
+ return jsDocumentComments.filter((comment) => OPEN_API_REGEX.test(comment.description.trim())).map((comment) => {
318
+ const loc = comment.tags.length + 1;
319
+ const result = mergeWith__default({}, ...tagsToObjects(comment.tags), customizer.customizer);
320
+ fixSecurityObject(result);
321
+ const [method, path] = comment.description.split(" ");
322
+ const pathsObject = {
323
+ [path.trim()]: {
324
+ [method.toLowerCase().trim()]: {
325
+ ...result
326
+ }
327
+ }
328
+ };
329
+ const spec = JSON.parse(JSON.stringify({ paths: pathsObject }));
330
+ return {
331
+ loc,
332
+ spec
333
+ };
334
+ });
335
+ };
336
+
337
+ module.exports = commentsToOpenApi;
@@ -0,0 +1,331 @@
1
+ import { parse } from 'comment-parser';
2
+ import mergeWith from 'lodash.mergewith';
3
+ import { c as customizer } from './customizer-CoMXMU7a.mjs';
4
+
5
+ const ARRAY_SUFFIX_REGEX = /\[\]$/;
6
+ const DESCRIPTION_DASH_REGEX = /^- /u;
7
+ const PARAM_SUFFIX_REGEX = /Param$/u;
8
+ const OPEN_API_REGEX = /^(GET|PUT|POST|DELETE|OPTIONS|HEAD|PATCH|TRACE) \/.*$/;
9
+ const fixSecurityObject = (thing) => {
10
+ if (thing.security) {
11
+ thing.security = Object.keys(thing.security).map((s) => {
12
+ return {
13
+ [s]: thing.security[s]
14
+ };
15
+ });
16
+ }
17
+ };
18
+ const primitiveTypes = /* @__PURE__ */ new Set(["array", "boolean", "integer", "number", "object", "string"]);
19
+ const formatMap = {
20
+ binary: "string",
21
+ byte: "string",
22
+ date: "string",
23
+ "date-time": "string",
24
+ double: "number",
25
+ float: "number",
26
+ int32: "integer",
27
+ int64: "integer",
28
+ password: "string"
29
+ };
30
+ const parseDescription = (tag) => {
31
+ const rawType = tag.type;
32
+ const isArray = rawType.endsWith("[]");
33
+ const parsedType = rawType.replace(ARRAY_SUFFIX_REGEX, "");
34
+ const isPrimitive = primitiveTypes.has(parsedType);
35
+ const isFormat = Object.keys(formatMap).includes(parsedType);
36
+ let defaultValue;
37
+ if (tag.default) {
38
+ switch (parsedType) {
39
+ case "double":
40
+ case "float":
41
+ case "number": {
42
+ defaultValue = Number.parseFloat(tag.default);
43
+ break;
44
+ }
45
+ case "int32":
46
+ case "int64":
47
+ case "integer": {
48
+ defaultValue = Number.parseInt(tag.default, 10);
49
+ break;
50
+ }
51
+ default: {
52
+ defaultValue = tag.default;
53
+ break;
54
+ }
55
+ }
56
+ }
57
+ let rootType;
58
+ if (isPrimitive) {
59
+ rootType = { default: defaultValue, type: parsedType };
60
+ } else if (isFormat) {
61
+ rootType = {
62
+ default: defaultValue,
63
+ format: parsedType,
64
+ type: formatMap[parsedType]
65
+ };
66
+ } else {
67
+ rootType = { $ref: `#/components/schemas/${parsedType}` };
68
+ }
69
+ let schema = isArray ? {
70
+ items: {
71
+ ...rootType
72
+ },
73
+ type: "array"
74
+ } : {
75
+ ...rootType
76
+ };
77
+ if (parsedType === "") {
78
+ schema = void 0;
79
+ }
80
+ let description = tag.description.trim().replace(DESCRIPTION_DASH_REGEX, "");
81
+ if (description === "") {
82
+ description = void 0;
83
+ }
84
+ return {
85
+ description,
86
+ name: tag.name,
87
+ rawType,
88
+ required: !tag.optional,
89
+ schema
90
+ };
91
+ };
92
+ const tagsToObjects = (tags, _verbose) => tags.map((tag) => {
93
+ const parsedResponse = parseDescription(tag);
94
+ let nameAndDescription = "";
95
+ if (parsedResponse.name) {
96
+ nameAndDescription += parsedResponse.name;
97
+ }
98
+ if (parsedResponse.description) {
99
+ nameAndDescription += ` ${parsedResponse.description.trim()}`;
100
+ }
101
+ switch (tag.tag) {
102
+ case "bodyComponent": {
103
+ return {
104
+ requestBody: {
105
+ $ref: `#/components/requestBodies/${parsedResponse.rawType}`
106
+ }
107
+ };
108
+ }
109
+ case "bodyContent": {
110
+ return {
111
+ requestBody: {
112
+ content: {
113
+ [parsedResponse.name.replace(String.raw`*\/*`, "*/*")]: {
114
+ schema: parsedResponse.schema
115
+ }
116
+ }
117
+ }
118
+ };
119
+ }
120
+ case "bodyDescription": {
121
+ return { requestBody: { description: nameAndDescription } };
122
+ }
123
+ case "bodyExample": {
124
+ const [contentType, example] = parsedResponse.name.split(".");
125
+ return {
126
+ requestBody: {
127
+ content: {
128
+ [contentType]: {
129
+ examples: {
130
+ [example]: {
131
+ $ref: `#/components/examples/${parsedResponse.rawType}`
132
+ }
133
+ }
134
+ }
135
+ }
136
+ }
137
+ };
138
+ }
139
+ case "bodyRequired": {
140
+ return { requestBody: { required: true } };
141
+ }
142
+ case "callback": {
143
+ return {
144
+ callbacks: {
145
+ [parsedResponse.name]: {
146
+ $ref: `#/components/callbacks/${parsedResponse.rawType}`
147
+ }
148
+ }
149
+ };
150
+ }
151
+ case "cookieParam":
152
+ case "headerParam":
153
+ case "pathParam":
154
+ case "queryParam": {
155
+ return {
156
+ parameters: [
157
+ {
158
+ description: parsedResponse.description,
159
+ in: tag.tag.replace(PARAM_SUFFIX_REGEX, ""),
160
+ name: parsedResponse.name,
161
+ required: parsedResponse.required,
162
+ schema: parsedResponse.schema
163
+ }
164
+ ]
165
+ };
166
+ }
167
+ case "deprecated": {
168
+ return { deprecated: true };
169
+ }
170
+ case "description":
171
+ case "operationId":
172
+ case "summary": {
173
+ return { [tag.tag]: nameAndDescription };
174
+ }
175
+ case "externalDocs": {
176
+ return {
177
+ externalDocs: {
178
+ description: parsedResponse.description,
179
+ url: parsedResponse.name
180
+ }
181
+ };
182
+ }
183
+ case "paramComponent": {
184
+ return {
185
+ parameters: [{ $ref: `#/components/parameters/${parsedResponse.rawType}` }]
186
+ };
187
+ }
188
+ case "response": {
189
+ return {
190
+ responses: {
191
+ [parsedResponse.name]: {
192
+ description: parsedResponse.description
193
+ }
194
+ }
195
+ };
196
+ }
197
+ case "responseComponent": {
198
+ return {
199
+ responses: {
200
+ [parsedResponse.name]: {
201
+ $ref: `#/components/responses/${parsedResponse.rawType}`
202
+ }
203
+ }
204
+ };
205
+ }
206
+ case "responseContent": {
207
+ const [status, contentType] = parsedResponse.name.split(".");
208
+ return {
209
+ responses: {
210
+ [status]: {
211
+ content: {
212
+ [contentType]: {
213
+ schema: parsedResponse.schema
214
+ }
215
+ }
216
+ }
217
+ }
218
+ };
219
+ }
220
+ case "responseExample": {
221
+ const [status, contentType, example] = parsedResponse.name.split(".");
222
+ return {
223
+ responses: {
224
+ [status]: {
225
+ content: {
226
+ [contentType]: {
227
+ examples: {
228
+ [example]: {
229
+ $ref: `#/components/examples/${parsedResponse.rawType}`
230
+ }
231
+ }
232
+ }
233
+ }
234
+ }
235
+ }
236
+ };
237
+ }
238
+ case "responseHeader": {
239
+ const [status, header] = parsedResponse.name.split(".");
240
+ return {
241
+ responses: {
242
+ [status]: {
243
+ headers: {
244
+ [header]: {
245
+ description: parsedResponse.description,
246
+ schema: parsedResponse.schema
247
+ }
248
+ }
249
+ }
250
+ }
251
+ };
252
+ }
253
+ case "responseHeaderComponent": {
254
+ const [status, header] = parsedResponse.name.split(".");
255
+ return {
256
+ responses: {
257
+ [status]: {
258
+ headers: {
259
+ [header]: {
260
+ $ref: `#/components/headers/${parsedResponse.rawType}`
261
+ }
262
+ }
263
+ }
264
+ }
265
+ };
266
+ }
267
+ case "responseLink": {
268
+ const [status, link] = parsedResponse.name.split(".");
269
+ return {
270
+ responses: {
271
+ [status]: {
272
+ links: {
273
+ [link]: {
274
+ $ref: `#/components/links/${parsedResponse.rawType}`
275
+ }
276
+ }
277
+ }
278
+ }
279
+ };
280
+ }
281
+ case "security": {
282
+ const [security, scopeItem] = parsedResponse.name.split(".");
283
+ let scope = [];
284
+ if (scopeItem) {
285
+ scope = [scopeItem];
286
+ }
287
+ return {
288
+ security: { [security]: scope }
289
+ };
290
+ }
291
+ case "server": {
292
+ return {
293
+ servers: [
294
+ {
295
+ description: parsedResponse.description,
296
+ url: parsedResponse.name
297
+ }
298
+ ]
299
+ };
300
+ }
301
+ case "tag": {
302
+ return { tags: [nameAndDescription] };
303
+ }
304
+ default: {
305
+ return {};
306
+ }
307
+ }
308
+ });
309
+ const commentsToOpenApi = (fileContents, verbose) => {
310
+ const jsDocumentComments = parse(fileContents, { spacing: "preserve" });
311
+ return jsDocumentComments.filter((comment) => OPEN_API_REGEX.test(comment.description.trim())).map((comment) => {
312
+ const loc = comment.tags.length + 1;
313
+ const result = mergeWith({}, ...tagsToObjects(comment.tags), customizer);
314
+ fixSecurityObject(result);
315
+ const [method, path] = comment.description.split(" ");
316
+ const pathsObject = {
317
+ [path.trim()]: {
318
+ [method.toLowerCase().trim()]: {
319
+ ...result
320
+ }
321
+ }
322
+ };
323
+ const spec = JSON.parse(JSON.stringify({ paths: pathsObject }));
324
+ return {
325
+ loc,
326
+ spec
327
+ };
328
+ });
329
+ };
330
+
331
+ export { commentsToOpenApi as default };
@@ -0,0 +1,35 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import path from 'node:path';
3
+ import yaml from 'yaml';
4
+ import yamlLoc from './yamlLoc-C7iHWvdq.mjs';
5
+
6
+ const ALLOWED_KEYS = /* @__PURE__ */ new Set(["components", "externalDocs", "info", "openapi", "paths", "security", "servers", "tags"]);
7
+ class ParseError extends Error {
8
+ filePath;
9
+ }
10
+ const parseFile = (file, commentsToOpenApi, verbose) => {
11
+ const fileContent = readFileSync(file, { encoding: "utf8" });
12
+ const extension = path.extname(file);
13
+ if (extension === ".yaml" || extension === ".yml") {
14
+ const spec = yaml.parse(fileContent);
15
+ const invalidKeys = Object.keys(spec).filter((key) => !ALLOWED_KEYS.has(key));
16
+ if (invalidKeys.length > 0) {
17
+ const error = new ParseError(`Unexpected keys: ${invalidKeys.join(", ")}`);
18
+ error.filePath = file;
19
+ throw error;
20
+ }
21
+ if (Object.keys(spec).some((key) => ALLOWED_KEYS.has(key))) {
22
+ const loc = yamlLoc(fileContent);
23
+ return [{ loc, spec }];
24
+ }
25
+ return [];
26
+ }
27
+ try {
28
+ return commentsToOpenApi(fileContent, verbose);
29
+ } catch (error) {
30
+ error.filePath = file;
31
+ throw error;
32
+ }
33
+ };
34
+
35
+ export { parseFile as default };