nest-prisma_doc-gen 1.0.9 → 1.0.11
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 +1 -1
- package/dist/entities/entity-generator.js +1 -1
- package/dist/main.js +4 -4
- package/dist/utils/helpers.js +32 -40
- package/dist/utils/prisma-utils.js +42 -0
- package/package.json +2 -2
- package/dist/testes.js +0 -21
- package/dist/utils/config-loader.js +0 -33
- package/dist/utils/copy-schemas.js +0 -10
|
@@ -40,7 +40,7 @@ export class DocGenDto {
|
|
|
40
40
|
.join("\n\n");
|
|
41
41
|
if (this.enums.size > 0) {
|
|
42
42
|
this.classValidators.add("IsEnum");
|
|
43
|
-
this.imports.add(`import { ${Array.from(this.enums)} } from '
|
|
43
|
+
this.imports.add(`import { ${Array.from(this.enums)} } from '@prisma/client';`);
|
|
44
44
|
}
|
|
45
45
|
this.imports.add(`import { ${Array.from(this.classValidators)} } from 'src/utils/validators';`);
|
|
46
46
|
return [
|
|
@@ -35,7 +35,7 @@ export class DocGenEntity {
|
|
|
35
35
|
})
|
|
36
36
|
.join("\n\n");
|
|
37
37
|
if (this.enums.size > 0) {
|
|
38
|
-
this.imports.add(`import { ${Array.from(this.enums)} } from '
|
|
38
|
+
this.imports.add(`import { ${Array.from(this.enums)} } from '@prisma/client';`);
|
|
39
39
|
}
|
|
40
40
|
return [
|
|
41
41
|
`${Array.from(this.imports).join("\n")}`,
|
package/dist/main.js
CHANGED
|
@@ -3,11 +3,11 @@ import * as path from "node:path";
|
|
|
3
3
|
import { DocEnums, DocGenEnum } from "./entities/enum.js";
|
|
4
4
|
import { DocGenModel } from "./entities/model.js";
|
|
5
5
|
import { DocFields } from "./field.type.js";
|
|
6
|
-
import { Helper } from "./utils/helpers.js";
|
|
7
6
|
import prismaPkg from "@prisma/internals";
|
|
7
|
+
import { PrismaUtils } from "./utils/prisma-utils.js";
|
|
8
8
|
const { getDMMF } = prismaPkg;
|
|
9
9
|
const ROOT = process.cwd();
|
|
10
|
-
const PRISMA_DIR = path.join(ROOT, "
|
|
10
|
+
const PRISMA_DIR = path.join(ROOT, "src");
|
|
11
11
|
export class DocGen {
|
|
12
12
|
datamodel;
|
|
13
13
|
properties;
|
|
@@ -15,7 +15,7 @@ export class DocGen {
|
|
|
15
15
|
fields;
|
|
16
16
|
models;
|
|
17
17
|
async init() {
|
|
18
|
-
const prismaDataModel = await
|
|
18
|
+
const prismaDataModel = await PrismaUtils.readPrismaFolderDatamodel(PRISMA_DIR);
|
|
19
19
|
const { datamodel } = await getDMMF({ datamodel: prismaDataModel });
|
|
20
20
|
this.enums = new DocEnums(datamodel.enums.map(({ dbName, name, values }) => {
|
|
21
21
|
return new DocGenEnum({
|
|
@@ -38,7 +38,7 @@ export class DocGen {
|
|
|
38
38
|
}
|
|
39
39
|
build() {
|
|
40
40
|
this.fields.file.save();
|
|
41
|
-
this.enums.file.save();
|
|
41
|
+
// this.enums.file.save();
|
|
42
42
|
for (const model of this.models) {
|
|
43
43
|
model.save();
|
|
44
44
|
}
|
package/dist/utils/helpers.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { promises as fs } from "node:fs";
|
|
2
|
-
import * as path from "node:path";
|
|
3
1
|
export class Helper {
|
|
4
2
|
static prismaScalarToTs(s) {
|
|
5
3
|
switch (s) {
|
|
@@ -83,44 +81,38 @@ export class Helper {
|
|
|
83
81
|
hasDate: model.fields.some((field) => field.kind === "scalar" && field.type === "DateTime"),
|
|
84
82
|
};
|
|
85
83
|
}
|
|
86
|
-
static async readPrismaFolderDatamodel(dir) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
return `${head}\n${tail}`;
|
|
119
|
-
}
|
|
120
|
-
// caso não exista schema.prisma, apenas concatena
|
|
121
|
-
const contents = await Promise.all(files.map(async (f) => (f.startsWith("\n// ---- ") ? f : fs.readFile(f, "utf-8"))));
|
|
122
|
-
return contents.join("\n");
|
|
123
|
-
}
|
|
84
|
+
// static async readPrismaFolderDatamodel(dir: string): Promise<string> {
|
|
85
|
+
// const files: string[] = [];
|
|
86
|
+
// const entries = await fs.readdir(dir, { withFileTypes: true });
|
|
87
|
+
// const mainSchemaPath = path.join(dir, "schema.prisma");
|
|
88
|
+
// try {
|
|
89
|
+
// const mainStat = await fs.stat(mainSchemaPath);
|
|
90
|
+
// if (mainStat.isFile()) files.push(mainSchemaPath);
|
|
91
|
+
// } catch {}
|
|
92
|
+
// // varrer demais itens (exceto migrations e o schema.prisma já incluído)
|
|
93
|
+
// for (const entry of entries) {
|
|
94
|
+
// if (entry.name === "migrations") continue;
|
|
95
|
+
// const full = path.join(dir, entry.name);
|
|
96
|
+
// if (entry.isDirectory()) {
|
|
97
|
+
// const nested = await this.readPrismaFolderDatamodel(full);
|
|
98
|
+
// if (nested.trim()) files.push(`\n// ---- ${full} ----\n${nested}`);
|
|
99
|
+
// } else if (entry.isFile() && entry.name.endsWith(".prisma") && full !== mainSchemaPath) {
|
|
100
|
+
// const content = await fs.readFile(full, "utf-8");
|
|
101
|
+
// files.push(`\n// ---- ${full} ----\n${content}`);
|
|
102
|
+
// }
|
|
103
|
+
// }
|
|
104
|
+
// // se não houver nada além de subpastas, retorna o que juntou nelas
|
|
105
|
+
// if (!files.length) return "";
|
|
106
|
+
// // quando schema.prisma existe, ele já está no topo do array
|
|
107
|
+
// if (files[0] === mainSchemaPath) {
|
|
108
|
+
// const head = await fs.readFile(mainSchemaPath, "utf-8");
|
|
109
|
+
// const tail = files.slice(1).join("\n");
|
|
110
|
+
// return `${head}\n${tail}`;
|
|
111
|
+
// }
|
|
112
|
+
// // caso não exista schema.prisma, apenas concatena
|
|
113
|
+
// const contents = await Promise.all(files.map(async (f) => (f.startsWith("\n// ---- ") ? f : fs.readFile(f, "utf-8"))));
|
|
114
|
+
// return contents.join("\n");
|
|
115
|
+
// }
|
|
124
116
|
findTypeForField(field) {
|
|
125
117
|
if (field.kind === "scalar") {
|
|
126
118
|
const base = Helper.prismaScalarToTs(field.type);
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { promises as fs } from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
export class PrismaUtils {
|
|
4
|
+
static async readPrismaFolderDatamodel(dir) {
|
|
5
|
+
const prismaFiles = [];
|
|
6
|
+
// percorre recursivamente e guarda TODOS os .prisma (exceto dentro de migrations)
|
|
7
|
+
const walk = async (currentDir) => {
|
|
8
|
+
const entries = await fs.readdir(currentDir, { withFileTypes: true });
|
|
9
|
+
for (const entry of entries) {
|
|
10
|
+
if (entry.name === "migrations")
|
|
11
|
+
continue;
|
|
12
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
13
|
+
if (entry.isDirectory()) {
|
|
14
|
+
await walk(fullPath);
|
|
15
|
+
}
|
|
16
|
+
else if (entry.isFile() && entry.name.endsWith(".prisma")) {
|
|
17
|
+
prismaFiles.push(fullPath);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
await walk(dir);
|
|
22
|
+
if (!prismaFiles.length)
|
|
23
|
+
return "";
|
|
24
|
+
// garantir que main.prisma (se existir) venha primeiro
|
|
25
|
+
prismaFiles.sort((a, b) => {
|
|
26
|
+
const aIsMain = path.basename(a) === "main.prisma";
|
|
27
|
+
const bIsMain = path.basename(b) === "main.prisma";
|
|
28
|
+
if (aIsMain && !bIsMain)
|
|
29
|
+
return -1;
|
|
30
|
+
if (!aIsMain && bIsMain)
|
|
31
|
+
return 1;
|
|
32
|
+
// fallback: ordem alfabética estável
|
|
33
|
+
return a.localeCompare(b);
|
|
34
|
+
});
|
|
35
|
+
const chunks = [];
|
|
36
|
+
for (const file of prismaFiles) {
|
|
37
|
+
const content = await fs.readFile(file, "utf-8");
|
|
38
|
+
chunks.push(`\n// ---- ${file} ----\n${content}`);
|
|
39
|
+
}
|
|
40
|
+
return chunks.join("\n");
|
|
41
|
+
}
|
|
42
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nest-prisma_doc-gen",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.11",
|
|
4
4
|
"description": "Auto generates ApiProperties from schema.prisma",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"author": "Alessandro Lepore",
|
|
29
29
|
"license": "ISC",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@prisma/internals": "^
|
|
31
|
+
"@prisma/internals": "^7.0.0",
|
|
32
32
|
"ajv": "^8.17.1",
|
|
33
33
|
"ajv-formats": "^3.0.1",
|
|
34
34
|
"prettier": "^3.6.2",
|
package/dist/testes.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// import { Ajv } from "ajv";
|
|
2
|
-
// import schema from "./schemas/config.schema.json" with { type: "json" };
|
|
3
|
-
export {};
|
|
4
|
-
// const ajv = new Ajv();
|
|
5
|
-
// const validate = ajv.compile(schema);
|
|
6
|
-
// const data = {
|
|
7
|
-
// ignore: ["senha", "id"],
|
|
8
|
-
// examples: [
|
|
9
|
-
// { fields: ["name"], example: "João" },
|
|
10
|
-
// { fields: ["idade"], example: 30 },
|
|
11
|
-
// ],
|
|
12
|
-
// validators: [
|
|
13
|
-
// { decorator: "IsString", fields: ["name"] },
|
|
14
|
-
// { decorator: "IsInt", fields: ["idade"] },
|
|
15
|
-
// ],
|
|
16
|
-
// };
|
|
17
|
-
// if (validate(data)) {
|
|
18
|
-
// console.log("✅ JSON válido!");
|
|
19
|
-
// } else {
|
|
20
|
-
// console.error("❌ Erros:", validate.errors);
|
|
21
|
-
// }
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
// import * as fs from "node:fs/promises";
|
|
2
|
-
// import * as path from "node:path";
|
|
3
|
-
// import { fileURLToPath } from "node:url";
|
|
4
|
-
// import Ajv from "ajv";
|
|
5
|
-
// import addFormats from "ajv-formats";
|
|
6
|
-
// import { DocGenRules } from "nest-prisma_doc-gen";
|
|
7
|
-
export {};
|
|
8
|
-
// // Caminho absoluto do diretório da lib (onde este arquivo está)
|
|
9
|
-
// const __filename = fileURLToPath(import.meta.url);
|
|
10
|
-
// const __dirname = path.dirname(__filename);
|
|
11
|
-
// // Caminho para o schema dentro da lib
|
|
12
|
-
// const SCHEMA_PATH = path.join(__dirname, "../schemas/config.schema.json");
|
|
13
|
-
// // Caminho para o config do projeto (que será validado)
|
|
14
|
-
// const CONFIG_PATH = path.join(process.cwd(), "doc-gen.config.json");
|
|
15
|
-
// async function readJson(filePath: string) {
|
|
16
|
-
// const content = await fs.readFile(filePath, "utf8");
|
|
17
|
-
// return JSON.parse(content);
|
|
18
|
-
// }
|
|
19
|
-
// export async function loadDocGenConfig() {
|
|
20
|
-
// // Lê os dois arquivos
|
|
21
|
-
// const [schema, config] = (await Promise.all([readJson(SCHEMA_PATH), readJson(CONFIG_PATH)])) as [any, DocGenRules];
|
|
22
|
-
// // Configura o validador
|
|
23
|
-
// const ajv = new Ajv.Ajv({ allErrors: true, strict: false });
|
|
24
|
-
// addFormats.default(ajv);
|
|
25
|
-
// const validate = ajv.compile(schema);
|
|
26
|
-
// const valid = validate(config);
|
|
27
|
-
// if (!valid) {
|
|
28
|
-
// const errors = (validate.errors ?? []).map((e) => `${e.instancePath || "(root)"} ${e.message}`).join("\n - ");
|
|
29
|
-
// throw new Error(`❌ Config inválida em ${path.basename(CONFIG_PATH)}:\n - ${errors}`);
|
|
30
|
-
// }
|
|
31
|
-
// console.log("✅ Configuração válida!");
|
|
32
|
-
// return { config, path: CONFIG_PATH };
|
|
33
|
-
// }
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
5
|
-
const __dirname = path.dirname(__filename);
|
|
6
|
-
const src = path.join(__dirname, "../schemas/config.schema.json");
|
|
7
|
-
const destDir = path.join(__dirname, "../dist/schemas");
|
|
8
|
-
fs.mkdirSync(destDir, { recursive: true });
|
|
9
|
-
fs.copyFileSync(src, path.join(destDir, "config.schema.json"));
|
|
10
|
-
console.log("✅ Copiado config.schema.json para dist/schemas/");
|