nest-prisma_doc-gen 1.0.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.
Files changed (50) hide show
  1. package/dist/entities/dto-generator.d.ts +13 -0
  2. package/dist/entities/dto-generator.js +51 -0
  3. package/dist/entities/entity-generator.d.ts +12 -0
  4. package/dist/entities/entity-generator.js +47 -0
  5. package/dist/entities/enum.d.ts +22 -0
  6. package/dist/entities/enum.js +37 -0
  7. package/dist/entities/field.d.ts +24 -0
  8. package/dist/entities/field.js +169 -0
  9. package/dist/entities/model.d.ts +11 -0
  10. package/dist/entities/model.js +18 -0
  11. package/dist/entities/validator.js +12 -0
  12. package/dist/field.type.d.ts +7 -0
  13. package/dist/field.type.js +22 -0
  14. package/dist/file.d.ts +11 -0
  15. package/dist/file.js +26 -0
  16. package/dist/helpers/helpers.d.ts +14 -0
  17. package/dist/helpers/helpers.js +143 -0
  18. package/dist/helpers/loader.d.ts +4 -0
  19. package/dist/helpers/loader.js +50 -0
  20. package/dist/helpers/propeties.static.d.ts +2 -0
  21. package/dist/helpers/propeties.static.js +2 -0
  22. package/dist/index.d.ts +2 -0
  23. package/dist/index.js +2 -0
  24. package/dist/main.d.ts +13 -0
  25. package/dist/main.js +53 -0
  26. package/dist/rules.d.ts +11 -0
  27. package/dist/rules.js +19 -0
  28. package/dist/static.d.ts +6 -0
  29. package/dist/static.js +25 -0
  30. package/dist/types.d.ts +79 -0
  31. package/dist/types.js +17 -0
  32. package/package.json +40 -0
  33. package/src/entities/dto-generator.ts +61 -0
  34. package/src/entities/entity-generator.ts +55 -0
  35. package/src/entities/enum.ts +47 -0
  36. package/src/entities/field.ts +188 -0
  37. package/src/entities/model.ts +23 -0
  38. package/src/entities/validator.ts +17 -0
  39. package/src/field.type.ts +27 -0
  40. package/src/file.ts +34 -0
  41. package/src/helpers/helpers.ts +152 -0
  42. package/src/helpers/loader.ts +60 -0
  43. package/src/helpers/propeties.static.ts +3 -0
  44. package/src/index.ts +2 -0
  45. package/src/main.ts +69 -0
  46. package/src/rules.ts +31 -0
  47. package/src/static.ts +28 -0
  48. package/src/types/global.d.ts +1 -0
  49. package/src/types.ts +109 -0
  50. package/tsconfig.json +15 -0
