@necessarylion/adonis-autoswagger 0.0.4 → 0.0.5

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 (40) hide show
  1. package/dist/adonis_helpers.d.ts +21 -0
  2. package/dist/{adonishelpers.js → adonis_helpers.js} +17 -2
  3. package/dist/auto_swagger.d.ts +28 -0
  4. package/dist/{autoswagger.js → auto_swagger.js} +43 -394
  5. package/dist/example.d.ts +47 -0
  6. package/dist/example.js +48 -1
  7. package/dist/file.d.ts +44 -0
  8. package/dist/file.js +93 -0
  9. package/dist/helpers.d.ts +11 -2
  10. package/dist/helpers.js +11 -25
  11. package/dist/index.d.ts +1 -1
  12. package/dist/index.js +2 -2
  13. package/dist/parsers/comment_parser.d.ts +10 -0
  14. package/dist/parsers/comment_parser.js +417 -0
  15. package/dist/parsers/enum_parser.d.ts +5 -0
  16. package/dist/parsers/enum_parser.js +51 -0
  17. package/dist/parsers/helpers.d.ts +13 -0
  18. package/dist/parsers/helpers.js +38 -0
  19. package/dist/parsers/index.d.ts +6 -0
  20. package/dist/parsers/index.js +22 -0
  21. package/dist/parsers/interface_parser.d.ts +13 -0
  22. package/dist/parsers/interface_parser.js +249 -0
  23. package/dist/parsers/model_parser.d.ts +11 -0
  24. package/dist/parsers/model_parser.js +234 -0
  25. package/dist/parsers/route_parser.d.ts +10 -0
  26. package/dist/parsers/route_parser.js +46 -0
  27. package/dist/parsers/validator_parser.d.ts +7 -0
  28. package/dist/parsers/validator_parser.js +192 -0
  29. package/dist/schema.d.ts +46 -0
  30. package/dist/schema.js +266 -0
  31. package/dist/types.d.ts +16 -17
  32. package/dist/ui.d.ts +31 -0
  33. package/dist/ui.js +157 -0
  34. package/package.json +2 -2
  35. package/dist/adonishelpers.d.ts +0 -6
  36. package/dist/autoswagger.d.ts +0 -30
  37. package/dist/parsers.d.ts +0 -83
  38. package/dist/parsers.js +0 -1142
  39. /package/dist/{scalarCustomCss.d.ts → scalar_custom_css.d.ts} +0 -0
  40. /package/dist/{scalarCustomCss.js → scalar_custom_css.js} +0 -0
