prisma-entity-gen 0.1.0

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/index.cjs ADDED
@@ -0,0 +1,691 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs');
4
+ var path = require('path');
5
+ var zod = require('zod');
6
+ var prismaAst = require('@mrleebo/prisma-ast');
7
+
8
+ // src/config/loader.ts
9
+ var ConfigSchema = zod.z.object({
10
+ /**
11
+ * Caminho para o schema.prisma
12
+ * @default "prisma/schema.prisma"
13
+ */
14
+ schemaPath: zod.z.string().default("prisma/schema.prisma"),
15
+ /**
16
+ * Diretório de saída das entities geradas
17
+ * @default "src/entities"
18
+ */
19
+ outputDir: zod.z.string().default("src/entities"),
20
+ /**
21
+ * Modo de geração:
22
+ * - "type" → type aliases e interfaces puras (melhor performance TS)
23
+ * - "class" → classes com decorators (NestJS / class-validator)
24
+ * - "both" → gera os dois em subpastas /types e /classes
25
+ */
26
+ mode: zod.z.enum(["type", "class", "both"]).default("type"),
27
+ /**
28
+ * Quando mode="class", inclui decorators do class-validator
29
+ * @default false
30
+ */
31
+ classValidator: zod.z.boolean().default(false),
32
+ /**
33
+ * Quando mode="class", inclui decorators do class-transformer
34
+ * @default false
35
+ */
36
+ classTransformer: zod.z.boolean().default(false),
37
+ /**
38
+ * Gera barrel index.ts na raiz do outputDir
39
+ * @default true
40
+ */
41
+ barrel: zod.z.boolean().default(true),
42
+ /**
43
+ * Modelos a ignorar na geração
44
+ * @default []
45
+ */
46
+ exclude: zod.z.array(zod.z.string()).default([]),
47
+ /**
48
+ * Apenas esses modelos serão gerados (vazio = todos)
49
+ * @default []
50
+ */
51
+ include: zod.z.array(zod.z.string()).default([]),
52
+ /**
53
+ * Formato de saída dos enums:
54
+ * - "enum" → export enum Role { ADMIN = "ADMIN" }
55
+ * - "union" → export type Role = "ADMIN" | "USER"
56
+ * Use "union" para evitar conflitos com enums do @prisma/client
57
+ * @default "enum"
58
+ */
59
+ enumOutput: zod.z.enum(["enum", "union"]).default("enum"),
60
+ /**
61
+ * Define se campos de relação são opcionais ou obrigatórios na entity gerada:
62
+ * - "optional" → relações sempre com ? (compatível com queries sem include)
63
+ * - "required" → relações sem ? (requer include em toda query que retornar o tipo)
64
+ * @default "optional"
65
+ */
66
+ relations: zod.z.enum(["optional", "required"]).default("optional"),
67
+ /**
68
+ * Sufixo dos arquivos gerados
69
+ * @default "entity"
70
+ * Resulta em: user.entity.ts
71
+ */
72
+ suffix: zod.z.string().default("entity"),
73
+ /**
74
+ * Simula a geração sem escrever arquivos
75
+ * @default false
76
+ */
77
+ dryRun: zod.z.boolean().default(false),
78
+ /**
79
+ * Nível de log: "silent" | "info" | "verbose"
80
+ * @default "info"
81
+ */
82
+ logLevel: zod.z.enum(["silent", "info", "verbose"]).default("info")
83
+ });
84
+ var DEFAULT_CONFIG = ConfigSchema.parse({});
85
+
86
+ // src/config/loader.ts
87
+ var RC_FILES = [
88
+ ".entitygenrc.json",
89
+ "entitygen.config.json",
90
+ ".entitygenrc"
91
+ ];
92
+ var ConfigError = class extends Error {
93
+ constructor(message, cause) {
94
+ super(message, { cause });
95
+ this.name = "ConfigError";
96
+ }
97
+ };
98
+ function loadConfig(cwd = process.cwd()) {
99
+ const rcFile = RC_FILES.map((f) => path.resolve(cwd, f)).find(fs.existsSync);
100
+ if (!rcFile) {
101
+ return ConfigSchema.parse({});
102
+ }
103
+ let raw;
104
+ try {
105
+ raw = JSON.parse(fs.readFileSync(rcFile, "utf-8"));
106
+ } catch (err) {
107
+ throw new ConfigError(`Falha ao ler ${rcFile}: arquivo JSON inv\xE1lido`, err);
108
+ }
109
+ try {
110
+ return ConfigSchema.parse(raw);
111
+ } catch (err) {
112
+ if (err instanceof zod.ZodError) {
113
+ const messages = err.errors.map((e) => ` \u2022 ${e.path.join(".")} \u2014 ${e.message}`).join("\n");
114
+ throw new ConfigError(
115
+ `Config inv\xE1lido em ${rcFile}:
116
+ ${messages}`,
117
+ err
118
+ );
119
+ }
120
+ throw err;
121
+ }
122
+ }
123
+
124
+ // src/parser/types.ts
125
+ var PRISMA_TO_TS = {
126
+ String: "string",
127
+ Boolean: "boolean",
128
+ Int: "number",
129
+ BigInt: "bigint",
130
+ Float: "number",
131
+ Decimal: "string",
132
+ // Decimal não tem tipo nativo TS — string é mais seguro que number
133
+ DateTime: "Date",
134
+ Json: "Record<string, unknown>",
135
+ Bytes: "Buffer"
136
+ };
137
+ var SCALARS = new Set(Object.keys(PRISMA_TO_TS));
138
+ function isScalar(type) {
139
+ return SCALARS.has(type);
140
+ }
141
+ function resolveTsType(prismaType, knownEnums) {
142
+ if (isScalar(prismaType)) return PRISMA_TO_TS[prismaType];
143
+ if (knownEnums.has(prismaType)) return prismaType;
144
+ return prismaType;
145
+ }
146
+
147
+ // src/parser/relations.ts
148
+ function detectCircularRefs(graph) {
149
+ const color = /* @__PURE__ */ new Map();
150
+ const circular = /* @__PURE__ */ new Map();
151
+ for (const node of graph.keys()) {
152
+ color.set(node, "white");
153
+ circular.set(node, /* @__PURE__ */ new Set());
154
+ }
155
+ function addCircular(a, b) {
156
+ circular.get(a)?.add(b);
157
+ circular.get(b)?.add(a);
158
+ }
159
+ function dfs(node, ancestors) {
160
+ color.set(node, "gray");
161
+ for (const neighbor of graph.get(node) ?? []) {
162
+ if (!color.has(neighbor)) continue;
163
+ if (color.get(neighbor) === "gray") {
164
+ addCircular(node, neighbor);
165
+ for (const anc of ancestors) {
166
+ if (color.get(anc) === "gray") {
167
+ addCircular(anc, neighbor);
168
+ addCircular(node, anc);
169
+ }
170
+ }
171
+ } else if (color.get(neighbor) === "white") {
172
+ dfs(neighbor, [...ancestors, node]);
173
+ }
174
+ }
175
+ color.set(node, "black");
176
+ }
177
+ for (const node of graph.keys()) {
178
+ if (color.get(node) === "white") {
179
+ dfs(node, []);
180
+ }
181
+ }
182
+ return circular;
183
+ }
184
+
185
+ // src/parser/index.ts
186
+ function hasAttribute(field, name) {
187
+ return field.attributes?.some((a) => a.name === name) ?? false;
188
+ }
189
+ function hasDefault(field) {
190
+ return hasAttribute(field, "default") || hasAttribute(field, "updatedAt");
191
+ }
192
+ function parseEnum(node) {
193
+ const values = node.enumerators.filter((e) => e.type === "enumerator").map((e) => e.name);
194
+ return { name: node.name, values, documentation: node.comment };
195
+ }
196
+ function parseField(field, knownModels, knownEnums) {
197
+ return {
198
+ name: field.name,
199
+ prismaType: field.fieldType,
200
+ tsType: resolveTsType(field.fieldType, knownEnums),
201
+ isOptional: field.optional,
202
+ isArray: field.array,
203
+ isRelation: knownModels.has(field.fieldType),
204
+ isCircular: false,
205
+ hasDefault: hasDefault(field),
206
+ isId: hasAttribute(field, "id"),
207
+ isUnique: hasAttribute(field, "unique"),
208
+ isUpdatedAt: hasAttribute(field, "updatedAt"),
209
+ decorators: []
210
+ };
211
+ }
212
+ function parseModel(node, knownModels, knownEnums) {
213
+ const fields = node.properties.filter((p) => p.type === "field").map((f) => parseField(f, knownModels, knownEnums));
214
+ const relations = [...new Set(
215
+ fields.filter((f) => f.isRelation).map((f) => f.prismaType)
216
+ )];
217
+ return {
218
+ name: node.name,
219
+ fields,
220
+ relations,
221
+ circularRefs: [],
222
+ documentation: node.comment
223
+ };
224
+ }
225
+ var ParseError = class extends Error {
226
+ constructor(message, cause) {
227
+ super(message, { cause });
228
+ this.name = "ParseError";
229
+ }
230
+ };
231
+ function parseSchema(schemaPath) {
232
+ let raw;
233
+ try {
234
+ raw = fs.readFileSync(schemaPath, "utf-8");
235
+ } catch (err) {
236
+ throw new ParseError(`N\xE3o foi poss\xEDvel ler o schema em "${schemaPath}"`, err);
237
+ }
238
+ return parseSchemaString(raw);
239
+ }
240
+ function parseSchemaString(schemaContent) {
241
+ let ast;
242
+ try {
243
+ ast = prismaAst.getSchema(schemaContent);
244
+ } catch (err) {
245
+ throw new ParseError("Falha ao fazer parse do schema Prisma", err);
246
+ }
247
+ const rawNodes = ast.list;
248
+ const knownModels = new Set(
249
+ rawNodes.filter((n) => n.type === "model").map((n) => n.name)
250
+ );
251
+ const knownEnums = new Set(
252
+ rawNodes.filter((n) => n.type === "enum").map((n) => n.name)
253
+ );
254
+ const enums = rawNodes.filter((n) => n.type === "enum").map((n) => parseEnum(n));
255
+ const models = rawNodes.filter((n) => n.type === "model").map((n) => parseModel(n, knownModels, knownEnums));
256
+ const graph = new Map(models.map((m) => [m.name, m.relations]));
257
+ const circularMap = detectCircularRefs(graph);
258
+ for (const model of models) {
259
+ const circulars = circularMap.get(model.name) ?? /* @__PURE__ */ new Set();
260
+ model.circularRefs = [...circulars];
261
+ for (const field of model.fields) {
262
+ if (field.isRelation && circulars.has(field.prismaType)) {
263
+ field.isCircular = true;
264
+ }
265
+ }
266
+ }
267
+ return { models, enums };
268
+ }
269
+
270
+ // src/emitters/base.ts
271
+ function fileHeader() {
272
+ return [
273
+ "/**",
274
+ " * ARQUIVO GERADO AUTOMATICAMENTE \u2014 N\xC3O EDITE MANUALMENTE.",
275
+ " * Gerado por prisma-entity-gen. Rode o gerador para atualizar.",
276
+ " */",
277
+ ""
278
+ ].join("\n");
279
+ }
280
+ function formatFieldType(tsType, isArray, isOptional, isCircular) {
281
+ const base = isArray ? `${tsType}[]` : tsType;
282
+ const nullable = isOptional ? ` | null` : "";
283
+ return `${base}${nullable}`;
284
+ }
285
+ function formatJsDoc(doc) {
286
+ if (!doc) return "";
287
+ const lines = doc.split("\n").map((l) => ` * ${l.trim()}`).join("\n");
288
+ return `/**
289
+ ${lines}
290
+ */
291
+ `;
292
+ }
293
+ var BaseEmitter = class {
294
+ };
295
+
296
+ // src/emitters/type.emitter.ts
297
+ function toKebab(name) {
298
+ return name.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2").toLowerCase();
299
+ }
300
+ var TypeEmitter = class extends BaseEmitter {
301
+ constructor(options = {}) {
302
+ super();
303
+ this.options = options;
304
+ }
305
+ options;
306
+ emit(model, enums) {
307
+ const enumNames = new Set(enums.map((e) => e.name));
308
+ const lines = [fileHeader()];
309
+ const relationImports = this.collectRelationImports(model, enumNames);
310
+ if (relationImports.length > 0) {
311
+ for (const imp of relationImports) lines.push(imp);
312
+ lines.push("");
313
+ }
314
+ const enumImports = this.collectEnumImports(model, enumNames);
315
+ if (enumImports.length > 0) {
316
+ for (const imp of enumImports) lines.push(imp);
317
+ lines.push("");
318
+ }
319
+ if (model.documentation) lines.push(formatJsDoc(model.documentation));
320
+ lines.push(`export interface ${model.name}Entity {`);
321
+ for (const field of model.fields) {
322
+ lines.push(` ${this.formatField(field)}`);
323
+ }
324
+ lines.push("}");
325
+ lines.push("");
326
+ return lines.join("\n");
327
+ }
328
+ formatField(field) {
329
+ const relationsOptional = this.options.relations !== "required";
330
+ const optional = field.isRelation && relationsOptional || field.isOptional ? "?" : "";
331
+ const tsType = field.isRelation ? `${field.prismaType}Entity` : field.tsType;
332
+ const type = formatFieldType(tsType, field.isArray, field.isOptional, field.isCircular);
333
+ return `${field.name}${optional}: ${type};`;
334
+ }
335
+ collectRelationImports(model, enumNames) {
336
+ const seen = /* @__PURE__ */ new Set();
337
+ const imports = [];
338
+ for (const field of model.fields) {
339
+ if (field.isRelation && !enumNames.has(field.prismaType) && !seen.has(field.prismaType) && field.prismaType !== model.name) {
340
+ seen.add(field.prismaType);
341
+ imports.push(
342
+ `import type { ${field.prismaType}Entity } from "./${toKebab(field.prismaType)}.entity.js";`
343
+ );
344
+ }
345
+ }
346
+ return imports;
347
+ }
348
+ collectEnumImports(model, enumNames) {
349
+ const seen = /* @__PURE__ */ new Set();
350
+ const imports = [];
351
+ for (const field of model.fields) {
352
+ if (enumNames.has(field.prismaType) && !seen.has(field.prismaType)) {
353
+ seen.add(field.prismaType);
354
+ imports.push(
355
+ `import { ${field.prismaType} } from "./${toKebab(field.prismaType)}.enum.js";`
356
+ );
357
+ }
358
+ }
359
+ return imports;
360
+ }
361
+ };
362
+
363
+ // src/emitters/class.emitter.ts
364
+ var ClassEmitter = class extends BaseEmitter {
365
+ constructor(options = {}) {
366
+ super();
367
+ this.options = options;
368
+ }
369
+ options;
370
+ emit(model, enums) {
371
+ const enumNames = new Set(enums.map((e) => e.name));
372
+ const lines = [fileHeader()];
373
+ const cvImports = this.collectCvImports(model, enumNames);
374
+ if (this.options.classValidator && cvImports.length > 0) {
375
+ lines.push(`import { ${cvImports.join(", ")} } from "class-validator";`);
376
+ }
377
+ if (this.options.classTransformer) {
378
+ lines.push(`import { Type } from "class-transformer";`);
379
+ }
380
+ if (this.options.classValidator && cvImports.length > 0 || this.options.classTransformer) {
381
+ lines.push("");
382
+ }
383
+ const relationImports = this.collectRelationImports(model, enumNames);
384
+ if (relationImports.length > 0) {
385
+ for (const imp of relationImports) lines.push(imp);
386
+ lines.push("");
387
+ }
388
+ const enumImports = this.collectEnumImports(model, enumNames);
389
+ if (enumImports.length > 0) {
390
+ for (const imp of enumImports) lines.push(imp);
391
+ lines.push("");
392
+ }
393
+ if (model.documentation) lines.push(formatJsDoc(model.documentation));
394
+ lines.push(`export class ${model.name}Entity {`);
395
+ for (const field of model.fields) {
396
+ const fieldLines = this.formatField(field, enumNames);
397
+ for (const l of fieldLines) lines.push(` ${l}`);
398
+ }
399
+ lines.push("}");
400
+ lines.push("");
401
+ return lines.join("\n");
402
+ }
403
+ formatField(field, enumNames) {
404
+ const lines = [];
405
+ if (this.options.classValidator) {
406
+ const decorators = this.getCvDecorators(field, enumNames);
407
+ for (const d of decorators) lines.push(d);
408
+ }
409
+ if (this.options.classTransformer && field.isRelation && !field.isCircular) {
410
+ lines.push(`@Type(() => ${field.tsType}Entity)`);
411
+ }
412
+ const optional = field.isOptional || field.hasDefault ? "?" : "!";
413
+ const type = formatFieldType(
414
+ field.isRelation && !field.isCircular ? `${field.tsType}Entity` : field.tsType,
415
+ field.isArray,
416
+ field.isOptional,
417
+ field.isCircular
418
+ );
419
+ const comment = field.isCircular ? " // circular ref \u2014 usar Ref" : "";
420
+ lines.push(`${field.name}${optional}: ${type};${comment}`);
421
+ lines.push("");
422
+ return lines;
423
+ }
424
+ getCvDecorators(field, enumNames) {
425
+ const decorators = [];
426
+ if (field.isOptional || field.hasDefault) {
427
+ decorators.push("@IsOptional()");
428
+ }
429
+ if (field.isArray) {
430
+ decorators.push("@IsArray()");
431
+ }
432
+ if (field.isRelation || enumNames.has(field.prismaType)) {
433
+ return decorators;
434
+ }
435
+ switch (field.prismaType) {
436
+ case "String":
437
+ decorators.push("@IsString()");
438
+ break;
439
+ case "Boolean":
440
+ decorators.push("@IsBoolean()");
441
+ break;
442
+ case "Int":
443
+ case "Float":
444
+ case "Decimal":
445
+ decorators.push("@IsNumber()");
446
+ break;
447
+ case "BigInt":
448
+ decorators.push("@IsInt()");
449
+ break;
450
+ case "DateTime":
451
+ decorators.push("@IsDate()");
452
+ break;
453
+ }
454
+ return decorators;
455
+ }
456
+ collectCvImports(model, enumNames) {
457
+ const imports = /* @__PURE__ */ new Set();
458
+ for (const field of model.fields) {
459
+ if (field.isOptional || field.hasDefault) imports.add("IsOptional");
460
+ if (field.isArray) imports.add("IsArray");
461
+ if (field.isRelation || enumNames.has(field.prismaType)) continue;
462
+ switch (field.prismaType) {
463
+ case "String":
464
+ imports.add("IsString");
465
+ break;
466
+ case "Boolean":
467
+ imports.add("IsBoolean");
468
+ break;
469
+ case "Int":
470
+ case "Float":
471
+ case "Decimal":
472
+ imports.add("IsNumber");
473
+ break;
474
+ case "BigInt":
475
+ imports.add("IsInt");
476
+ break;
477
+ case "DateTime":
478
+ imports.add("IsDate");
479
+ break;
480
+ }
481
+ }
482
+ return [...imports].sort();
483
+ }
484
+ collectRelationImports(model, enumNames) {
485
+ const seen = /* @__PURE__ */ new Set();
486
+ const imports = [];
487
+ for (const field of model.fields) {
488
+ if (field.isRelation && !field.isCircular && !enumNames.has(field.prismaType) && !seen.has(field.prismaType)) {
489
+ seen.add(field.prismaType);
490
+ const fileName = field.prismaType.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2").toLowerCase();
491
+ imports.push(
492
+ `import { ${field.prismaType}Entity } from "./${fileName}.entity.js";`
493
+ );
494
+ }
495
+ }
496
+ return imports;
497
+ }
498
+ collectEnumImports(model, enumNames) {
499
+ const seen = /* @__PURE__ */ new Set();
500
+ const imports = [];
501
+ for (const field of model.fields) {
502
+ if (enumNames.has(field.prismaType) && !seen.has(field.prismaType)) {
503
+ seen.add(field.prismaType);
504
+ const fileName = field.prismaType.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2").toLowerCase();
505
+ imports.push(
506
+ `import { ${field.prismaType} } from "./${fileName}.enum.js";`
507
+ );
508
+ }
509
+ }
510
+ return imports;
511
+ }
512
+ };
513
+ var FileWriter = class {
514
+ constructor(outputDir, dryRun, logger) {
515
+ this.outputDir = outputDir;
516
+ this.dryRun = dryRun;
517
+ this.logger = logger;
518
+ }
519
+ outputDir;
520
+ dryRun;
521
+ logger;
522
+ writeAll(files) {
523
+ const result = { written: [], skipped: [] };
524
+ if (!this.dryRun) {
525
+ fs.mkdirSync(path.resolve(this.outputDir), { recursive: true });
526
+ }
527
+ for (const file of files) {
528
+ const absPath = path.resolve(this.outputDir, file.relativePath);
529
+ if (this.dryRun) {
530
+ this.logger.info(`[dry-run] ${file.relativePath}`);
531
+ result.skipped.push(absPath);
532
+ continue;
533
+ }
534
+ fs.mkdirSync(path.dirname(absPath), { recursive: true });
535
+ fs.writeFileSync(absPath, file.content, "utf-8");
536
+ this.logger.success(file.relativePath);
537
+ result.written.push(absPath);
538
+ }
539
+ return result;
540
+ }
541
+ };
542
+
543
+ // src/writer/barrel.ts
544
+ function generateBarrel(files) {
545
+ const exports$1 = files.filter((f) => !f.relativePath.endsWith("index.ts")).map((f) => {
546
+ const path = f.relativePath.replace(/\.ts$/, ".js");
547
+ return `export * from "./${path}";`;
548
+ }).sort();
549
+ return [fileHeader(), ...exports$1, ""].join("\n");
550
+ }
551
+
552
+ // src/logger.ts
553
+ var LEVELS = {
554
+ silent: 0,
555
+ info: 1,
556
+ verbose: 2
557
+ };
558
+ var Logger = class {
559
+ level;
560
+ constructor(logLevel = "info") {
561
+ this.level = LEVELS[logLevel];
562
+ }
563
+ info(msg) {
564
+ if (this.level >= LEVELS.info) {
565
+ console.log(` ${msg}`);
566
+ }
567
+ }
568
+ verbose(msg) {
569
+ if (this.level >= LEVELS.verbose) {
570
+ console.log(` [verbose] ${msg}`);
571
+ }
572
+ }
573
+ success(msg) {
574
+ if (this.level >= LEVELS.info) {
575
+ console.log(` \u2713 ${msg}`);
576
+ }
577
+ }
578
+ warn(msg) {
579
+ if (this.level >= LEVELS.info) {
580
+ console.warn(` \u26A0 ${msg}`);
581
+ }
582
+ }
583
+ error(msg) {
584
+ console.error(` \u2717 ${msg}`);
585
+ }
586
+ };
587
+
588
+ // src/generator.ts
589
+ function toKebabCase(name) {
590
+ return name.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1-$2").toLowerCase();
591
+ }
592
+ function shouldInclude(name, config) {
593
+ if (config.include.length > 0 && !config.include.includes(name)) return false;
594
+ if (config.exclude.includes(name)) return false;
595
+ return true;
596
+ }
597
+ function buildFiles(models, enums, config) {
598
+ const files = [];
599
+ const useType = config.mode === "type" || config.mode === "both";
600
+ const useClass = config.mode === "class" || config.mode === "both";
601
+ const typeEmitter = useType ? new TypeEmitter({ relations: config.relations }) : null;
602
+ const classEmitter = useClass ? new ClassEmitter({
603
+ classValidator: config.classValidator,
604
+ classTransformer: config.classTransformer
605
+ }) : null;
606
+ const typeDir = config.mode === "both" ? "types/" : "";
607
+ const classDir = config.mode === "both" ? "classes/" : "";
608
+ for (const model of models) {
609
+ if (!shouldInclude(model.name, config)) continue;
610
+ const fileName = `${toKebabCase(model.name)}.${config.suffix}.ts`;
611
+ if (typeEmitter) {
612
+ files.push({
613
+ relativePath: `${typeDir}${fileName}`,
614
+ content: typeEmitter.emit(model, enums),
615
+ sourceName: model.name
616
+ });
617
+ }
618
+ if (classEmitter) {
619
+ files.push({
620
+ relativePath: `${classDir}${fileName}`,
621
+ content: classEmitter.emit(model, enums),
622
+ sourceName: model.name
623
+ });
624
+ }
625
+ }
626
+ for (const enumDef of enums) {
627
+ if (!shouldInclude(enumDef.name, config)) continue;
628
+ const fileName = `${toKebabCase(enumDef.name)}.enum.ts`;
629
+ const content = buildEnumFile(enumDef, config.enumOutput);
630
+ if (typeDir) files.push({ relativePath: `${typeDir}${fileName}`, content, sourceName: enumDef.name });
631
+ else files.push({ relativePath: fileName, content, sourceName: enumDef.name });
632
+ if (classDir) files.push({ relativePath: `${classDir}${fileName}`, content, sourceName: enumDef.name });
633
+ }
634
+ return files;
635
+ }
636
+ function buildEnumFile(enumDef, enumOutput) {
637
+ const header = [
638
+ "/**",
639
+ " * ARQUIVO GERADO AUTOMATICAMENTE \u2014 N\xC3O EDITE MANUALMENTE.",
640
+ " * Gerado por prisma-entity-gen. Rode o gerador para atualizar.",
641
+ " */",
642
+ ""
643
+ ];
644
+ if (enumOutput === "union") {
645
+ const union = enumDef.values.map((v) => `"${v}"`).join(" | ");
646
+ return [...header, `export type ${enumDef.name} = ${union};`, ""].join("\n");
647
+ }
648
+ return [
649
+ ...header,
650
+ `export enum ${enumDef.name} {`,
651
+ ...enumDef.values.map((v) => ` ${v} = "${v}",`),
652
+ "}",
653
+ ""
654
+ ].join("\n");
655
+ }
656
+ async function generate(config) {
657
+ const logger = new Logger(config.logLevel);
658
+ logger.verbose(`Lendo schema: ${config.schemaPath}`);
659
+ const { models, enums } = parseSchema(config.schemaPath);
660
+ logger.info(`${models.length} models encontrados`);
661
+ logger.info(`${enums.length} enums encontrados`);
662
+ const files = buildFiles(models, enums, config);
663
+ logger.verbose(`${files.length} arquivos a gerar`);
664
+ if (config.barrel) {
665
+ files.push({
666
+ relativePath: "index.ts",
667
+ content: generateBarrel(files),
668
+ sourceName: "barrel"
669
+ });
670
+ }
671
+ const writer = new FileWriter(config.outputDir, config.dryRun, logger);
672
+ const result = writer.writeAll(files);
673
+ if (config.dryRun) {
674
+ logger.info(`${result.skipped.length} arquivos seriam gerados`);
675
+ } else {
676
+ logger.success(`${result.written.length} arquivos gerados em ${config.outputDir}`);
677
+ }
678
+ }
679
+
680
+ exports.ClassEmitter = ClassEmitter;
681
+ exports.ConfigError = ConfigError;
682
+ exports.ConfigSchema = ConfigSchema;
683
+ exports.DEFAULT_CONFIG = DEFAULT_CONFIG;
684
+ exports.ParseError = ParseError;
685
+ exports.TypeEmitter = TypeEmitter;
686
+ exports.generate = generate;
687
+ exports.loadConfig = loadConfig;
688
+ exports.parseSchema = parseSchema;
689
+ exports.parseSchemaString = parseSchemaString;
690
+ //# sourceMappingURL=index.cjs.map
691
+ //# sourceMappingURL=index.cjs.map