@@ -0,0 +1,188 @@
1
+ import { Helper } from "../helpers/helpers.js";
2
+ import { config } from "../helpers/loader.js";
3
+ import { Static } from "../static.js";
4
+ import { FieldDefault, Scalar, FieldKind, FieldType, Field } from "../types.js";
5
+ import { Validator } from "./validator.js";
6
+
7
+ const helpers = new Helper();
8
+ const rules = config;
9
+
10
+ export class DocGenField {
11
+ name: string;
12
+ isList: boolean;
13
+ default?: FieldDefault | string;
14
+ scalarType: Scalar;
15
+ kind: FieldKind;
16
+
17
+ type!: string;
18
+ fieldType: FieldType;
19
+
20
+ isEnum: boolean = false;
21
+ isEntity: boolean = false;
22
+ isUpdatedAt: boolean = false;
23
+ isRequired: boolean;
24
+ validators = new Set<Validator>();
25
+
26
+ readonly scalarField: Field;
27
+
28
+ constructor(field: Field, fieldType: FieldType) {
29
+ const { name, isList, type, kind, isRequired, isUpdatedAt } = field;
30
+
31
+ this.name = name;
32
+ this.isList = isList;
33
+ this.scalarType = type;
34
+ this.kind = kind;
35
+ this.isRequired = isRequired;
36
+ this.scalarField = field;
37
+ this.isUpdatedAt = isUpdatedAt;
38
+ this.fieldType = fieldType;
39
+
40
+ this.setType();
41
+ this.setValidators();
42
+ }
43
+
44
+ private processValidator(name: string) {
45
+ const validator = new Validator({ name });
46
+ if (this.isList) validator.content = "{ each: true }";
47
+
48
+ this.validators.add(validator);
49
+ }
50
+
51
+ private setValidators() {
52
+ if (this.scalarType === "String" || this.scalarType === "DateTime") {
53
+ this.processValidator("IsString");
54
+
55
+ if (this.isRequired) {
56
+ this.processValidator("IsNotEmpty");
57
+ }
58
+ } else if (this.scalarType === "Boolean") {
59
+ this.processValidator("IsBoolean");
60
+ } else if (
61
+ this.scalarType === "Int" ||
62
+ this.scalarType === "BigInt" ||
63
+ this.scalarType === "Float" ||
64
+ this.scalarType === "Decimal"
65
+ ) {
66
+ this.processValidator("IsNumber");
67
+ }
68
+
69
+ if (this.isList) {
70
+ const validator = new Validator({ name: "IsArray" });
71
+ this.validators.add(validator);
72
+ }
73
+
74
+ if (!this.isRequired) this.processValidator("IsOptional");
75
+
76
+ if (this.isEnum) {
77
+ this.validators.add(
78
+ new Validator({
79
+ name: "IsEnum",
80
+ content: this.type,
81
+ })
82
+ );
83
+ }
84
+
85
+ const findedDecorators = rules.validators.get(this.name);
86
+
87
+ if (findedDecorators) {
88
+ findedDecorators.forEach((name) => {
89
+ this.processValidator(name);
90
+ });
91
+ }
92
+ }
93
+
94
+ private setType() {
95
+ if (this.kind === "enum") {
96
+ this.isEnum = true;
97
+ this.type = this.scalarType;
98
+ } else if (this.kind === "object") {
99
+ this.isEntity = true;
100
+ this.type = `${this.scalarType}Entity`;
101
+ } else if (this.kind === "scalar") {
102
+ this.type = Helper.prismaScalarToTs(this.scalarType);
103
+ }
104
+ }
105
+
106
+ private buildApiExample(): string[] {
107
+ const fieldName = this.scalarField.name;
108
+ const props: string[] = [];
109
+ const scalarDbName = this.scalarField.dbName ?? "genericDbName";
110
+
111
+ if (this.isEntity) {
112
+ if (this.isList) {
113
+ props.push(`example: [generateExample(${this.type})]`);
114
+ } else {
115
+ props.push(`example: generateExample(${this.type})`);
116
+ }
117
+ } else if (rules.examples.has(fieldName)) {
118
+ props.push(`example: '${rules.examples.get(fieldName)?.example}'`);
119
+ } else if (helpers.isDate(this.scalarField)) {
120
+ props.push(`example: '2025-09-03T03:00:00.000Z'`);
121
+ } else if (this.scalarField.isId || (this.scalarField.isReadOnly && scalarDbName.split("_").includes("id"))) {
122
+ props.push(`example: 'cmfxu4njg000008l52v7t8qze'`);
123
+ } else if (this.scalarField.type === "Boolean") {
124
+ props.push(`example: true`);
125
+ } else if (this.scalarField.kind === "enum") {
126
+ props.push(`example: ${this.scalarField.type}[0]`);
127
+ } else if (this.scalarField.type === "Int") {
128
+ props.push(`example: ${Static.getRandomNumber()}`);
129
+ }
130
+
131
+ props.push(`required: ${this.scalarField.isRequired}`);
132
+ return props;
133
+ }
134
+
135
+ private sanitizeValidators() {
136
+ const sanitizedValidators = Array.from(this.validators).map((validator) => {
137
+ return validator.build();
138
+ });
139
+
140
+ return sanitizedValidators;
141
+ }
142
+
143
+ private buildInfos() {
144
+ const key = this.isEnum ? "enum" : "type";
145
+
146
+ const apiType = () => {
147
+ if (this.type === "Date") return `'string'`;
148
+
149
+ if (this.isList && this.isEntity) {
150
+ return `[${this.type}]`;
151
+ } else if (this.isEnum) {
152
+ return this.type;
153
+ } else if (this.isEntity) {
154
+ return `() => ${this.type}`;
155
+ }
156
+
157
+ return `'${this.type}'`;
158
+ };
159
+
160
+ const fieldType = () => {
161
+ if (this.isList) {
162
+ return `${this.type}[]`;
163
+ } else {
164
+ return this.type;
165
+ }
166
+ };
167
+ const optionalFlag = this.isRequired ? "" : "?";
168
+
169
+ const validators = this.sanitizeValidators();
170
+ const apiExample = this.buildApiExample().join(", ");
171
+
172
+ return {
173
+ apiProperty: `@ApiProperty({ ${key}: ${apiType()}, ${apiExample} })`,
174
+ validators,
175
+ atributes: `${this.name}${optionalFlag}: ${fieldType()};`,
176
+ };
177
+ }
178
+
179
+ build() {
180
+ const { apiProperty, atributes, validators } = this.buildInfos();
181
+
182
+ if (this.fieldType === "dto") {
183
+ return [apiProperty, ...validators, atributes].join("\n");
184
+ } else {
185
+ return [apiProperty, atributes].join("\n");
186
+ }
187
+ }
188
+ }
@@ -0,0 +1,23 @@
1
+ import { Field, Model } from "../types.js";
2
+ import { DocGenDto } from "./dto-generator.js";
3
+ import { DocGenEntity } from "./entity-generator.js";
4
+
5
+ export class DocGenModel {
6
+ name: string;
7
+ entitie: DocGenEntity;
8
+ createDtos: DocGenDto;
9
+ fields: Field[];
10
+
11
+ constructor(model: Model) {
12
+ this.name = model.name;
13
+ this.fields = model.fields;
14
+
15
+ this.entitie = new DocGenEntity(model);
16
+ this.createDtos = new DocGenDto(model);
17
+ }
18
+
19
+ save() {
20
+ this.entitie.file.save();
21
+ this.createDtos.file.save();
22
+ }
23
+ }
@@ -0,0 +1,17 @@
1
+ import { Scalar } from "../types.js";
2
+
3
+ export class Validator {
4
+ name: string;
5
+ content: string;
6
+
7
+ constructor(params: { name: string; content?: string }) {
8
+ const { content, name } = params;
9
+
10
+ this.name = name;
11
+ this.content = content ?? "";
12
+ }
13
+
14
+ build() {
15
+ return `@${this.name}(${this.content})`;
16
+ }
17
+ }
@@ -0,0 +1,27 @@
1
+ import { DocGenFile } from "./file.js";
2
+ import { Static } from "./static.js";
3
+
4
+ export class DocFields {
5
+ fields: string;
6
+ file: DocGenFile;
7
+
8
+ constructor(fields: string) {
9
+ this.fields = fields;
10
+
11
+ this.file = new DocGenFile({
12
+ dir: "/",
13
+ fileName: "fields.ts",
14
+ data: this.build(),
15
+ });
16
+ }
17
+
18
+ build() {
19
+ const content = `
20
+ ${Static.AUTO_GENERATED_COMMENT}
21
+ export const FIELD_NAMES = [${this.fields}] as const
22
+ export type FieldName = (typeof FIELD_NAMES)[number];
23
+ `;
24
+
25
+ return content;
26
+ }
27
+ }
package/src/file.ts ADDED
@@ -0,0 +1,34 @@
1
+ import { promises as fs } from "node:fs";
2
+ import * as path from "node:path";
3
+ import * as prettier from "prettier";
4
+
5
+ const ROOT = process.cwd();
6
+ const OUT_DIR = path.join(ROOT, "generated/docgen");
7
+
8
+ export class DocGenFile {
9
+ outDir: string;
10
+ data: string;
11
+
12
+ constructor(params: { fileName: string; dir: string; data: string; customDir?: string }) {
13
+ const { fileName, dir, data, customDir } = params;
14
+
15
+ this.outDir = path.join(OUT_DIR, dir, fileName);
16
+ this.data = data;
17
+
18
+ if (customDir) this.outDir = customDir;
19
+ }
20
+
21
+ async save() {
22
+ const dir = path.dirname(this.outDir);
23
+ await fs.mkdir(dir, { recursive: true });
24
+
25
+ const prettierConfig = await prettier.resolveConfig(this.outDir);
26
+
27
+ const formatted = await prettier.format(this.data, {
28
+ ...prettierConfig,
29
+ filepath: this.outDir,
30
+ });
31
+
32
+ await fs.writeFile(this.outDir, formatted, "utf-8");
33
+ }
34
+ }
@@ -0,0 +1,152 @@
1
+ import { promises as fs } from "node:fs";
2
+ import * as path from "node:path";
3
+ import { Scalar, Field, DocGenModel } from "../types.js";
4
+
5
+ export class Helper {
6
+ static prismaScalarToTs(s: Scalar): string {
7
+ switch (s) {
8
+ case "String":
9
+ return "string";
10
+ case "Int":
11
+ return "number";
12
+ case "BigInt":
13
+ return "bigint";
14
+ case "Float":
15
+ case "Decimal":
16
+ return "number";
17
+ case "Boolean":
18
+ return "boolean";
19
+ case "DateTime":
20
+ return "Date";
21
+ case "Json":
22
+ return "any";
23
+ case "Bytes":
24
+ return "Buffer";
25
+ default: {
26
+ return "any";
27
+ }
28
+ }
29
+ }
30
+
31
+ static validatorForScalar(s: Scalar): string {
32
+ switch (s) {
33
+ case "String":
34
+ return "IsString";
35
+ case "Int":
36
+ return "IsInt";
37
+ case "BigInt":
38
+ return "IsNumber"; // class-validator não tem IsBigInt
39
+ case "Float":
40
+ case "Decimal":
41
+ return "IsNumber";
42
+ case "Boolean":
43
+ return "IsBoolean";
44
+ case "DateTime":
45
+ return "IsDate";
46
+ case "Json":
47
+ return ""; // costuma ser livre
48
+ case "Bytes":
49
+ return ""; // Buffer não tem decorador nativo
50
+ default:
51
+ return "";
52
+ }
53
+ }
54
+
55
+ static swaggerType(field: Field): string | undefined {
56
+ // mapeia para Swagger 'type' básico quando possível
57
+ if (field.kind === "scalar") {
58
+ const t = field.type;
59
+
60
+ switch (t) {
61
+ case "String":
62
+ return "string";
63
+ case "Int":
64
+ case "Float":
65
+ case "Decimal":
66
+ return "number";
67
+ case "BigInt":
68
+ return "integer";
69
+ case "Boolean":
70
+ return "boolean";
71
+ case "DateTime":
72
+ return "string"; // format date-time
73
+ case "Json":
74
+ return "object";
75
+ case "Bytes":
76
+ return "string"; // base64
77
+ }
78
+ }
79
+ return undefined;
80
+ }
81
+
82
+ static toKebab(s: string): string {
83
+ return s.replace(/([a-z])([A-Z])/g, "$1-$2").toLowerCase();
84
+ }
85
+
86
+ importsForModel(model: DocGenModel): {
87
+ enums: boolean;
88
+ hasDate: boolean;
89
+ } {
90
+ const needsEnum = model.fields.some((field) => field.kind === "enum");
91
+ return {
92
+ enums: needsEnum,
93
+ hasDate: model.fields.some((field) => field.kind === "scalar" && field.type === "DateTime"),
94
+ };
95
+ }
96
+
97
+ static async readPrismaFolderDatamodel(dir: string): Promise<string> {
98
+ const files: string[] = [];
99
+ const entries = await fs.readdir(dir, { withFileTypes: true });
100
+
101
+ const mainSchemaPath = path.join(dir, "schema.prisma");
102
+ try {
103
+ const mainStat = await fs.stat(mainSchemaPath);
104
+ if (mainStat.isFile()) files.push(mainSchemaPath);
105
+ } catch {}
106
+
107
+ // varrer demais itens (exceto migrations e o schema.prisma já incluído)
108
+ for (const entry of entries) {
109
+ if (entry.name === "migrations") continue;
110
+ const full = path.join(dir, entry.name);
111
+
112
+ if (entry.isDirectory()) {
113
+ const nested = await this.readPrismaFolderDatamodel(full);
114
+ if (nested.trim()) files.push(`\n// ---- ${full} ----\n${nested}`);
115
+ } else if (entry.isFile() && entry.name.endsWith(".prisma") && full !== mainSchemaPath) {
116
+ const content = await fs.readFile(full, "utf-8");
117
+ files.push(`\n// ---- ${full} ----\n${content}`);
118
+ }
119
+ }
120
+
121
+ // se não houver nada além de subpastas, retorna o que juntou nelas
122
+ if (!files.length) return "";
123
+
124
+ // quando schema.prisma existe, ele já está no topo do array
125
+ if (files[0] === mainSchemaPath) {
126
+ const head = await fs.readFile(mainSchemaPath, "utf-8");
127
+ const tail = files.slice(1).join("\n");
128
+ return `${head}\n${tail}`;
129
+ }
130
+
131
+ // caso não exista schema.prisma, apenas concatena
132
+ const contents = await Promise.all(files.map(async (f) => (f.startsWith("\n// ---- ") ? f : fs.readFile(f, "utf-8"))));
133
+ return contents.join("\n");
134
+ }
135
+
136
+ findTypeForField(field: Field): string {
137
+ if (field.kind === "scalar") {
138
+ const base = Helper.prismaScalarToTs(field.type);
139
+ return field.isList ? `${base}[]` : base;
140
+ } else if (field.kind === "enum") {
141
+ const base = field.type;
142
+ return field.isList ? `${base}[]` : base;
143
+ } else if (field.kind === "object") {
144
+ const base = "any";
145
+ return field.isList ? `${base}[]` : base;
146
+ } else return "any";
147
+ }
148
+
149
+ isDate(field: Field): boolean {
150
+ return field.kind === "scalar" && field.type === "DateTime";
151
+ }
152
+ }
@@ -0,0 +1,60 @@
1
+ import "tsx/esm";
2
+ import { pathToFileURL } from "node:url";
3
+ import * as fs from "node:fs";
4
+ import * as path from "node:path";
5
+ import { DocGenRules } from "../rules.js";
6
+ import { ApiExampleBuilder, DocGenParams } from "../types.js";
7
+
8
+ export class DocGenConfig {
9
+ public readonly ignore: string[];
10
+ public readonly examples: Map<string, ApiExampleBuilder>;
11
+ public readonly validators: Map<string, string[]>;
12
+
13
+ constructor(configs: DocGenRules) {
14
+ const { examples, ignore, validators } = configs;
15
+ this.ignore = ignore;
16
+ this.examples = examples;
17
+ this.validators = validators;
18
+ }
19
+
20
+ /**
21
+ * Carrega o arquivo doc-gen.config.ts|.js da raiz do projeto.
22
+ */
23
+ static async load(): Promise<DocGenConfig> {
24
+ const ROOT = process.cwd();
25
+ const CONFIG_PATH_TS = path.join(ROOT, "doc-gen.config.mts");
26
+ const CONFIG_PATH_JS = path.join(ROOT, "doc-gen.config.mjs");
27
+
28
+ let configFile: string | undefined;
29
+ if (fs.existsSync(CONFIG_PATH_TS)) configFile = CONFIG_PATH_TS;
30
+ else if (fs.existsSync(CONFIG_PATH_JS)) configFile = CONFIG_PATH_JS;
31
+
32
+ if (!configFile) {
33
+ console.warn("⚠️ Nenhum arquivo doc-gen.config.ts|.js encontrado. Usando configuração vazia.");
34
+ return this.newEmpty();
35
+ }
36
+
37
+ await import("tsx/esm");
38
+ const imported = await import(pathToFileURL(configFile).href);
39
+
40
+ const rules = imported.rules as DocGenParams | undefined;
41
+ if (!rules) {
42
+ console.warn("⚠️ O arquivo doc-gen.config.ts|.js não exporta 'rules'.");
43
+ return this.newEmpty();
44
+ }
45
+
46
+ return this.newWithConfigs(rules);
47
+ }
48
+
49
+ /** Cria uma instância vazia */
50
+ private static newEmpty() {
51
+ return new DocGenConfig(new DocGenRules({ ignore: [], examples: [], validators: [] }));
52
+ }
53
+
54
+ /** Cria uma instância a partir de configurações */
55
+ private static newWithConfigs(params: DocGenParams) {
56
+ return new DocGenConfig(new DocGenRules(params));
57
+ }
58
+ }
59
+
60
+ export const config = await DocGenConfig.load();
@@ -0,0 +1,3 @@
1
+ // AUTO-GERADO: NÃO EDITAR MANUALMENTE. SUJEITO A PAULADAS!
2
+ export const FIELD_NAMES = [""] as const;
3
+ export type FieldName = (typeof FIELD_NAMES)[number];
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { DocGenRules } from "./rules.js";
2
+ export { DocGenConfig } from "./helpers/loader.js";
package/src/main.ts ADDED
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+ import * as path from "node:path";
3
+ import { DocEnums, DocGenEnum, EnumValue } from "./entities/enum.js";
4
+ import { DocGenModel } from "./entities/model.js";
5
+ import { DocFields } from "./field.type.js";
6
+ import { Helper } from "./helpers/helpers.js";
7
+ import { Model } from "./types.js";
8
+
9
+ import prismaPkg from "@prisma/internals";
10
+ import { config } from "./helpers/loader.js";
11
+ const { getDMMF } = prismaPkg;
12
+
13
+ const ROOT = process.cwd();
14
+ const PRISMA_DIR = path.join(ROOT, "prisma");
15
+
16
+ export class DocGen {
17
+ datamodel!: string;
18
+ properties!: Set<string>;
19
+ enums!: DocEnums;
20
+ fields!: DocFields;
21
+ models!: DocGenModel[];
22
+
23
+ async init() {
24
+ const prismaDataModel = await Helper.readPrismaFolderDatamodel(PRISMA_DIR);
25
+ const { datamodel } = await getDMMF({ datamodel: prismaDataModel });
26
+
27
+ this.enums = new DocEnums(
28
+ datamodel.enums.map(({ dbName, name, values }) => {
29
+ return new DocGenEnum({
30
+ dbName: dbName ?? "",
31
+ name,
32
+ values: values as EnumValue[],
33
+ });
34
+ })
35
+ );
36
+
37
+ const fieldSet = new Set<string>();
38
+
39
+ datamodel.models.forEach((model) => {
40
+ model.fields.forEach((field) => fieldSet.add(`'${field.name}'`));
41
+ });
42
+
43
+ this.fields = new DocFields(Array.from(fieldSet).toString());
44
+
45
+ this.models = datamodel.models.map((model) => {
46
+ return new DocGenModel(model as Model);
47
+ });
48
+
49
+ this.build();
50
+ }
51
+
52
+ build() {
53
+ this.fields.file.save();
54
+ this.enums.file.save();
55
+ this.models.forEach((model) => {
56
+ model.save();
57
+ });
58
+ }
59
+ }
60
+
61
+ const generator = new DocGen();
62
+
63
+ try {
64
+ await generator.init();
65
+ console.log("✅ DTOs gerados com sucesso!");
66
+ } catch (err) {
67
+ console.error("❌ Erro ao gerar DTOs:", err);
68
+ process.exit(1);
69
+ }
package/src/rules.ts ADDED
@@ -0,0 +1,31 @@
1
+ import { ApiExampleBuilder, ValidatorBuilder } from "./types.js";
2
+
3
+ export class DocGenRules {
4
+ ignore: string[];
5
+ examples: Map<string, ApiExampleBuilder>;
6
+ validators: Map<string, string[]>;
7
+
8
+ constructor(params: { ignore: string[]; examples: ApiExampleBuilder[]; validators: ValidatorBuilder[] }) {
9
+ const { examples, ignore, validators } = params;
10
+
11
+ this.ignore = ignore;
12
+
13
+ if (!validators.length) {
14
+ console.warn("[doc-gen] Nenhum validator encontrado. Verifique seu docgen.config.ts*");
15
+ }
16
+
17
+ const allFields = validators.flatMap((validator) => validator.fields);
18
+ const uniqueFieldsToValidate = [...new Set(allFields)];
19
+
20
+ this.examples = new Map<string, ApiExampleBuilder>(
21
+ examples.flatMap((builder) => builder.fields.map((field) => [field, builder]))
22
+ );
23
+
24
+ this.validators = new Map<string, string[]>(
25
+ uniqueFieldsToValidate.map((field) => [
26
+ field,
27
+ validators.filter((validator) => validator.fields.includes(field)).map((validator) => validator.decorator.name),
28
+ ])
29
+ );
30
+ }
31
+ }
package/src/static.ts ADDED
@@ -0,0 +1,28 @@
1
+ export class Static {
2
+ static readonly AUTO_GENERATED_COMMENT = "// AUTO-GERADO: NÃO EDITAR MANUALMENTE. SUJEITO A PAULADAS!" as const;
3
+
4
+ static readonly STATIC_NAMES = [
5
+ "Alessandro",
6
+ "Pablo",
7
+ "Cláudio",
8
+ "Thiago",
9
+ "Guilherme",
10
+ "Dalton",
11
+ "Kaio",
12
+ "Gustavo",
13
+ "Cadu",
14
+ "Neyanne",
15
+ "John",
16
+ "Matheus",
17
+ "Davi",
18
+ ] as const;
19
+
20
+ static getRandomString(values: string[]): string {
21
+ const idx = Math.floor(Math.random() * values.length);
22
+ return values[idx];
23
+ }
24
+
25
+ static getRandomNumber(min = 0, max = 1000): number {
26
+ return Math.floor(Math.random() * (max - min)) + min;
27
+ }
28
+ }
@@ -0,0 +1 @@
1
+ declare module "tsx/esm";