@visulima/jsdoc-open-api 1.2.0 → 1.2.2

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/src/exported.d.ts DELETED
@@ -1,266 +0,0 @@
1
- declare function openapi(options?: ParserOptions): OpenApiObject;
2
-
3
- export default openapi;
4
-
5
- export interface ParserOptions {
6
- cwd: string;
7
- extension?: string[];
8
- include?: string[];
9
- exclude?: string[];
10
- excludeNodeModules?: boolean;
11
- verbose?: boolean;
12
- }
13
-
14
- export interface BaseDefinition {
15
- openapi: string;
16
- info: InfoObject;
17
- servers?: ServerObject[];
18
- paths?: PathsObject;
19
- components?: ComponentsObject;
20
- security?: SecurityRequirementObject[];
21
- tags?: TagObject[];
22
- externalDocs?: ExternalDocumentationObject;
23
- }
24
-
25
- export interface OpenApiObject extends BaseDefinition {
26
- paths: PathsObject;
27
- }
28
-
29
- export interface InfoObject {
30
- title: string;
31
- version: string;
32
- description?: string;
33
- termsOfService?: string;
34
- contact?: ContactObject;
35
- license?: LicenseObject;
36
- }
37
-
38
- export interface ContactObject {
39
- name?: string;
40
- url?: string;
41
- email?: string;
42
- }
43
-
44
- export interface LicenseObject {
45
- name: string;
46
- url?: string;
47
- }
48
-
49
- export interface ServerObject {
50
- url: string;
51
- description?: string;
52
- variables?: Map<ServerVariable>;
53
- }
54
-
55
- export interface ServerVariable {
56
- default: string;
57
- enum?: string[];
58
- description?: string;
59
- }
60
-
61
- export interface ComponentsObject {
62
- schemas?: Map<SchemaObject | ReferenceObject>;
63
- responses?: Map<ResponseObject | ReferenceObject>;
64
- parameters?: Map<ParameterObject | ReferenceObject>;
65
- examples?: Map<ExampleObject | ReferenceObject>;
66
- requestBodies?: Map<RequestBodyObject | ReferenceObject>;
67
- headers?: Map<HeaderObject | ReferenceObject>;
68
- securitySchemes?: Map<
69
- ApiKeySecuritySchemeObject | HttpSecuritySchemeObject | Oauth2SecuritySchemeObject | OpenIdConnectSecuritySchemeObject | ReferenceObject
70
- >;
71
- links?: Map<LinkObject | ReferenceObject>;
72
- callbacks?: Map<CallbackObject | ReferenceObject>;
73
- }
74
-
75
- export interface PathsObject {
76
- [path: string]: PathItemObject;
77
- }
78
-
79
- export interface PathItemObject {
80
- $ref?: string;
81
- summary?: string;
82
- description?: string;
83
- get?: OperationObject;
84
- put?: OperationObject;
85
- post?: OperationObject;
86
- delete?: OperationObject;
87
- options?: OperationObject;
88
- head?: OperationObject;
89
- patch?: OperationObject;
90
- trace?: OperationObject;
91
- servers?: ServerObject[];
92
- parameters?: (ParameterObject | ReferenceObject)[];
93
- }
94
-
95
- export interface OperationObject {
96
- responses: ResponsesObject;
97
- tags?: string[];
98
- summary?: string;
99
- description?: string;
100
- externalDocs?: ExternalDocumentationObject;
101
- operationId?: string;
102
- parameters?: (ParameterObject | ReferenceObject)[];
103
- requestBody?: RequestBodyObject | ReferenceObject;
104
- callbacks?: Map<CallbackObject | ReferenceObject>;
105
- deprecated?: boolean;
106
- security?: SecurityRequirementObject[];
107
- servers?: ServerObject[];
108
- }
109
-
110
- export interface ExternalDocumentationObject {
111
- url: string;
112
- description?: string;
113
- }
114
-
115
- export interface ParameterObject {
116
- name: string;
117
- in: string;
118
- description?: string;
119
- required?: boolean;
120
- deprecated?: boolean;
121
- allowEmptyValue?: boolean;
122
- //
123
- style?: string;
124
- explode?: string;
125
- allowReserved?: boolean;
126
- schema?: SchemaObject | ReferenceObject;
127
- example?: any;
128
- examples?: Map<ExampleObject | ReferenceObject>;
129
- //
130
- content?: Map<MediaTypeObject>;
131
- // ignoring stylings: matrix, label, form, simple, spaceDelimited,
132
- // pipeDelimited and deepObject
133
- }
134
-
135
- export interface RequestBodyObject {
136
- content: Map<MediaTypeObject>;
137
- description?: string;
138
- required?: boolean;
139
- }
140
-
141
- export interface MediaTypeObject {
142
- schema?: SchemaObject | ReferenceObject;
143
- example?: any;
144
- examples?: Map<ExampleObject | ReferenceObject>;
145
- encoding?: Map<EncodingObject>;
146
- }
147
-
148
- export interface EncodingObject {
149
- contentType?: string;
150
- headers?: Map<HeaderObject | ReferenceObject>;
151
- style?: string;
152
- explode?: boolean;
153
- allowReserved?: boolean;
154
- }
155
-
156
- export interface ResponsesObject {
157
- [code: string]: ResponseObject | ReferenceObject;
158
- }
159
-
160
- export interface ResponseObject {
161
- description: string;
162
- headers?: Map<HeaderObject | ReferenceObject>;
163
- content?: Map<MediaTypeObject>;
164
- links?: Map<LinkObject | ReferenceObject>;
165
- }
166
-
167
- export interface CallbackObject {
168
- [expression: string]: PathItemObject;
169
- }
170
-
171
- export interface ExampleObject {
172
- summary?: string;
173
- description?: string;
174
- value?: any;
175
- externalValue?: string;
176
- }
177
-
178
- export interface LinkObject {
179
- operationRef?: string;
180
- operationId?: string;
181
- parameters?: Map<any>;
182
- requestBody?: any;
183
- description?: string;
184
- server?: ServerObject;
185
- }
186
-
187
- export interface HeaderObject {
188
- description?: string;
189
- required?: boolean;
190
- deprecated?: boolean;
191
- allowEmptyValue?: boolean;
192
- //
193
- style?: string;
194
- explode?: string;
195
- allowReserved?: boolean;
196
- schema?: SchemaObject | ReferenceObject;
197
- example?: any;
198
- examples?: Map<ExampleObject | ReferenceObject>;
199
- //
200
- content?: Map<MediaTypeObject>;
201
- // ignoring stylings: matrix, label, form, simple, spaceDelimited,
202
- // pipeDelimited and deepObject
203
- }
204
-
205
- export interface TagObject {
206
- name: string;
207
- description?: string;
208
- externalDocs?: ExternalDocumentationObject;
209
- }
210
-
211
- export interface ReferenceObject {
212
- $ref: string;
213
- }
214
-
215
- // TODO: this could be expanded on.
216
- export interface SchemaObject {
217
- [key: string]: any;
218
- }
219
-
220
- export interface ApiKeySecuritySchemeObject {
221
- type: string;
222
- description?: string;
223
- name: string;
224
- in: string;
225
- }
226
-
227
- export interface HttpSecuritySchemeObject {
228
- type: string;
229
- description?: string;
230
- scheme: string;
231
- bearerFormat?: string;
232
- }
233
-
234
- export interface Oauth2SecuritySchemeObject {
235
- type: string;
236
- description?: string;
237
- flows: OAuthFlowsObject;
238
- }
239
-
240
- export interface OpenIdConnectSecuritySchemeObject {
241
- type: string;
242
- description?: string;
243
- openIdConnectUrl: string;
244
- }
245
-
246
- export interface OAuthFlowsObject {
247
- implicit?: OAuthFlowObject;
248
- password?: OAuthFlowObject;
249
- clientCredentials?: OAuthFlowObject;
250
- authorizationCode?: OAuthFlowObject;
251
- }
252
-
253
- export interface OAuthFlowObject {
254
- authorizationUrl?: string; // required for some?
255
- tokenUrl?: string; // required for some?
256
- refreshUrl: string;
257
- scopes: Map<string>;
258
- }
259
-
260
- export interface SecurityRequirementObject {
261
- [name: string]: string[];
262
- }
263
-
264
- export interface Map<T> {
265
- [key: string]: T;
266
- }
package/src/index.ts DELETED
@@ -1,7 +0,0 @@
1
- export { default as SpecBuilder } from "./spec-builder";
2
- export { default as parseFile } from "./parse-file";
3
- export { default as yamlLoc } from "./util/yaml-loc";
4
- export type { BaseDefinition, OpenApiObject } from "./exported";
5
- export { default as SwaggerCompilerPlugin } from "./webpack/swagger-compiler-plugin";
6
- export { default as jsDocumentCommentsToOpenApi } from "./jsdoc/comments-to-open-api";
7
- export { default as swaggerJsDocumentCommentsToOpenApi } from "./swagger-jsdoc/comments-to-open-api";
@@ -1,402 +0,0 @@
1
- import type { Spec } from "comment-parser";
2
- import { parse as parseComments } from "comment-parser";
3
- import mergeWith from "lodash.mergewith";
4
-
5
- import { OpenApiObject, PathsObject } from "../exported";
6
- import customizer from "../util/customizer";
7
-
8
- // The security object has a bizare setup...
9
- function fixSecurityObject(thing: any) {
10
- if (thing.security) {
11
- // eslint-disable-next-line no-param-reassign
12
- thing.security = Object.keys(thing.security).map((s) => {
13
- return {
14
- [s]: thing.security[s],
15
- };
16
- });
17
- }
18
- }
19
-
20
- const primitiveTypes = new Set(["integer", "number", "string", "boolean", "object", "array"]);
21
-
22
- const formatMap: { [key: string]: string } = {
23
- int32: "integer",
24
- int64: "integer",
25
- float: "number",
26
- double: "number",
27
- date: "string",
28
- "date-time": "string",
29
- password: "string",
30
- byte: "string",
31
- binary: "string",
32
- };
33
-
34
- function parseDescription(tag: any) {
35
- const rawType = tag.type;
36
- const isArray = rawType && rawType.endsWith("[]");
37
-
38
- let parsedType;
39
-
40
- if (rawType) {
41
- parsedType = rawType.replace(/\[]$/, "");
42
- }
43
-
44
- const isPrimitive = primitiveTypes.has(parsedType);
45
- const isFormat = Object.keys(formatMap).includes(parsedType);
46
-
47
- let defaultValue;
48
-
49
- if (tag.default) {
50
- switch (parsedType) {
51
- case "integer":
52
- case "int32":
53
- case "int64": {
54
- defaultValue = Number.parseInt(tag.default, 10);
55
- break;
56
- }
57
- case "number":
58
- case "double":
59
- case "float": {
60
- defaultValue = Number.parseFloat(tag.default);
61
- break;
62
- }
63
- default: {
64
- defaultValue = tag.default;
65
- break;
66
- }
67
- }
68
- }
69
-
70
- let rootType;
71
-
72
- if (isPrimitive) {
73
- rootType = { type: parsedType, default: defaultValue };
74
- } else if (isFormat) {
75
- rootType = {
76
- type: formatMap[parsedType],
77
- format: parsedType,
78
- default: defaultValue,
79
- };
80
- } else {
81
- rootType = { $ref: `#/components/schemas/${parsedType}` };
82
- }
83
-
84
- let schema: undefined | object = isArray
85
- ? {
86
- type: "array",
87
- items: {
88
- ...rootType,
89
- },
90
- }
91
- : {
92
- ...rootType,
93
- };
94
-
95
- if (parsedType === undefined) {
96
- schema = undefined;
97
- }
98
-
99
- // remove the optional dash from the description.
100
- let description = tag.description.trim().replace(/^- /, "");
101
-
102
- if (description === "") {
103
- description = undefined;
104
- }
105
-
106
- return {
107
- name: tag.name,
108
- description,
109
- required: !tag.optional,
110
- schema,
111
- rawType,
112
- };
113
- }
114
-
115
- // @ts-ignore
116
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
117
- function tagsToObjects(tags: Spec[], verbose?: boolean) {
118
- return tags.map((tag) => {
119
- const parsedResponse = parseDescription(tag);
120
-
121
- // Some ops only have a `description`, merge `name` and `description`
122
- // for these.
123
- let nameAndDescription = "";
124
-
125
- if (parsedResponse.name) {
126
- nameAndDescription += parsedResponse.name;
127
- }
128
-
129
- if (parsedResponse.description) {
130
- nameAndDescription += ` ${parsedResponse.description.trim()}`;
131
- }
132
-
133
- switch (tag.tag) {
134
- case "operationId":
135
- case "summary":
136
- case "description": {
137
- return { [tag.tag]: nameAndDescription };
138
- }
139
-
140
- case "deprecated": {
141
- return { deprecated: true };
142
- }
143
-
144
- case "externalDocs": {
145
- return {
146
- externalDocs: {
147
- url: parsedResponse.name,
148
- description: parsedResponse.description,
149
- },
150
- };
151
- }
152
-
153
- case "server": {
154
- return {
155
- servers: [
156
- {
157
- url: parsedResponse.name,
158
- description: parsedResponse.description,
159
- },
160
- ],
161
- };
162
- }
163
-
164
- case "tag": {
165
- return { tags: [nameAndDescription] };
166
- }
167
-
168
- case "cookieParam":
169
- case "headerParam":
170
- case "queryParam":
171
- case "pathParam": {
172
- return {
173
- parameters: [
174
- {
175
- name: parsedResponse.name,
176
- in: tag.tag.replace(/Param$/, ""),
177
- description: parsedResponse.description,
178
- required: parsedResponse.required,
179
- schema: parsedResponse.schema,
180
- },
181
- ],
182
- };
183
- }
184
-
185
- case "bodyContent": {
186
- return {
187
- requestBody: {
188
- content: {
189
- [parsedResponse.name.replace("*\\/*", "*/*")]: {
190
- schema: parsedResponse.schema,
191
- },
192
- },
193
- },
194
- };
195
- }
196
-
197
- case "bodyExample": {
198
- const [contentType, example] = parsedResponse.name.split(".");
199
- return {
200
- requestBody: {
201
- content: {
202
- [contentType]: {
203
- examples: {
204
- [example]: {
205
- $ref: `#/components/examples/${parsedResponse.rawType}`,
206
- },
207
- },
208
- },
209
- },
210
- },
211
- };
212
- }
213
-
214
- case "bodyDescription": {
215
- return { requestBody: { description: nameAndDescription } };
216
- }
217
-
218
- case "bodyRequired": {
219
- return { requestBody: { required: true } };
220
- }
221
-
222
- case "response": {
223
- return {
224
- responses: {
225
- [parsedResponse.name]: {
226
- description: parsedResponse.description,
227
- },
228
- },
229
- };
230
- }
231
-
232
- case "callback": {
233
- return {
234
- callbacks: {
235
- [parsedResponse.name]: {
236
- $ref: `#/components/callbacks/${parsedResponse.rawType}`,
237
- },
238
- },
239
- };
240
- }
241
-
242
- case "responseContent": {
243
- const [status, contentType] = parsedResponse.name.split(".");
244
-
245
- return {
246
- responses: {
247
- [status]: {
248
- content: {
249
- [contentType]: {
250
- schema: parsedResponse.schema,
251
- },
252
- },
253
- },
254
- },
255
- };
256
- }
257
-
258
- case "responseHeaderComponent": {
259
- const [status, header] = parsedResponse.name.split(".");
260
- return {
261
- responses: {
262
- [status]: {
263
- headers: {
264
- [header]: {
265
- $ref: `#/components/headers/${parsedResponse.rawType}`,
266
- },
267
- },
268
- },
269
- },
270
- };
271
- }
272
-
273
- case "responseHeader": {
274
- const [status, header] = parsedResponse.name.split(".");
275
- return {
276
- responses: {
277
- [status]: {
278
- headers: {
279
- [header]: {
280
- description: parsedResponse.description,
281
- schema: parsedResponse.schema,
282
- },
283
- },
284
- },
285
- },
286
- };
287
- }
288
-
289
- case "responseExample": {
290
- const [status, contentType, example] = parsedResponse.name.split(".");
291
- return {
292
- responses: {
293
- [status]: {
294
- content: {
295
- [contentType]: {
296
- examples: {
297
- [example]: {
298
- $ref: `#/components/examples/${parsedResponse.rawType}`,
299
- },
300
- },
301
- },
302
- },
303
- },
304
- },
305
- };
306
- }
307
-
308
- case "responseLink": {
309
- const [status, link] = parsedResponse.name.split(".");
310
- return {
311
- responses: {
312
- [status]: {
313
- links: {
314
- [link]: {
315
- $ref: `#/components/links/${parsedResponse.rawType}`,
316
- },
317
- },
318
- },
319
- },
320
- };
321
- }
322
-
323
- case "bodyComponent": {
324
- return {
325
- requestBody: {
326
- $ref: `#/components/requestBodies/${parsedResponse.rawType}`,
327
- },
328
- };
329
- }
330
-
331
- case "responseComponent": {
332
- return {
333
- responses: {
334
- [parsedResponse.name]: {
335
- $ref: `#/components/responses/${parsedResponse.rawType}`,
336
- },
337
- },
338
- };
339
- }
340
-
341
- case "paramComponent": {
342
- return {
343
- parameters: [{ $ref: `#/components/parameters/${parsedResponse.rawType}` }],
344
- };
345
- }
346
-
347
- case "security": {
348
- const [security, scopeItem] = parsedResponse.name.split(".");
349
- let scope: string[] = [];
350
- if (scopeItem) {
351
- scope = [scopeItem];
352
- }
353
- return {
354
- security: { [security]: scope },
355
- };
356
- }
357
-
358
- default: {
359
- return {};
360
- }
361
- }
362
- });
363
- }
364
-
365
- const commentsToOpenApi = (fileContents: string, verbose?: boolean): { spec: OpenApiObject; loc: number }[] => {
366
- const openAPIRegex = /^(GET|PUT|POST|DELETE|OPTIONS|HEAD|PATCH|TRACE) \/.*$/;
367
-
368
- const jsDocumentComments = parseComments(fileContents, { spacing: "preserve" });
369
-
370
- return jsDocumentComments
371
- .filter((comment) => openAPIRegex.test(comment.description.trim()))
372
- .map((comment) => {
373
- // Line count, number of tags + 1 for description.
374
- // - Don't count line-breaking due to long descriptions
375
- // - Don't count empty lines
376
- const loc = comment.tags.length + 1;
377
-
378
- const result = mergeWith({}, ...tagsToObjects(comment.tags, verbose), customizer);
379
-
380
- fixSecurityObject(result);
381
-
382
- const [method, path]: string[] = comment.description.split(" ");
383
-
384
- const pathsObject: PathsObject = {
385
- [(path as string).trim()]: {
386
- [(method as string).toLowerCase().trim()]: {
387
- ...result,
388
- },
389
- },
390
- };
391
-
392
- // Purge all undefined objects/arrays.
393
- const spec = JSON.parse(JSON.stringify({ paths: pathsObject }));
394
-
395
- return {
396
- spec,
397
- loc,
398
- };
399
- });
400
- };
401
-
402
- export default commentsToOpenApi;
package/src/options.ts DELETED
@@ -1,28 +0,0 @@
1
- const DEFAULT_OPTIONS = {
2
- cwd: undefined,
3
- extension: [".js", ".cjs", ".mjs", ".ts", ".tsx", ".jsx", ".yaml", ".yml"],
4
- include: ["**"],
5
- exclude: [
6
- "coverage/**",
7
- "packages/*/test{,s}/**",
8
- "**/*.d.ts",
9
- "test{,s}/**",
10
- "test{,-*}.{js,cjs,mjs,ts,tsx,jsx,yaml,yml}",
11
- "**/*{.,-}test.{js,cjs,mjs,ts,tsx,jsx,yaml,yml}",
12
- "**/__tests__/**",
13
-
14
- /* Exclude common development tool configuration files */
15
- "**/{ava,babel,nyc}.config.{js,cjs,mjs}",
16
- "**/jest.config.{js,cjs,mjs,ts}",
17
- "**/{karma,rollup,webpack}.config.js",
18
- "**/.{eslint,mocha}rc.{js,cjs}",
19
- "**/.{travis,yarnrc}.yml",
20
- "**/{docker-compose}.yml",
21
-
22
- // always ignore '**/node_modules/**'
23
- ],
24
- excludeNodeModules: true,
25
- verbose: true,
26
- };
27
-
28
- export default DEFAULT_OPTIONS;