@@ -0,0 +1,417 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.CommentParser = void 0;
7
+ const http_status_code_1 = __importDefault(require("http-status-code"));
8
+ const helpers_1 = require("./helpers");
9
+ const util_1 = __importDefault(require("util"));
10
+ const extract_comments_1 = __importDefault(require("extract-comments"));
11
+ const fs_1 = __importDefault(require("fs"));
12
+ const lodash_1 = __importDefault(require("lodash"));
13
+ class CommentParser {
14
+ parsedFiles = {};
15
+ exampleGenerator;
16
+ options;
17
+ constructor(options) {
18
+ this.options = options;
19
+ }
20
+ #parseAnnotations(lines) {
21
+ let summary = "";
22
+ let tag = "";
23
+ let description = "";
24
+ let operationId;
25
+ let responses = {};
26
+ let requestBody;
27
+ let parameters = {};
28
+ let headers = {};
29
+ lines.forEach((line) => {
30
+ if (line.startsWith("@summary")) {
31
+ summary = line.replace("@summary ", "");
32
+ }
33
+ if (line.startsWith("@tag")) {
34
+ tag = line.replace("@tag ", "");
35
+ }
36
+ if (line.startsWith("@description")) {
37
+ description = line.replace("@description ", "");
38
+ }
39
+ if (line.startsWith("@operationId")) {
40
+ operationId = line.replace("@operationId ", "");
41
+ }
42
+ if (line.startsWith("@responseBody")) {
43
+ responses = {
44
+ ...responses,
45
+ ...this.#parseResponseBody(line),
46
+ };
47
+ }
48
+ if (line.startsWith("@responseHeader")) {
49
+ const header = this.#parseResponseHeader(line);
50
+ if (header === null) {
51
+ console.error("Error with line: " + line);
52
+ return;
53
+ }
54
+ headers[header["status"]] = {
55
+ ...headers[header["status"]],
56
+ ...header["header"],
57
+ };
58
+ }
59
+ if (line.startsWith("@requestBody")) {
60
+ requestBody = this.#parseBody(line, "requestBody");
61
+ }
62
+ if (line.startsWith("@requestFormDataBody")) {
63
+ const parsedBody = this.#parseRequestFormDataBody(line);
64
+ if (parsedBody) {
65
+ requestBody = parsedBody;
66
+ }
67
+ }
68
+ if (line.startsWith("@param")) {
69
+ parameters = { ...parameters, ...this.#parseParam(line) };
70
+ }
71
+ });
72
+ for (const [key, value] of Object.entries(responses)) {
73
+ if (typeof headers[key] !== undefined) {
74
+ responses[key]["headers"] = headers[key];
75
+ }
76
+ if (!responses[key]["description"]) {
77
+ responses[key]["description"] = `Returns **${key}** (${http_status_code_1.default.getMessage(key)}) as **${Object.entries(responses[key]["content"])[0][0]}**`;
78
+ }
79
+ }
80
+ return {
81
+ description,
82
+ responses,
83
+ requestBody,
84
+ parameters,
85
+ summary,
86
+ operationId,
87
+ tag,
88
+ };
89
+ }
90
+ #parseParam(line) {
91
+ let where = "path";
92
+ let required = true;
93
+ let type = "string";
94
+ let example = null;
95
+ let enums = [];
96
+ if (line.startsWith("@paramUse")) {
97
+ let use = (0, helpers_1.getBetweenBrackets)(line, "paramUse");
98
+ const used = use.split(",");
99
+ let h = [];
100
+ used.forEach((u) => {
101
+ if (typeof this.options.common.parameters[u] === "undefined") {
102
+ return;
103
+ }
104
+ const common = this.options.common.parameters[u];
105
+ h = [...h, ...common];
106
+ });
107
+ return h;
108
+ }
109
+ if (line.startsWith("@paramPath")) {
110
+ required = true;
111
+ }
112
+ if (line.startsWith("@paramQuery")) {
113
+ required = false;
114
+ }
115
+ let match = line.match("@param([a-zA-Z]*)");
116
+ if (match !== null) {
117
+ where = match[1].toLowerCase();
118
+ line = line.replace(match[0] + " ", "");
119
+ }
120
+ let [param, description, meta] = line.split(" - ");
121
+ if (typeof param === "undefined") {
122
+ return;
123
+ }
124
+ if (typeof description === "undefined") {
125
+ description = "";
126
+ }
127
+ if (typeof meta !== "undefined") {
128
+ if (meta.includes("@required")) {
129
+ required = true;
130
+ }
131
+ let enumsFromMeta = (0, helpers_1.getBetweenBrackets)(meta, "enum");
132
+ example = (0, helpers_1.getBetweenBrackets)(meta, "example");
133
+ const typeFromMeta = (0, helpers_1.getBetweenBrackets)(meta, "type");
134
+ if (typeFromMeta !== "") {
135
+ type = typeFromMeta;
136
+ }
137
+ if (enumsFromMeta !== "") {
138
+ enums = enumsFromMeta.split(",");
139
+ example = enums[0];
140
+ }
141
+ }
142
+ let parameter = {
143
+ in: where,
144
+ name: param,
145
+ description: description,
146
+ schema: {
147
+ example: example,
148
+ type: type,
149
+ },
150
+ required: required,
151
+ };
152
+ if (enums.length > 1) {
153
+ parameter["schema"]["enum"] = enums;
154
+ }
155
+ return { [param]: parameter };
156
+ }
157
+ #parseResponseHeader(responseLine) {
158
+ let description = "";
159
+ let example = "";
160
+ let type = "string";
161
+ let enums = [];
162
+ const line = responseLine.replace("@responseHeader ", "");
163
+ let [status, name, descriptionFromLine, meta] = line.split(" - ");
164
+ if (typeof status === "undefined" || typeof name === "undefined") {
165
+ return null;
166
+ }
167
+ if (typeof descriptionFromLine !== "undefined") {
168
+ description = descriptionFromLine;
169
+ }
170
+ if (name.includes("@use")) {
171
+ let use = (0, helpers_1.getBetweenBrackets)(name, "use");
172
+ const used = use.split(",");
173
+ let header = {};
174
+ used.forEach((u) => {
175
+ if (typeof this.options.common.headers[u] === "undefined") {
176
+ return;
177
+ }
178
+ const common = this.options.common.headers[u];
179
+ header = { ...header, ...common };
180
+ });
181
+ return {
182
+ status: status,
183
+ header: header,
184
+ };
185
+ }
186
+ if (typeof meta !== "undefined") {
187
+ example = (0, helpers_1.getBetweenBrackets)(meta, "example");
188
+ const typeFromMeta = (0, helpers_1.getBetweenBrackets)(meta, "type");
189
+ if (typeFromMeta !== "") {
190
+ type = typeFromMeta;
191
+ }
192
+ }
193
+ if (example === "" || example === null) {
194
+ switch (type) {
195
+ case "string":
196
+ example = "string";
197
+ break;
198
+ case "integer":
199
+ example = 1;
200
+ break;
201
+ case "float":
202
+ example = 1.5;
203
+ break;
204
+ }
205
+ }
206
+ let header = {
207
+ schema: { type: type, example: example },
208
+ description: description,
209
+ };
210
+ if (enums.length > 1) {
211
+ header["schema"]["enum"] = enums;
212
+ }
213
+ return {
214
+ status: status,
215
+ header: {
216
+ [name]: header,
217
+ },
218
+ };
219
+ }
220
+ #parseResponseBody(responseLine) {
221
+ let responses = {};
222
+ const line = responseLine.replace("@responseBody ", "");
223
+ let [status, res, description] = line.split(" - ");
224
+ if (typeof status === "undefined")
225
+ return;
226
+ responses[status] = this.#parseBody(res, "responseBody");
227
+ responses[status]["description"] = description;
228
+ return responses;
229
+ }
230
+ #parseRequestFormDataBody(rawLine) {
231
+ const line = rawLine.replace("@requestFormDataBody ", "");
232
+ let json = {}, required = [];
233
+ const isJson = (0, helpers_1.isJSONString)(line);
234
+ if (!isJson) {
235
+ // try to get json from reference
236
+ let rawRef = line.substring(line.indexOf("<") + 1, line.lastIndexOf(">"));
237
+ const cleandRef = rawRef.replace("[]", "");
238
+ if (cleandRef === "") {
239
+ return;
240
+ }
241
+ const parsedRef = this.exampleGenerator.parseRef(line, true);
242
+ let props = [];
243
+ const ref = this.exampleGenerator.schemas[cleandRef];
244
+ const ks = [];
245
+ if (ref.required && Array.isArray(ref.required))
246
+ required.push(...ref.required);
247
+ Object.entries(ref.properties).map(([key, value]) => {
248
+ if (typeof parsedRef[key] === "undefined") {
249
+ return;
250
+ }
251
+ ks.push(key);
252
+ if (value["required"])
253
+ required.push(key);
254
+ props.push({
255
+ [key]: {
256
+ type: typeof value["type"] === "undefined" ? "string" : value["type"],
257
+ format: typeof value["format"] === "undefined"
258
+ ? "string"
259
+ : value["format"],
260
+ },
261
+ });
262
+ });
263
+ const properties = props.reduce((acc, curr) => ({ ...acc, ...curr }), {});
264
+ const appends = Object.keys(parsedRef).filter((k) => !ks.includes(k));
265
+ json = properties;
266
+ if (appends.length > 0) {
267
+ appends.forEach((append) => {
268
+ json[append] = parsedRef[append];
269
+ });
270
+ }
271
+ }
272
+ else {
273
+ json = JSON.parse(line);
274
+ for (let key in json) {
275
+ if (json[key].required === "true") {
276
+ required.push(key);
277
+ }
278
+ }
279
+ }
280
+ // No need to try/catch this JSON.parse as we already did that in the isJSONString function
281
+ return {
282
+ content: {
283
+ "multipart/form-data": {
284
+ schema: {
285
+ type: "object",
286
+ properties: json,
287
+ required,
288
+ },
289
+ },
290
+ },
291
+ };
292
+ }
293
+ #parseBody(rawLine, type) {
294
+ let line = rawLine.replace(`@${type} `, "");
295
+ const isJson = (0, helpers_1.isJSONString)(line);
296
+ if (isJson) {
297
+ // No need to try/catch this JSON.parse as we already did that in the isJSONString function
298
+ const json = JSON.parse(line);
299
+ const obj = this.#jsonToObj(json);
300
+ return {
301
+ content: {
302
+ "application/json": {
303
+ schema: {
304
+ type: Array.isArray(json) ? "array" : "object",
305
+ ...(Array.isArray(json)
306
+ ? { items: this.#arrayItems(json) }
307
+ : obj),
308
+ },
309
+ example: this.exampleGenerator.jsonToRef(json),
310
+ },
311
+ },
312
+ };
313
+ }
314
+ return this.exampleGenerator.parseRef(line);
315
+ }
316
+ #arrayItems(json) {
317
+ const oneOf = [];
318
+ const type = typeof json[0];
319
+ if (type === "string") {
320
+ json.forEach((item) => {
321
+ const value = this.exampleGenerator.parseRef(item);
322
+ if (lodash_1.default.has(value, "content.application/json.schema.$ref")) {
323
+ oneOf.push({
324
+ $ref: value["content"]["application/json"]["schema"]["$ref"],
325
+ });
326
+ }
327
+ });
328
+ }
329
+ if (oneOf.length > 0) {
330
+ return { oneOf: oneOf };
331
+ }
332
+ return { type: typeof json[0] };
333
+ }
334
+ #jsonToObj(json) {
335
+ const obj = {
336
+ type: "object",
337
+ properties: Object.keys(json)
338
+ .map((key) => {
339
+ const type = typeof json[key];
340
+ const val = json[key];
341
+ let value = val;
342
+ if (type === "object") {
343
+ value = this.#jsonToObj(json[key]);
344
+ }
345
+ if (type === "string" && val.includes("<") && val.includes(">")) {
346
+ value = this.exampleGenerator.parseRef(val);
347
+ if (val.includes("[]")) {
348
+ let ref = "";
349
+ if (lodash_1.default.has(value, "content.application/json.schema.$ref")) {
350
+ ref = value["content"]["application/json"]["schema"]["$ref"];
351
+ }
352
+ if (lodash_1.default.has(value, "content.application/json.schema.items.$ref")) {
353
+ ref =
354
+ value["content"]["application/json"]["schema"]["items"]["$" + "ref"];
355
+ }
356
+ value = {
357
+ type: "array",
358
+ items: {
359
+ $ref: ref,
360
+ },
361
+ };
362
+ }
363
+ else {
364
+ value = {
365
+ $ref: value["content"]["application/json"]["schema"]["$ref"],
366
+ };
367
+ }
368
+ }
369
+ return {
370
+ [key]: value,
371
+ };
372
+ })
373
+ .reduce((acc, curr) => ({ ...acc, ...curr }), {}),
374
+ };
375
+ return obj;
376
+ }
377
+ async getAnnotations(file, action) {
378
+ let annotations = {};
379
+ let newdata = "";
380
+ if (typeof file === "undefined")
381
+ return;
382
+ if (typeof this.parsedFiles[file] !== "undefined") {
383
+ newdata = this.parsedFiles[file];
384
+ }
385
+ else {
386
+ try {
387
+ const readFile = util_1.default.promisify(fs_1.default.readFile);
388
+ const fileContent = await readFile(file, "utf8");
389
+ for (const line of fileContent.split("\n")) {
390
+ const trimmedLine = line.trim();
391
+ if (!trimmedLine.startsWith("@")) {
392
+ newdata += trimmedLine + "\n";
393
+ }
394
+ }
395
+ this.parsedFiles[file] = newdata;
396
+ }
397
+ catch (e) {
398
+ console.error("\x1b[31m✗ File not found\x1b[0m", file);
399
+ }
400
+ }
401
+ const comments = (0, extract_comments_1.default)(newdata);
402
+ if (comments.length > 0) {
403
+ comments.forEach((comment) => {
404
+ if (comment.type !== "BlockComment")
405
+ return;
406
+ let lines = comment.value.split("\n").filter((l) => l != "");
407
+ // fix for decorators
408
+ if (lines[0].trim() !== "@" + action)
409
+ return;
410
+ lines = lines.filter((l) => l != "");
411
+ annotations[action] = this.#parseAnnotations(lines);
412
+ });
413
+ }
414
+ return annotations;
415
+ }
416
+ }
417
+ exports.CommentParser = CommentParser;
@@ -0,0 +1,5 @@
1
+ export declare class EnumParser {
2
+ #private;
3
+ constructor();
4
+ parseEnums(fileContent: string): Record<string, any>;
5
+ }
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EnumParser = void 0;
4
+ const lodash_1 = require("lodash");
5
+ class EnumParser {
6
+ constructor() { }
7
+ parseEnums(fileContent) {
8
+ const enums = {};
9
+ const lines = fileContent.split("\n");
10
+ let currentEnum = null;
11
+ let description = null;
12
+ for (const line of lines) {
13
+ const trimmedLine = line.trim();
14
+ if (trimmedLine.startsWith("//")) {
15
+ description = trimmedLine.slice(2).trim();
16
+ continue;
17
+ }
18
+ if (trimmedLine.startsWith("enum") ||
19
+ trimmedLine.startsWith("export enum")) {
20
+ const match = trimmedLine.match(/(?:export\s+)?enum\s+(\w+)/);
21
+ if (match) {
22
+ currentEnum = match[1];
23
+ enums[currentEnum] = {
24
+ type: "string",
25
+ enum: [],
26
+ properties: {},
27
+ description: description || `${(0, lodash_1.startCase)(currentEnum)} enumeration`,
28
+ };
29
+ description = null;
30
+ }
31
+ continue;
32
+ }
33
+ if (currentEnum && trimmedLine !== "{" && trimmedLine !== "}") {
34
+ const [key, value] = trimmedLine.split("=").map((s) => s.trim());
35
+ if (key) {
36
+ const enumValue = value ? this.#parseEnumValue(value) : key;
37
+ enums[currentEnum].enum.push(enumValue);
38
+ }
39
+ }
40
+ if (trimmedLine === "}") {
41
+ currentEnum = null;
42
+ }
43
+ }
44
+ return enums;
45
+ }
46
+ #parseEnumValue(value) {
47
+ // Remove quotes and comma
48
+ return value.replace(/['",]/g, "").trim();
49
+ }
50
+ }
51
+ exports.EnumParser = EnumParser;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Check if a string is a valid JSON
3
+ * @param str string
4
+ * @returns
5
+ */
6
+ export declare function isJSONString(str: string): boolean;
7
+ /**
8
+ * Get string between brackets
9
+ * @param value string
10
+ * @param start string
11
+ * @returns
12
+ */
13
+ export declare function getBetweenBrackets(value: string, start: string): string;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isJSONString = isJSONString;
4
+ exports.getBetweenBrackets = getBetweenBrackets;
5
+ /**
6
+ * Check if a string is a valid JSON
7
+ * @param str string
8
+ * @returns
9
+ */
10
+ function isJSONString(str) {
11
+ try {
12
+ JSON.parse(str);
13
+ return true;
14
+ }
15
+ catch (error) {
16
+ return false;
17
+ }
18
+ }
19
+ /**
20
+ * Get string between brackets
21
+ * @param value string
22
+ * @param start string
23
+ * @returns
24
+ */
25
+ function getBetweenBrackets(value, start) {
26
+ let match = value.match(new RegExp(start + "\\(([^()]*)\\)", "g"));
27
+ if (match !== null) {
28
+ let m = match[0].replace(start + "(", "").replace(")", "");
29
+ if (start !== "example") {
30
+ m = m.replace(/ /g, "");
31
+ }
32
+ if (start === "paginated") {
33
+ return "true";
34
+ }
35
+ return m;
36
+ }
37
+ return "";
38
+ }
@@ -0,0 +1,6 @@
1
+ export * from "./comment_parser";
2
+ export * from "./route_parser";
3
+ export * from "./model_parser";
4
+ export * from "./validator_parser";
5
+ export * from "./interface_parser";
6
+ export * from "./enum_parser";
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./comment_parser"), exports);
18
+ __exportStar(require("./route_parser"), exports);
19
+ __exportStar(require("./model_parser"), exports);
20
+ __exportStar(require("./validator_parser"), exports);
21
+ __exportStar(require("./interface_parser"), exports);
22
+ __exportStar(require("./enum_parser"), exports);
@@ -0,0 +1,13 @@
1
+ import ExampleGenerator from "../example";
2
+ export declare class InterfaceParser {
3
+ #private;
4
+ exampleGenerator: ExampleGenerator;
5
+ snakeCase: boolean;
6
+ schemas: any;
7
+ constructor(snakeCase: boolean, schemas?: any);
8
+ objToExample(obj: Record<string, any>): Record<string, any>;
9
+ parseProps(obj: Record<string, any>): Record<string, any>;
10
+ getInheritedProperties(baseType: string): any;
11
+ parseInterfaces(fileContent: string): Record<string, any>;
12
+ parseType(type: string | any, field: string): any;
13
+ }