vsrepo 1.1.2 → 1.1.4
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 +26 -26
- package/VSRepository/VSRepoUtils.js +114 -71
- package/VSRepository/VSRepository.d.ts +6 -1
- package/VSRepository/VSRepository.js +14 -17
- package/package.json +7 -4
- package/scripts/configure-prisma-import.mjs +4 -4
package/README.md
CHANGED
|
@@ -70,21 +70,21 @@ Equivale a:
|
|
|
70
70
|
|
|
71
71
|
```bash
|
|
72
72
|
npx vsrepo generate \
|
|
73
|
-
--output
|
|
74
|
-
--prisma
|
|
73
|
+
--output generated/vsrepo \
|
|
74
|
+
--prisma generated/prisma
|
|
75
75
|
```
|
|
76
76
|
|
|
77
77
|
**Flags disponíveis:**
|
|
78
78
|
|
|
79
79
|
| Flag | Alias | Padrão |
|
|
80
80
|
| ---------- | ----- | ---------------------- |
|
|
81
|
-
| `--output` | `-o` | `
|
|
82
|
-
| `--prisma` | `-p` | `
|
|
81
|
+
| `--output` | `-o` | `generated/vsrepo` |
|
|
82
|
+
| `--prisma` | `-p` | `generated/prisma` |
|
|
83
83
|
|
|
84
84
|
**Arquivos gerados:**
|
|
85
85
|
|
|
86
86
|
```
|
|
87
|
-
|
|
87
|
+
generated/vsrepo/
|
|
88
88
|
├── VSRepoError.ts
|
|
89
89
|
├── VSRepoError.types.d.ts
|
|
90
90
|
├── VSRepository.ts
|
|
@@ -96,7 +96,7 @@ Após gerar, importe sempre a partir da pasta gerada:
|
|
|
96
96
|
|
|
97
97
|
```ts
|
|
98
98
|
// CORRETO ✅
|
|
99
|
-
import { setupVSRepo } from "
|
|
99
|
+
import { setupVSRepo } from "../../generated/vsrepo";
|
|
100
100
|
|
|
101
101
|
// ERRADO ❌
|
|
102
102
|
import { setupVSRepo } from "vsrepo";
|
|
@@ -110,7 +110,7 @@ import { setupVSRepo } from "vsrepo";
|
|
|
110
110
|
|
|
111
111
|
```ts
|
|
112
112
|
// src/configs/db.ts
|
|
113
|
-
import { PrismaClient } from '
|
|
113
|
+
import { PrismaClient } from '../../generated/prisma/client';
|
|
114
114
|
import { PrismaPg } from '@prisma/adapter-pg';
|
|
115
115
|
import 'dotenv/config';
|
|
116
116
|
|
|
@@ -125,8 +125,8 @@ export default prisma;
|
|
|
125
125
|
```ts
|
|
126
126
|
// src/repositories/usuarioRepository.ts
|
|
127
127
|
import prisma from "../configs/db";
|
|
128
|
-
import { setupVSRepo } from "
|
|
129
|
-
import type { Usuario } from "
|
|
128
|
+
import { setupVSRepo } from "../../generated/vsrepo";
|
|
129
|
+
import type { Usuario } from "../../generated/prisma/client";
|
|
130
130
|
|
|
131
131
|
const usuarioRepository = setupVSRepo<Usuario, "usuario">()({
|
|
132
132
|
tableName: "usuario",
|
|
@@ -172,11 +172,11 @@ O VSRepository pode ser facilmente integrado em projetos NestJS através de prov
|
|
|
172
172
|
### Configurando o repository como provider
|
|
173
173
|
|
|
174
174
|
```ts
|
|
175
|
-
// src/
|
|
175
|
+
// src/resources/user/user.repository.ts
|
|
176
176
|
import { Provider } from "@nestjs/common";
|
|
177
177
|
import { PrismaService } from "../../database/prisma.service";
|
|
178
|
-
import { UserGetPayload } from "
|
|
179
|
-
import { setupVSRepo } from "
|
|
178
|
+
import { UserGetPayload } from "../../../generated/prisma/models";
|
|
179
|
+
import { setupVSRepo } from "../../../generated/vsrepo";
|
|
180
180
|
|
|
181
181
|
const userVSRepo = setupVSRepo<
|
|
182
182
|
UserGetPayload<{ include: { profile: true } }>,
|
|
@@ -242,9 +242,9 @@ export const UserRepositoryProvider: Provider = {
|
|
|
242
242
|
### Registrando o provider no módulo
|
|
243
243
|
|
|
244
244
|
```ts
|
|
245
|
-
// src/
|
|
245
|
+
// src/resources/user/user.module.ts
|
|
246
246
|
import { Module } from "@nestjs/common";
|
|
247
|
-
import { UserRepositoryProvider } from "
|
|
247
|
+
import { UserRepositoryProvider } from "./user.repository";
|
|
248
248
|
import { UserService } from "./user.service";
|
|
249
249
|
import { UserController } from "./user.controller";
|
|
250
250
|
|
|
@@ -260,9 +260,9 @@ export class UserModule {}
|
|
|
260
260
|
### Utilizando o repository em um serviço
|
|
261
261
|
|
|
262
262
|
```ts
|
|
263
|
-
// src/
|
|
263
|
+
// src/resources/user/user.service.ts
|
|
264
264
|
import { Injectable, Inject } from "@nestjs/common";
|
|
265
|
-
import { USER_REPOSITORY, UserRepository } from "
|
|
265
|
+
import { USER_REPOSITORY, UserRepository } from "./user.repository";
|
|
266
266
|
|
|
267
267
|
@Injectable()
|
|
268
268
|
export class UserService {
|
|
@@ -292,7 +292,7 @@ export class UserService {
|
|
|
292
292
|
### Usando em um controller
|
|
293
293
|
|
|
294
294
|
```ts
|
|
295
|
-
// src/
|
|
295
|
+
// src/resources/user/user.controller.ts
|
|
296
296
|
import { Controller, Get, Post, Body, Param, Patch, Delete } from "@nestjs/common";
|
|
297
297
|
import { UserService } from "./user.service";
|
|
298
298
|
|
|
@@ -723,7 +723,7 @@ methods: {
|
|
|
723
723
|
Configure relações para que o `save` as gerencie automaticamente. Para que as relações apareçam no autocomplete, o tipo genérico deve incluir as relações usando `GetPayload`:
|
|
724
724
|
|
|
725
725
|
```ts
|
|
726
|
-
import type { Prisma } from "
|
|
726
|
+
import type { Prisma } from "../../generated/prisma/client";
|
|
727
727
|
|
|
728
728
|
type Usuario = Prisma.usuarioGetPayload<{
|
|
729
729
|
include: { perfil: true; postagens: true };
|
|
@@ -818,7 +818,7 @@ const usuarioRepository = setupVSRepo<Usuario, "usuario">()({
|
|
|
818
818
|
O VSRepository lança `VSRepoError` e suas subclasses em situações específicas (OBS: Erros do Prisma não são sobrescritos como `VSRepoError`):
|
|
819
819
|
|
|
820
820
|
```ts
|
|
821
|
-
import { VSRepoError } from "
|
|
821
|
+
import { VSRepoError } from "../../generated/vsrepo";
|
|
822
822
|
|
|
823
823
|
try {
|
|
824
824
|
const usuario = await usuarioRepository.get();
|
|
@@ -847,7 +847,7 @@ O VSRepository exporta os seguintes tipos para uso nas suas aplicações:
|
|
|
847
847
|
### Tipos de cliente
|
|
848
848
|
|
|
849
849
|
```ts
|
|
850
|
-
import type { DbClient, DbTransaction, ClientOrTransaction } from "
|
|
850
|
+
import type { DbClient, DbTransaction, ClientOrTransaction } from "../../generated/vsrepo";
|
|
851
851
|
|
|
852
852
|
type DbClient = PrismaClient;
|
|
853
853
|
type DbTransaction = Prisma.TransactionClient;
|
|
@@ -864,7 +864,7 @@ import type {
|
|
|
864
864
|
OrdenationModel,
|
|
865
865
|
PaginationModel,
|
|
866
866
|
ModelUpsertInput,
|
|
867
|
-
} from "
|
|
867
|
+
} from "../../generated/vsrepo";
|
|
868
868
|
|
|
869
869
|
// Select de um campo específico
|
|
870
870
|
type UsuarioSelect = SelectModel<"usuario">;
|
|
@@ -888,7 +888,7 @@ type UsuarioUpsertInput = ModelUpsertInput<"usuario">;
|
|
|
888
888
|
### Todos os inputs do modelo
|
|
889
889
|
|
|
890
890
|
```ts
|
|
891
|
-
import type { PrismaModelInputs } from "
|
|
891
|
+
import type { PrismaModelInputs } from "../../generated/vsrepo";
|
|
892
892
|
|
|
893
893
|
type UsuarioInputs = PrismaModelInputs<"usuario">;
|
|
894
894
|
// Contém:
|
|
@@ -899,7 +899,7 @@ type UsuarioInputs = PrismaModelInputs<"usuario">;
|
|
|
899
899
|
### Tipos de opções de método
|
|
900
900
|
|
|
901
901
|
```ts
|
|
902
|
-
import type { MethodOptions, MethodOptionsModel } from "
|
|
902
|
+
import type { MethodOptions, MethodOptionsModel } from "../../generated/vsrepo";
|
|
903
903
|
|
|
904
904
|
// MethodOptions<S> — opções passadas nos métodos do repository
|
|
905
905
|
// S = chave do select model ou false
|
|
@@ -919,7 +919,7 @@ import type {
|
|
|
919
919
|
RepositoryRelations,
|
|
920
920
|
ExtractRelationConfig,
|
|
921
921
|
UpsertWithRelations,
|
|
922
|
-
} from "
|
|
922
|
+
} from "../../generated/vsrepo";
|
|
923
923
|
|
|
924
924
|
// Configuração de um método dinâmico
|
|
925
925
|
type MeuMethodConfig = MethodConfig<"usuario", typeof meuSelectModels>;
|
|
@@ -943,7 +943,7 @@ type UsuarioComRelacoes = UpsertWithRelations<Usuario, "usuario", typeof relatio
|
|
|
943
943
|
### Tipo do repository construído
|
|
944
944
|
|
|
945
945
|
```ts
|
|
946
|
-
import type { BuiltRepository, RepositoryOf } from "
|
|
946
|
+
import type { BuiltRepository, RepositoryOf } from "../../generated/vsrepo";
|
|
947
947
|
|
|
948
948
|
// Tipo completo de um repository construído
|
|
949
949
|
type MeuRepo = BuiltRepository<Usuario, "usuario", typeof config, typeof buildConfig>;
|
|
@@ -970,7 +970,7 @@ type UsuarioRepositoryExtended = RepositoryOf<typeof usuarioVSRepo, undefined, t
|
|
|
970
970
|
### Tipo auxiliar
|
|
971
971
|
|
|
972
972
|
```ts
|
|
973
|
-
import type { DistributiveOmit } from "
|
|
973
|
+
import type { DistributiveOmit } from "../../generated/vsrepo";
|
|
974
974
|
|
|
975
975
|
// Omit distributivo — preserva unions ao omitir propriedades
|
|
976
976
|
type SemEmail = DistributiveOmit<Usuario | Perfil, "email">;
|
|
@@ -1,84 +1,127 @@
|
|
|
1
|
-
import
|
|
1
|
+
import z from "zod";
|
|
2
|
+
import { VSRepoConfigError, VSRepoBuildError } from "./VSRepoError.js";
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}
|
|
4
|
+
const stringSchema = z.string().trim().nonempty();
|
|
5
|
+
const objectSchema = z.looseObject({});
|
|
6
|
+
const booleanSchema = z.boolean();
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
8
|
+
export function validateConfig(config) {
|
|
9
|
+
const configSchema = z.strictObject({
|
|
10
|
+
tableName: stringSchema,
|
|
11
|
+
pkName: stringSchema,
|
|
12
|
+
selectModels: z.record(stringSchema, objectSchema).optional(),
|
|
13
|
+
defaultSelectModel: stringSchema.optional(),
|
|
14
|
+
requiredWhere: objectSchema.optional(),
|
|
15
|
+
relations: z.record(
|
|
16
|
+
stringSchema,
|
|
17
|
+
z.strictObject({
|
|
18
|
+
mode: z.enum(['otm', 'mtm', 'mto', 'oto']),
|
|
19
|
+
restriction: z.enum(['set', 'add']),
|
|
20
|
+
pk: stringSchema,
|
|
21
|
+
nullAble: booleanSchema.optional(),
|
|
22
|
+
})
|
|
23
|
+
).optional(),
|
|
24
|
+
methods: z.record(stringSchema, z.strictObject({
|
|
25
|
+
map: booleanSchema,
|
|
26
|
+
selectModel: stringSchema.or(z.literal(false)).optional(),
|
|
27
|
+
whereType: z.enum(["overwrite", "extending"]).optional(),
|
|
28
|
+
proxyTo: stringSchema.optional(),
|
|
29
|
+
pushWhere: objectSchema.optional(),
|
|
30
|
+
fbMode: z.enum(["one", "list"]).optional(),
|
|
31
|
+
injectOrdenation: objectSchema.or(z.array(objectSchema)).optional(),
|
|
32
|
+
injectPagination: objectSchema.optional()
|
|
33
|
+
})).optional()
|
|
34
|
+
}).superRefine((config, ctx)=>{
|
|
35
|
+
if (config.defaultSelectModel && !config.selectModels?.[config.defaultSelectModel]) {
|
|
36
|
+
ctx.addIssue({
|
|
37
|
+
code: "vs_custom",
|
|
38
|
+
path: ["defaultSelectModel"],
|
|
39
|
+
message: "must be a valid key of 'selectModels'",
|
|
40
|
+
});
|
|
19
41
|
}
|
|
20
42
|
|
|
21
|
-
if (
|
|
22
|
-
|
|
23
|
-
|
|
43
|
+
if (config.methods) {
|
|
44
|
+
for (const [key, method] of Object.entries(config.methods)) {
|
|
45
|
+
if (method.selectModel && !config.selectModels?.[method.selectModel]) {
|
|
46
|
+
ctx.addIssue({
|
|
47
|
+
code: "vs_custom",
|
|
48
|
+
path: ["methods", key, "selectModel"],
|
|
49
|
+
message: "must be a valid key of 'selectModels'",
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
24
53
|
}
|
|
54
|
+
});
|
|
25
55
|
|
|
26
|
-
|
|
56
|
+
const configParsed = configSchema.safeParse(config);
|
|
27
57
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
58
|
+
if(!configParsed.success) {
|
|
59
|
+
const firstIssue = configParsed.error.issues[0];
|
|
60
|
+
const path = firstIssue.path.length ? firstIssue.path.join(".") : "config";
|
|
61
|
+
throw new VSRepoConfigError(`[VSRepository] (config) ${path}: ${firstIssue.message}`)
|
|
31
62
|
}
|
|
32
63
|
|
|
33
|
-
|
|
34
|
-
const error = new this.throws("");
|
|
35
|
-
error.message = `[VSRepository] (${error.type}) '${fieldName}' ${reason}.`;
|
|
36
|
-
return error;
|
|
37
|
-
}
|
|
64
|
+
return configParsed.data;
|
|
38
65
|
}
|
|
39
66
|
|
|
40
|
-
export function
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
67
|
+
export function validateBuildConfig(buildConfig, buildInstance) {
|
|
68
|
+
const activeSchema = booleanSchema.default(true);
|
|
69
|
+
const defaultSelectSchema = buildInstance.selectModels ?
|
|
70
|
+
z.enum(Object.keys(buildInstance.selectModels)).optional()
|
|
71
|
+
: z.never("can only be passed if you have configured 'selectModels'.");
|
|
72
|
+
const ignoreRequiredWhereSchema = booleanSchema.default(false);
|
|
73
|
+
|
|
74
|
+
const buildConfigSchema = z.strictObject({
|
|
75
|
+
freeze: booleanSchema.default(true),
|
|
76
|
+
showWorking: booleanSchema.default(false),
|
|
77
|
+
baseMethods: z.strictObject({
|
|
78
|
+
get: z.strictObject({
|
|
79
|
+
active: activeSchema,
|
|
80
|
+
defaultSelect: defaultSelectSchema,
|
|
81
|
+
ignoreRequiredWhere: ignoreRequiredWhereSchema
|
|
82
|
+
}).optional(),
|
|
83
|
+
getOrThrow: z.strictObject({
|
|
84
|
+
active: activeSchema,
|
|
85
|
+
defaultSelect: defaultSelectSchema,
|
|
86
|
+
ignoreRequiredWhere: ignoreRequiredWhereSchema
|
|
87
|
+
}).optional(),
|
|
88
|
+
getAll: z.strictObject({
|
|
89
|
+
active: activeSchema,
|
|
90
|
+
defaultSelect: defaultSelectSchema,
|
|
91
|
+
ignoreRequiredWhere: ignoreRequiredWhereSchema
|
|
92
|
+
}).optional(),
|
|
93
|
+
remove: z.strictObject({
|
|
94
|
+
active: activeSchema,
|
|
95
|
+
defaultSelect: defaultSelectSchema,
|
|
96
|
+
ignoreRequiredWhere: ignoreRequiredWhereSchema
|
|
97
|
+
}).optional(),
|
|
98
|
+
save: z.strictObject({
|
|
99
|
+
active: activeSchema,
|
|
100
|
+
defaultSelect: defaultSelectSchema,
|
|
101
|
+
ignoreRequiredWhere: ignoreRequiredWhereSchema
|
|
102
|
+
}).optional(),
|
|
103
|
+
removeList: z.strictObject({
|
|
104
|
+
active: activeSchema,
|
|
105
|
+
ignoreRequiredWhere: ignoreRequiredWhereSchema
|
|
106
|
+
}).optional(),
|
|
107
|
+
total: z.strictObject({
|
|
108
|
+
active: activeSchema,
|
|
109
|
+
ignoreRequiredWhere: ignoreRequiredWhereSchema
|
|
110
|
+
}).optional(),
|
|
111
|
+
has: z.strictObject({
|
|
112
|
+
active: activeSchema,
|
|
113
|
+
ignoreRequiredWhere: ignoreRequiredWhereSchema
|
|
114
|
+
}).optional(),
|
|
115
|
+
}).optional()
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const buildConfigParsed = buildConfigSchema.safeParse(buildConfig);
|
|
119
|
+
|
|
120
|
+
if(!buildConfigParsed.success) {
|
|
121
|
+
const firstIssue = buildConfigParsed.error.issues[0];
|
|
122
|
+
const path = firstIssue.path.length ? firstIssue.path.join(".") : "config";
|
|
123
|
+
throw new VSRepoBuildError(`[VSRepository] (build) ${path}: ${firstIssue.message}`)
|
|
54
124
|
}
|
|
55
125
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
for (const key of Object.keys(config.relations)) {
|
|
60
|
-
const relation = config.relations[key];
|
|
61
|
-
|
|
62
|
-
validator.validate(relation.pk, "pk", "string", false, false, `of relation '${key}' must be a string`);
|
|
63
|
-
validator.validate(relation.mode, "mode", (field) => ['otm', 'mtm', 'mto', 'oto'].includes(field), false, false, `of relation '${key}' must be 'otm', 'mtm', 'mto' or 'oto'`);
|
|
64
|
-
validator.validate(relation.restriction, "restriction", (field) => ['set', 'add'].includes(field), false, false, `of relation '${key}' must be 'set' or 'add'`);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
validator.validate(config.requiredWhere, "requiredWhere", "object", true);
|
|
69
|
-
|
|
70
|
-
if(config.methods !== undefined) {
|
|
71
|
-
validator.validate(config.methods, "methods", "object");
|
|
72
|
-
|
|
73
|
-
for (const [key, value] of Object.entries(config.methods)) {
|
|
74
|
-
validator.validate(value.map, "map", "boolean", false, false, `on ${key} must be a valid boolean`);
|
|
75
|
-
validator.validate(value.whereType, "whereType", (field) => ['extending', 'overwrite'].includes(field), true, false, `on ${key} must be 'extending' or 'overwrite'`);
|
|
76
|
-
validator.validate(value.selectModel, "selectModel", (field) => !!(field === false || (config.selectModels && Object.keys(config.selectModels).includes(field))), true, false, `on ${key} must be a valid key of 'selectModels'`);
|
|
77
|
-
validator.validate(value.proxyTo, "proxyTo", "string", true, false, `on ${key} must be a valid string`);
|
|
78
|
-
validator.validate(value.fbMode, "fbMode", (field) => ['one', 'list'].includes(field), true, false, `on ${key} must be 'one' or 'list'`);
|
|
79
|
-
validator.validate(value.pushWhere, "pushWhere", "object", true, false, `on ${key} must be a valid object`);
|
|
80
|
-
validator.validate(value.injectOrdenation, "injectOrdenation", "object", true, false, `on ${key} must be a valid object or array`);
|
|
81
|
-
validator.validate(value.injectPagination, "injectPagination", "object", true, false, `on ${key} must be a valid object`);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
126
|
+
return buildConfigParsed.data;
|
|
127
|
+
}
|
|
@@ -590,6 +590,11 @@ export type BuiltRepository<T extends object, M extends Prisma.ModelName, Config
|
|
|
590
590
|
* Estende o repository com métodos personalizados sem perder a tipagem.
|
|
591
591
|
*/
|
|
592
592
|
extend<E>(extensionFunc: (repo: BuiltRepository<T, M, Config, C>) => E): BuiltRepository<T, M, Config, C> & E;
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* Instância do Prisma Client passada no `build`.
|
|
596
|
+
*/
|
|
597
|
+
readonly prisma: DbClient;
|
|
593
598
|
} & DynamicMethods<T, M, Config, PrismaModelInputs<M>> & InjectedBaseMethods<T, M, Config, C>;
|
|
594
599
|
|
|
595
600
|
/**
|
|
@@ -605,7 +610,7 @@ export declare class VSRepository<T extends object, M extends Prisma.ModelName,
|
|
|
605
610
|
/**
|
|
606
611
|
* Constrói o repository final com os métodos base e dinâmicos.
|
|
607
612
|
*/
|
|
608
|
-
build<C extends BuildConfig<
|
|
613
|
+
build<C extends BuildConfig<keyof ExtractSelectModels<Config>>>(prisma: DbClient, config?: C): BuiltRepository<T, M, Config, C>;
|
|
609
614
|
vsrepocache: never;
|
|
610
615
|
}
|
|
611
616
|
|
|
@@ -9,7 +9,7 @@ export * from "./VSRepoError.js";
|
|
|
9
9
|
|
|
10
10
|
// * Importando classes de erro
|
|
11
11
|
import { VSRepoBuildError, VSRepoExtendError, VSRepoRuntimeError } from "./VSRepoError.js";
|
|
12
|
-
import { validateConfig } from "./VSRepoUtils.js";
|
|
12
|
+
import { validateBuildConfig, validateConfig } from "./VSRepoUtils.js";
|
|
13
13
|
|
|
14
14
|
// * Essa é a classe pincipal, é a partir dela que serão criados os objetos dos repositories
|
|
15
15
|
export class VSRepository {
|
|
@@ -29,7 +29,7 @@ export class VSRepository {
|
|
|
29
29
|
methods;
|
|
30
30
|
|
|
31
31
|
constructor(config) {
|
|
32
|
-
validateConfig(config);
|
|
32
|
+
config = validateConfig(config);
|
|
33
33
|
|
|
34
34
|
this.vsrepocache = new Map();
|
|
35
35
|
this.tableName = config.tableName;
|
|
@@ -59,18 +59,17 @@ export class VSRepository {
|
|
|
59
59
|
return extended;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
build(prisma, config = {}) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
if(typeof config !== 'object' || config === null) {
|
|
66
|
-
throw new VSRepoBuildError(`[VSRepository] (build) 'config' must be a valid object.`);
|
|
67
|
-
}
|
|
68
|
-
if(config.freeze === undefined) {
|
|
69
|
-
config.freeze = true;
|
|
62
|
+
build(prisma, config = { freeze: true, showWorking: false }) {
|
|
63
|
+
if(typeof prisma !== 'object' || prisma === null) {
|
|
64
|
+
throw new VSRepoBuildError(`[VSRepository] (build) 'prisma' must be a valid Prisma Client.`);
|
|
70
65
|
}
|
|
71
66
|
|
|
72
67
|
const buildInstance = Object.create(this);
|
|
73
68
|
|
|
69
|
+
config = validateBuildConfig(config, buildInstance);
|
|
70
|
+
|
|
71
|
+
const showWorking = config.showWorking;
|
|
72
|
+
|
|
74
73
|
const relationsKeys = buildInstance.relations ? Object.keys(buildInstance.relations) : [];
|
|
75
74
|
|
|
76
75
|
const methods = buildInstance.methods;
|
|
@@ -487,10 +486,6 @@ export class VSRepository {
|
|
|
487
486
|
whereArgs.push(buildedWhere);
|
|
488
487
|
}
|
|
489
488
|
|
|
490
|
-
if(showWorking) {
|
|
491
|
-
console.log(`[VSRepository] (build) Where object builded to ${keyToMap}:\n`, JSON.stringify(buildedWhere, null, 2));
|
|
492
|
-
}
|
|
493
|
-
|
|
494
489
|
if(buildedWhere.autoInjectVal === undefined) argsCount++;
|
|
495
490
|
}
|
|
496
491
|
|
|
@@ -700,9 +695,9 @@ export class VSRepository {
|
|
|
700
695
|
const missingParams = whereParams.concat(otherParams).slice(args.length);
|
|
701
696
|
throw new VSRepoRuntimeError(`[VSRepository] (runtime) Missing parameters: ${missingParams.join(', ')}`);
|
|
702
697
|
} else if(args.length > argsCount) {
|
|
703
|
-
const optionsArg = args[args.length - 1]
|
|
698
|
+
const optionsArg = args[args.length - 1];
|
|
704
699
|
db = optionsArg.db ?? db;
|
|
705
|
-
optionsSelectModel = optionsArg.selectModel
|
|
700
|
+
optionsSelectModel = optionsArg.selectModel;
|
|
706
701
|
} else {
|
|
707
702
|
args.push('1')
|
|
708
703
|
}
|
|
@@ -1198,7 +1193,9 @@ export class VSRepository {
|
|
|
1198
1193
|
}
|
|
1199
1194
|
}
|
|
1200
1195
|
|
|
1201
|
-
|
|
1196
|
+
buildInstance.prisma = prisma;
|
|
1197
|
+
|
|
1198
|
+
if(config.freeze) Object.freeze(buildInstance);
|
|
1202
1199
|
return buildInstance;
|
|
1203
1200
|
}
|
|
1204
1201
|
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vsrepo",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.4",
|
|
4
4
|
"description": "Uma biblioteca de repository pattern para Prisma",
|
|
5
5
|
"homepage": "https://github.com/jaobrabo123/VSRepository#readme",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "https://github.com/jaobrabo123/VSRepository"
|
|
8
|
+
"url": "git+https://github.com/jaobrabo123/VSRepository.git"
|
|
9
9
|
},
|
|
10
10
|
"main": "./VSRepository/index.js",
|
|
11
11
|
"types": "./VSRepository/index.d.ts",
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"scripts"
|
|
33
33
|
],
|
|
34
34
|
"bin": {
|
|
35
|
-
"vsrepo": "
|
|
35
|
+
"vsrepo": "scripts/configure-prisma-import.mjs"
|
|
36
36
|
},
|
|
37
37
|
"engines": {
|
|
38
38
|
"node": ">=18"
|
|
@@ -63,5 +63,8 @@
|
|
|
63
63
|
"prisma": "^7.8.0",
|
|
64
64
|
"tsx": "^4.22.3",
|
|
65
65
|
"typescript": "^6.0.3"
|
|
66
|
+
},
|
|
67
|
+
"dependencies": {
|
|
68
|
+
"zod": "^4.4.3"
|
|
66
69
|
}
|
|
67
|
-
}
|
|
70
|
+
}
|
|
@@ -8,8 +8,8 @@ const workspaceRoot = process.cwd();
|
|
|
8
8
|
const args = process.argv.slice(2);
|
|
9
9
|
const scriptDirectory = path.dirname(fileURLToPath(import.meta.url));
|
|
10
10
|
|
|
11
|
-
const DEFAULT_OUTPUT = '
|
|
12
|
-
const DEFAULT_PRISMA = '
|
|
11
|
+
const DEFAULT_OUTPUT = 'generated/vsrepo';
|
|
12
|
+
const DEFAULT_PRISMA = 'generated/prisma';
|
|
13
13
|
const GENERATED_HEADER = `/**
|
|
14
14
|
* ! THIS FILE IS AUTO-GENERATED.
|
|
15
15
|
* ! DO NOT EDIT MANUALLY.
|
|
@@ -55,7 +55,7 @@ if (prismaArg.startsWith('-')) {
|
|
|
55
55
|
const outputDir = path.resolve(workspaceRoot, outputArg);
|
|
56
56
|
|
|
57
57
|
const prismaTargetPath = stripKnownExtension(
|
|
58
|
-
path.resolve(workspaceRoot, prismaArg, 'client')
|
|
58
|
+
path.resolve(workspaceRoot, prismaArg, prismaArg.endsWith('client') ? '' : 'client')
|
|
59
59
|
);
|
|
60
60
|
|
|
61
61
|
const installedNodeModulesPath = path.join(workspaceRoot, 'node_modules/vsrepo');
|
|
@@ -186,7 +186,7 @@ const readmeTarget = path.join(outputDir, 'README.md');
|
|
|
186
186
|
|
|
187
187
|
if (fs.existsSync(readmeSource)) {
|
|
188
188
|
fs.copyFileSync(readmeSource, readmeTarget);
|
|
189
|
-
console.log(`
|
|
189
|
+
console.log(`Gerado: ${path.relative(workspaceRoot, readmeTarget)}`);
|
|
190
190
|
} else {
|
|
191
191
|
console.warn(`README.md do VSRepository nao encontrado em: ${path.relative(workspaceRoot, readmeSource)}. Ignorando a copia.`);
|
|
192
192
|
}
|