nest-prisma_doc-gen 1.0.12 → 1.0.14
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/dist/entities/dto-generator.js +12 -4
- package/dist/entities/enum.js +40 -37
- package/dist/entities/field.js +19 -16
- package/dist/entities/generic.js +23 -0
- package/dist/entities/model.js +7 -7
- package/dist/entities/response-generator.js +47 -0
- package/dist/main.js +13 -9
- package/package.json +1 -1
|
@@ -6,7 +6,11 @@ export class DocGenDto {
|
|
|
6
6
|
name;
|
|
7
7
|
file;
|
|
8
8
|
fields = [];
|
|
9
|
-
imports = new Set([
|
|
9
|
+
imports = new Set([
|
|
10
|
+
`${Static.AUTO_GENERATED_COMMENT}`,
|
|
11
|
+
`import { ApiProperty, IntersectionType } from '@nestjs/swagger'`,
|
|
12
|
+
`import { DefaultIdDto } from '../generic.dto'`,
|
|
13
|
+
]);
|
|
10
14
|
classValidators = new Set();
|
|
11
15
|
enums = new Set();
|
|
12
16
|
constructor(model) {
|
|
@@ -28,8 +32,8 @@ export class DocGenDto {
|
|
|
28
32
|
for (const { name } of field.validators) {
|
|
29
33
|
this.classValidators.add(name);
|
|
30
34
|
}
|
|
31
|
-
if (field.
|
|
32
|
-
this.imports.add(`import { ${field.type} } from '../entities/${Helper.toKebab(field.scalarType)}.
|
|
35
|
+
if (field.isResponse) {
|
|
36
|
+
this.imports.add(`import { ${field.type} } from '../entities/${Helper.toKebab(field.scalarType)}.response'`);
|
|
33
37
|
this.imports.add(`import { generateExample } from 'src/utils/functions/reflect'`);
|
|
34
38
|
}
|
|
35
39
|
else if (field.isEnum) {
|
|
@@ -42,12 +46,16 @@ export class DocGenDto {
|
|
|
42
46
|
this.classValidators.add("IsEnum");
|
|
43
47
|
this.imports.add(`import { ${Array.from(this.enums)} } from '@prisma/client';`);
|
|
44
48
|
}
|
|
45
|
-
this.imports.add(`import { ${Array.from(this.classValidators)} } from 'src/
|
|
49
|
+
this.imports.add(`import { ${Array.from(this.classValidators)} } from 'src/_core/validators';`);
|
|
46
50
|
return [
|
|
47
51
|
`${Array.from(this.imports).join("\n")}`,
|
|
48
52
|
`export class ${this.name}Dto {
|
|
49
53
|
${sanitizedFields}
|
|
50
54
|
}`,
|
|
55
|
+
`export class ${this.name}WithIdDto extends IntersectionType(
|
|
56
|
+
${this.name}Dto,
|
|
57
|
+
DefaultIdDto,
|
|
58
|
+
) {}`,
|
|
51
59
|
].join("\n\n");
|
|
52
60
|
}
|
|
53
61
|
}
|
package/dist/entities/enum.js
CHANGED
|
@@ -1,37 +1,40 @@
|
|
|
1
|
-
import { DocGenFile } from "../file.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
}
|
|
1
|
+
// import { DocGenFile } from "../file.js";
|
|
2
|
+
// import { DbName } from "../types.js";
|
|
3
|
+
export {};
|
|
4
|
+
// export type EnumValue = { name: string; dbName: DbName };
|
|
5
|
+
// export class DocGenEnum {
|
|
6
|
+
// name: string;
|
|
7
|
+
// values: EnumValue[];
|
|
8
|
+
// dbName: DbName;
|
|
9
|
+
// constructor(params: { name: string; values: EnumValue[]; dbName: DbName }) {
|
|
10
|
+
// const { dbName, name, values } = params;
|
|
11
|
+
// this.dbName = dbName;
|
|
12
|
+
// this.name = name;
|
|
13
|
+
// this.values = values;
|
|
14
|
+
// }
|
|
15
|
+
// }
|
|
16
|
+
// export class DocEnums {
|
|
17
|
+
// enums: DocGenEnum[];
|
|
18
|
+
// file: DocGenFile;
|
|
19
|
+
// constructor(enums: DocGenEnum[]) {
|
|
20
|
+
// this.enums = enums;
|
|
21
|
+
// this.file = new DocGenFile({
|
|
22
|
+
// dir: "/",
|
|
23
|
+
// fileName: "enums.ts",
|
|
24
|
+
// data: this.build(),
|
|
25
|
+
// });
|
|
26
|
+
// }
|
|
27
|
+
// build() {
|
|
28
|
+
// const enums = this.enums.map((en) => {
|
|
29
|
+
// const enumName = en.name;
|
|
30
|
+
// return `
|
|
31
|
+
// export const ${enumName} = [${en.values.map((n) => `'${n.name}'`)}] as const;
|
|
32
|
+
// export type ${enumName} = typeof ${enumName}[number];
|
|
33
|
+
// `;
|
|
34
|
+
// });
|
|
35
|
+
// return `
|
|
36
|
+
// // AUTO-GERADO: NÃO EDITAR MANUALMENTE. SUJEITO A PAULADAS!
|
|
37
|
+
// ${enums.join("\n")}
|
|
38
|
+
// `;
|
|
39
|
+
// }
|
|
40
|
+
// }
|
package/dist/entities/field.js
CHANGED
|
@@ -5,14 +5,14 @@ const helpers = new Helper();
|
|
|
5
5
|
const rules = config;
|
|
6
6
|
export class DocGenField {
|
|
7
7
|
name;
|
|
8
|
-
|
|
8
|
+
isArray;
|
|
9
9
|
default;
|
|
10
10
|
scalarType;
|
|
11
11
|
kind;
|
|
12
12
|
type;
|
|
13
13
|
fieldType;
|
|
14
14
|
isEnum = false;
|
|
15
|
-
|
|
15
|
+
isResponse = false;
|
|
16
16
|
isUpdatedAt = false;
|
|
17
17
|
isRequired;
|
|
18
18
|
validators = new Set();
|
|
@@ -20,7 +20,7 @@ export class DocGenField {
|
|
|
20
20
|
constructor(field, fieldType) {
|
|
21
21
|
const { name, isList, type, kind, isRequired, isUpdatedAt } = field;
|
|
22
22
|
this.name = name;
|
|
23
|
-
this.
|
|
23
|
+
this.isArray = isList;
|
|
24
24
|
this.scalarType = type;
|
|
25
25
|
this.kind = kind;
|
|
26
26
|
this.isRequired = isRequired;
|
|
@@ -32,7 +32,7 @@ export class DocGenField {
|
|
|
32
32
|
}
|
|
33
33
|
processValidator(name) {
|
|
34
34
|
const validator = new Validator({ name });
|
|
35
|
-
if (this.
|
|
35
|
+
if (this.isArray)
|
|
36
36
|
validator.content = "{ each: true }";
|
|
37
37
|
this.validators.add(validator);
|
|
38
38
|
}
|
|
@@ -52,16 +52,17 @@ export class DocGenField {
|
|
|
52
52
|
this.scalarType === "Decimal") {
|
|
53
53
|
this.processValidator("IsNumber");
|
|
54
54
|
}
|
|
55
|
-
if (this.
|
|
55
|
+
if (this.isArray) {
|
|
56
56
|
const validator = new Validator({ name: "IsArray" });
|
|
57
57
|
this.validators.add(validator);
|
|
58
58
|
}
|
|
59
59
|
if (!this.isRequired)
|
|
60
60
|
this.processValidator("IsOptional");
|
|
61
61
|
if (this.isEnum) {
|
|
62
|
+
const content = this.isArray ? `${this.type}, { each: true } ` : this.type;
|
|
62
63
|
this.validators.add(new Validator({
|
|
63
64
|
name: "IsEnum",
|
|
64
|
-
content
|
|
65
|
+
content,
|
|
65
66
|
}));
|
|
66
67
|
}
|
|
67
68
|
const findedDecorators = rules.validators.get(this.name);
|
|
@@ -77,8 +78,8 @@ export class DocGenField {
|
|
|
77
78
|
this.type = this.scalarType;
|
|
78
79
|
}
|
|
79
80
|
else if (this.kind === "object") {
|
|
80
|
-
this.
|
|
81
|
-
this.type = `${this.scalarType}
|
|
81
|
+
this.isResponse = true;
|
|
82
|
+
this.type = `${this.scalarType}Res`;
|
|
82
83
|
}
|
|
83
84
|
else if (this.kind === "scalar") {
|
|
84
85
|
this.type = Helper.prismaScalarToTs(this.scalarType);
|
|
@@ -87,8 +88,8 @@ export class DocGenField {
|
|
|
87
88
|
buildApiExample() {
|
|
88
89
|
const fieldName = this.scalarField.name;
|
|
89
90
|
const props = [];
|
|
90
|
-
if (this.
|
|
91
|
-
if (this.
|
|
91
|
+
if (this.isResponse) {
|
|
92
|
+
if (this.isArray) {
|
|
92
93
|
props.push(`example: [generateExample(${this.type})]`);
|
|
93
94
|
}
|
|
94
95
|
else {
|
|
@@ -108,7 +109,9 @@ export class DocGenField {
|
|
|
108
109
|
props.push(`example: true`);
|
|
109
110
|
}
|
|
110
111
|
else if (this.scalarField.kind === "enum") {
|
|
111
|
-
|
|
112
|
+
const example = [`example: Object.values(${this.scalarField.type})`];
|
|
113
|
+
this.isArray ?? example.push("[0]");
|
|
114
|
+
props.push(example.join());
|
|
112
115
|
}
|
|
113
116
|
else if (this.scalarField.type === "Int") {
|
|
114
117
|
props.push(`example: 777`);
|
|
@@ -135,19 +138,19 @@ export class DocGenField {
|
|
|
135
138
|
const apiType = () => {
|
|
136
139
|
if (this.type === "Date")
|
|
137
140
|
return `'string'`;
|
|
138
|
-
if (this.
|
|
141
|
+
if (this.isArray && this.isResponse) {
|
|
139
142
|
return `[${this.type}]`;
|
|
140
143
|
}
|
|
141
144
|
else if (this.isEnum) {
|
|
142
|
-
return this.type
|
|
145
|
+
return `${this.type}`;
|
|
143
146
|
}
|
|
144
|
-
else if (this.
|
|
147
|
+
else if (this.isResponse) {
|
|
145
148
|
return `() => ${this.type}`;
|
|
146
149
|
}
|
|
147
150
|
return `'${this.type}'`;
|
|
148
151
|
};
|
|
149
152
|
const fieldType = () => {
|
|
150
|
-
if (this.
|
|
153
|
+
if (this.isArray) {
|
|
151
154
|
return `${this.type}[]`;
|
|
152
155
|
}
|
|
153
156
|
else {
|
|
@@ -158,7 +161,7 @@ export class DocGenField {
|
|
|
158
161
|
const validators = this.sanitizeValidators();
|
|
159
162
|
const apiExample = this.buildApiExample().join(", ");
|
|
160
163
|
return {
|
|
161
|
-
apiProperty: `@ApiProperty({ ${key}: ${apiType()}, ${apiExample} })`,
|
|
164
|
+
apiProperty: `@ApiProperty({ ${key}: ${apiType()}, ${apiExample}, ${this.isArray ? "isArray: true" : ""} })`,
|
|
162
165
|
validators,
|
|
163
166
|
atributes: `${this.name}${optionalFlag}: ${fieldType()};`,
|
|
164
167
|
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { DocGenFile } from "../file.js";
|
|
2
|
+
export class DocGenGeneric {
|
|
3
|
+
file;
|
|
4
|
+
constructor() {
|
|
5
|
+
const imports = `
|
|
6
|
+
import { ApiProperty } from '@nestjs/swagger';
|
|
7
|
+
import { IsString, IsNotEmpty } from 'src/_core/validators';
|
|
8
|
+
`;
|
|
9
|
+
const validatorProps = `
|
|
10
|
+
export class DefaultIdDto {
|
|
11
|
+
@ApiProperty({ type: 'string', example: 'cmfxu4njg000008l52v7t8qze', required: true })
|
|
12
|
+
@IsString()
|
|
13
|
+
@IsNotEmpty()
|
|
14
|
+
id!: string;
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
17
|
+
const fileContent = [imports, validatorProps];
|
|
18
|
+
this.file = new DocGenFile({ fileName: "generic.dto.ts", data: fileContent.join("\n"), dir: "" });
|
|
19
|
+
}
|
|
20
|
+
build() {
|
|
21
|
+
this.file.save();
|
|
22
|
+
}
|
|
23
|
+
}
|
package/dist/entities/model.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { DocGenDto } from "./dto-generator.js";
|
|
2
|
-
import {
|
|
2
|
+
import { DocGenResponse } from "./response-generator.js";
|
|
3
3
|
export class DocGenModel {
|
|
4
4
|
name;
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
responses;
|
|
6
|
+
dtos;
|
|
7
7
|
fields;
|
|
8
8
|
constructor(model) {
|
|
9
9
|
this.name = model.name;
|
|
10
10
|
this.fields = model.fields;
|
|
11
|
-
this.
|
|
12
|
-
this.
|
|
11
|
+
this.responses = new DocGenResponse(model);
|
|
12
|
+
this.dtos = new DocGenDto(model);
|
|
13
13
|
}
|
|
14
14
|
save() {
|
|
15
|
-
this.
|
|
16
|
-
this.
|
|
15
|
+
this.responses.file.save();
|
|
16
|
+
this.dtos.file.save();
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { DocGenFile } from "../file.js";
|
|
2
|
+
import { Helper } from "../utils/helpers.js";
|
|
3
|
+
import { Static } from "../static.js";
|
|
4
|
+
import { DocGenField } from "./field.js";
|
|
5
|
+
export class DocGenResponse {
|
|
6
|
+
name;
|
|
7
|
+
file;
|
|
8
|
+
fields = [];
|
|
9
|
+
imports = new Set([`${Static.AUTO_GENERATED_COMMENT}`, `import { ApiProperty } from '@nestjs/swagger'`]);
|
|
10
|
+
enums = new Set();
|
|
11
|
+
constructor(model) {
|
|
12
|
+
this.name = model.name;
|
|
13
|
+
for (const field of model.fields) {
|
|
14
|
+
if (field.kind === "object")
|
|
15
|
+
continue;
|
|
16
|
+
this.fields.push(new DocGenField(field, "res"));
|
|
17
|
+
}
|
|
18
|
+
this.file = new DocGenFile({
|
|
19
|
+
dir: "/res",
|
|
20
|
+
fileName: `${Helper.toKebab(this.name)}.res.ts`,
|
|
21
|
+
data: this.build(),
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
build() {
|
|
25
|
+
const sanitizedFields = this.fields
|
|
26
|
+
.map((field) => {
|
|
27
|
+
if (field.isResponse) {
|
|
28
|
+
this.imports.add(`import { ${field.type} } from './${Helper.toKebab(field.scalarType)}.res'`);
|
|
29
|
+
this.imports.add(`import { generateExample } from 'src/utils/functions/reflect'`);
|
|
30
|
+
}
|
|
31
|
+
else if (field.isEnum) {
|
|
32
|
+
this.enums.add(field.type);
|
|
33
|
+
}
|
|
34
|
+
return field.build();
|
|
35
|
+
})
|
|
36
|
+
.join("\n\n");
|
|
37
|
+
if (this.enums.size > 0) {
|
|
38
|
+
this.imports.add(`import { ${Array.from(this.enums)} } from '@prisma/client';`);
|
|
39
|
+
}
|
|
40
|
+
return [
|
|
41
|
+
`${Array.from(this.imports).join("\n")}`,
|
|
42
|
+
`export class ${this.name}Res {
|
|
43
|
+
${sanitizedFields}
|
|
44
|
+
}`,
|
|
45
|
+
].join("\n\n");
|
|
46
|
+
}
|
|
47
|
+
}
|
package/dist/main.js
CHANGED
|
@@ -1,29 +1,32 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import { DocEnums, DocGenEnum } from "./entities/enum.js";
|
|
4
3
|
import { DocGenModel } from "./entities/model.js";
|
|
5
4
|
import { DocFields } from "./field.type.js";
|
|
6
5
|
import prismaPkg from "@prisma/internals";
|
|
7
6
|
import { PrismaUtils } from "./utils/prisma-utils.js";
|
|
7
|
+
import { DocGenGeneric } from "./entities/generic.js";
|
|
8
8
|
const { getDMMF } = prismaPkg;
|
|
9
9
|
const ROOT = process.cwd();
|
|
10
10
|
const PRISMA_DIR = path.join(ROOT, "src");
|
|
11
11
|
export class DocGen {
|
|
12
12
|
datamodel;
|
|
13
13
|
properties;
|
|
14
|
-
enums;
|
|
14
|
+
// enums!: DocEnums;
|
|
15
15
|
fields;
|
|
16
16
|
models;
|
|
17
|
+
generic = new DocGenGeneric();
|
|
17
18
|
async init() {
|
|
18
19
|
const prismaDataModel = await PrismaUtils.readPrismaFolderDatamodel(PRISMA_DIR);
|
|
19
20
|
const { datamodel } = await getDMMF({ datamodel: prismaDataModel });
|
|
20
|
-
this.enums = new DocEnums(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
})
|
|
21
|
+
// this.enums = new DocEnums(
|
|
22
|
+
// datamodel.enums.map(({ dbName, name, values }) => {
|
|
23
|
+
// return new DocGenEnum({
|
|
24
|
+
// dbName: dbName ?? "",
|
|
25
|
+
// name,
|
|
26
|
+
// values: values as EnumValue[],
|
|
27
|
+
// });
|
|
28
|
+
// })
|
|
29
|
+
// );
|
|
27
30
|
const fieldSet = new Set();
|
|
28
31
|
for (const model of datamodel.models) {
|
|
29
32
|
for (const field of model.fields) {
|
|
@@ -37,6 +40,7 @@ export class DocGen {
|
|
|
37
40
|
this.build();
|
|
38
41
|
}
|
|
39
42
|
build() {
|
|
43
|
+
this.generic.build();
|
|
40
44
|
this.fields.file.save();
|
|
41
45
|
for (const model of this.models) {
|
|
42
46
|
model.save();
|