@necessarylion/adonis-autoswagger 0.0.2 → 0.0.3
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/README.md +80 -4
- package/dist/autoswagger.js +19 -16
- package/dist/parsers.d.ts +5 -2
- package/dist/parsers.js +19 -9
- package/package.json +9 -8
package/README.md
CHANGED
|
@@ -13,11 +13,13 @@ Adonis AutoSwagger <br />
|
|
|
13
13
|
## 💻️ Install
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
pnpm i adonis-autoswagger #using pnpm
|
|
16
|
+
pnpm i @necessarylion/adonis-autoswagger #using pnpm
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
+
*This is a fork of [adonis-autoswagger](https://github.com/ad-on-is/adonis-autoswagger) with some additional features.*
|
|
22
|
+
|
|
21
23
|
## ⭐️ Features
|
|
22
24
|
|
|
23
25
|
- Creates **paths** automatically based on `routes.ts`
|
|
@@ -76,7 +78,7 @@ In your `routes.ts`
|
|
|
76
78
|
## 6️⃣ for AdonisJS v6
|
|
77
79
|
|
|
78
80
|
```js
|
|
79
|
-
import AutoSwagger from "adonis-autoswagger";
|
|
81
|
+
import AutoSwagger from "@necessarylion/adonis-autoswagger";
|
|
80
82
|
import swagger from "#config/swagger";
|
|
81
83
|
// returns swagger in YAML
|
|
82
84
|
router.get("/swagger", async () => {
|
|
@@ -94,7 +96,7 @@ router.get("/docs", async () => {
|
|
|
94
96
|
## 5️⃣ for AdonisJS v5
|
|
95
97
|
|
|
96
98
|
```js
|
|
97
|
-
import AutoSwagger from "adonis-autoswagger";
|
|
99
|
+
import AutoSwagger from "@necessarylion/adonis-autoswagger";
|
|
98
100
|
import swagger from "Config/swagger";
|
|
99
101
|
// returns swagger in YAML
|
|
100
102
|
Route.get("/swagger", async () => {
|
|
@@ -456,6 +458,71 @@ Generates responses and requestBody based on your simple Controller-Annotation (
|
|
|
456
458
|
|
|
457
459
|
## Schemas
|
|
458
460
|
|
|
461
|
+
### Validators
|
|
462
|
+
|
|
463
|
+
Automatically generates swagger schema-descriptions based on your validators.
|
|
464
|
+
|
|
465
|
+
#### Adding example values
|
|
466
|
+
|
|
467
|
+
```ts
|
|
468
|
+
export const adminLogin = vine.compile(
|
|
469
|
+
vine.object({
|
|
470
|
+
email: vine.string().trim().example('admin@laconcept.de'),
|
|
471
|
+
password: vine.string().trim().example('password'),
|
|
472
|
+
})
|
|
473
|
+
)
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
##### Create custom validators with vine
|
|
477
|
+
|
|
478
|
+
```ts
|
|
479
|
+
// start/validators/example.ts
|
|
480
|
+
|
|
481
|
+
import vine, { VineNumber, VineString, VineNativeEnum } from '@vinejs/vine'
|
|
482
|
+
import { EnumLike } from '@vinejs/vine/types'
|
|
483
|
+
|
|
484
|
+
type Options = {
|
|
485
|
+
example: any
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
declare module '@vinejs/vine' {
|
|
489
|
+
interface VineString {
|
|
490
|
+
example(example: string): this
|
|
491
|
+
}
|
|
492
|
+
interface VineNumber {
|
|
493
|
+
example(example: number): this
|
|
494
|
+
}
|
|
495
|
+
interface VineNativeEnum<Values extends EnumLike> {
|
|
496
|
+
example(example: string): this
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
export const exampleRule = vine.createRule((_: unknown, opt: Options) => {
|
|
501
|
+
return opt.example
|
|
502
|
+
})
|
|
503
|
+
|
|
504
|
+
VineString.macro('example', function (this: VineString, example: string) {
|
|
505
|
+
return this.use(exampleRule({ example }))
|
|
506
|
+
})
|
|
507
|
+
VineNumber.macro('example', function (this: VineNumber, example: number) {
|
|
508
|
+
return this.use(exampleRule({ example }))
|
|
509
|
+
})
|
|
510
|
+
VineNativeEnum.macro('example', function (this: VineNativeEnum<any>, example: string) {
|
|
511
|
+
return this.use(exampleRule({ example }))
|
|
512
|
+
})
|
|
513
|
+
```
|
|
514
|
+
|
|
515
|
+
##### Import in `adonisrc.ts` preloads
|
|
516
|
+
|
|
517
|
+
```ts
|
|
518
|
+
preloads: [
|
|
519
|
+
() => import('#start/routes'),
|
|
520
|
+
() => import('#start/kernel'),
|
|
521
|
+
() => import('#start/sentry'),
|
|
522
|
+
() => import('#start/validators/example.ts'),
|
|
523
|
+
],
|
|
524
|
+
```
|
|
525
|
+
|
|
459
526
|
### Models
|
|
460
527
|
|
|
461
528
|
Automatically generates swagger schema-descriptions based on your models
|
|
@@ -464,7 +531,16 @@ Automatically generates swagger schema-descriptions based on your models
|
|
|
464
531
|
|
|
465
532
|
### Interfaces
|
|
466
533
|
|
|
467
|
-
Instead of using `param: any` you can now use custom interfaces `param: UserDetails`. The interfaces files need to be located at `app/Interfaces/`
|
|
534
|
+
Instead of using `param: any` you can now use custom interfaces `param: UserDetails`. The interfaces files need to be located at `app/Interfaces/` or `app/interfaces/`
|
|
535
|
+
|
|
536
|
+
```ts
|
|
537
|
+
export interface UserDetails {
|
|
538
|
+
// @example(John Doe)
|
|
539
|
+
name: string;
|
|
540
|
+
// @example(johndoe@example.com)
|
|
541
|
+
email: string;
|
|
542
|
+
}
|
|
543
|
+
```
|
|
468
544
|
|
|
469
545
|
### Enums
|
|
470
546
|
|
package/dist/autoswagger.js
CHANGED
|
@@ -279,22 +279,23 @@ class AutoSwagger {
|
|
|
279
279
|
description: "The resource has been created",
|
|
280
280
|
},
|
|
281
281
|
},
|
|
282
|
-
securitySchemes:
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
282
|
+
securitySchemes: this.options.securitySchemes
|
|
283
|
+
? this.options.securitySchemes
|
|
284
|
+
: {
|
|
285
|
+
BearerAuth: {
|
|
286
|
+
type: "http",
|
|
287
|
+
scheme: "bearer",
|
|
288
|
+
},
|
|
289
|
+
BasicAuth: {
|
|
290
|
+
type: "http",
|
|
291
|
+
scheme: "basic",
|
|
292
|
+
},
|
|
293
|
+
ApiKeyAuth: {
|
|
294
|
+
type: "apiKey",
|
|
295
|
+
in: "header",
|
|
296
|
+
name: "X-API-Key",
|
|
297
|
+
},
|
|
295
298
|
},
|
|
296
|
-
...this.options.securitySchemes,
|
|
297
|
-
},
|
|
298
299
|
schemas: this.schemas,
|
|
299
300
|
},
|
|
300
301
|
paths: {},
|
|
@@ -675,10 +676,12 @@ class AutoSwagger {
|
|
|
675
676
|
}
|
|
676
677
|
let schema = {
|
|
677
678
|
type: "object",
|
|
678
|
-
required: parsed.required,
|
|
679
679
|
properties: parsed.props,
|
|
680
680
|
description: name + " (Model)",
|
|
681
681
|
};
|
|
682
|
+
if (parsed.required.length > 0) {
|
|
683
|
+
schema['required'] = parsed.required;
|
|
684
|
+
}
|
|
682
685
|
models[name] = schema;
|
|
683
686
|
}
|
|
684
687
|
return models;
|
package/dist/parsers.d.ts
CHANGED
|
@@ -52,11 +52,14 @@ export declare class ValidatorParser {
|
|
|
52
52
|
validatorToObject(validator: VineValidator<any, any>): Promise<any>;
|
|
53
53
|
parsePropsAndMeta(obj: any, testObj: any, validator: VineValidator<any, any>): Promise<any>;
|
|
54
54
|
objToTest(obj: any): {};
|
|
55
|
-
parseSchema(json: any, refs: any): {
|
|
55
|
+
parseSchema(json: any, refs: any): {
|
|
56
|
+
properties: {};
|
|
57
|
+
};
|
|
58
|
+
getType(type: string): string;
|
|
56
59
|
getMetaFromValidations(validations: any, refs: any): {
|
|
57
60
|
minimum?: number;
|
|
58
61
|
maximum?: number;
|
|
59
|
-
|
|
62
|
+
enum?: any;
|
|
60
63
|
pattern?: string;
|
|
61
64
|
example?: any;
|
|
62
65
|
};
|
package/dist/parsers.js
CHANGED
|
@@ -110,7 +110,7 @@ class CommentParser {
|
|
|
110
110
|
return h;
|
|
111
111
|
}
|
|
112
112
|
if (line.startsWith("@paramPath")) {
|
|
113
|
-
required =
|
|
113
|
+
required = true;
|
|
114
114
|
}
|
|
115
115
|
if (line.startsWith("@paramQuery")) {
|
|
116
116
|
required = false;
|
|
@@ -688,7 +688,7 @@ class ValidatorParser {
|
|
|
688
688
|
// console.dir(json, { depth: null });
|
|
689
689
|
const obj = {
|
|
690
690
|
type: "object",
|
|
691
|
-
|
|
691
|
+
...this.parseSchema(validator.toJSON()["schema"]["schema"], validator.toJSON()["refs"]),
|
|
692
692
|
};
|
|
693
693
|
// console.dir(obj, { depth: null });
|
|
694
694
|
const testObj = this.objToTest(obj["properties"]);
|
|
@@ -779,6 +779,7 @@ class ValidatorParser {
|
|
|
779
779
|
}
|
|
780
780
|
parseSchema(json, refs) {
|
|
781
781
|
const obj = {};
|
|
782
|
+
const required = [];
|
|
782
783
|
for (const p of json["properties"]) {
|
|
783
784
|
let meta = this.getMetaFromValidations(p["validations"], refs);
|
|
784
785
|
// console.dir(p, { depth: null });
|
|
@@ -788,7 +789,7 @@ class ValidatorParser {
|
|
|
788
789
|
const field = p["fieldName"];
|
|
789
790
|
if (type === "object") {
|
|
790
791
|
console.log(field, p);
|
|
791
|
-
obj[field] = { type: "object",
|
|
792
|
+
obj[field] = { type: "object", ...this.parseSchema(p, refs) };
|
|
792
793
|
}
|
|
793
794
|
else {
|
|
794
795
|
// if array
|
|
@@ -798,7 +799,7 @@ class ValidatorParser {
|
|
|
798
799
|
type: "array",
|
|
799
800
|
items: {
|
|
800
801
|
type: "object",
|
|
801
|
-
|
|
802
|
+
...this.parseSchema(p["each"], refs),
|
|
802
803
|
}
|
|
803
804
|
};
|
|
804
805
|
}
|
|
@@ -807,7 +808,7 @@ class ValidatorParser {
|
|
|
807
808
|
obj[field] = {
|
|
808
809
|
type: "array",
|
|
809
810
|
items: {
|
|
810
|
-
type: "
|
|
811
|
+
type: this.getType(p["each"]["type"]),
|
|
811
812
|
...meta,
|
|
812
813
|
example: meta.example ?? meta.minimum ?? this.exampleGenerator.exampleByType("number"),
|
|
813
814
|
},
|
|
@@ -816,16 +817,25 @@ class ValidatorParser {
|
|
|
816
817
|
}
|
|
817
818
|
else {
|
|
818
819
|
obj[field] = {
|
|
819
|
-
type:
|
|
820
|
+
type: this.getType(type),
|
|
820
821
|
example: meta.example ?? meta.minimum ?? this.exampleGenerator.exampleByType("number"),
|
|
821
822
|
...meta,
|
|
822
823
|
};
|
|
823
824
|
}
|
|
824
825
|
}
|
|
825
826
|
if (!p["isOptional"])
|
|
826
|
-
|
|
827
|
+
required.push(p["fieldName"]);
|
|
827
828
|
}
|
|
828
|
-
|
|
829
|
+
const res = { properties: obj };
|
|
830
|
+
if (required.length > 0)
|
|
831
|
+
res["required"] = required;
|
|
832
|
+
return res;
|
|
833
|
+
}
|
|
834
|
+
getType(type) {
|
|
835
|
+
if (type == 'literal') {
|
|
836
|
+
return 'string';
|
|
837
|
+
}
|
|
838
|
+
return type;
|
|
829
839
|
}
|
|
830
840
|
getMetaFromValidations(validations, refs) {
|
|
831
841
|
let meta = {};
|
|
@@ -840,7 +850,7 @@ class ValidatorParser {
|
|
|
840
850
|
meta = { ...meta, maximum: refs[v["ruleFnId"]].options.max };
|
|
841
851
|
}
|
|
842
852
|
if (refs[v["ruleFnId"]].options?.choices) {
|
|
843
|
-
meta = { ...meta,
|
|
853
|
+
meta = { ...meta, enum: refs[v["ruleFnId"]].options.choices };
|
|
844
854
|
}
|
|
845
855
|
if (refs[v["ruleFnId"]].options?.toString().includes("/")) {
|
|
846
856
|
meta = { ...meta, pattern: refs[v["ruleFnId"]].options.toString() };
|
package/package.json
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@necessarylion/adonis-autoswagger",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Auto-Generate swagger docs for AdonisJS",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
9
|
+
"dev": "watchexec -e ts -- tsc",
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"prepare": "npm run build"
|
|
12
|
+
},
|
|
7
13
|
"author": "Adis Durakovic <adis.durakovic@gmail.com>",
|
|
8
14
|
"repository": {
|
|
9
15
|
"type": "git",
|
|
@@ -38,10 +44,5 @@
|
|
|
38
44
|
"bracketSpacing": true,
|
|
39
45
|
"arrowParens": "always"
|
|
40
46
|
},
|
|
41
|
-
"packageManager": "pnpm@8.11.0"
|
|
42
|
-
|
|
43
|
-
"test": "echo \"Error: no test specified\" && exit 1",
|
|
44
|
-
"dev": "watchexec -e ts -- tsc",
|
|
45
|
-
"build": "tsc"
|
|
46
|
-
}
|
|
47
|
-
}
|
|
47
|
+
"packageManager": "pnpm@8.11.0"
|
|
48
|
+
}
|