vsrepo 1.0.5 → 1.0.7

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 CHANGED
@@ -616,7 +616,7 @@ Cada entrada em `methods` aceita as seguintes opções:
616
616
  | `whereType` | `'extending'` \| `'overwrite'` | `extending` | `extending` combina com `requiredWhere`. `overwrite` ignora o `requiredWhere`. |
617
617
  | `selectModel` | `keyof SelectModels \| false` | — | Sobrescreve o `defaultSelectModel` para este método. |
618
618
  | `fbMode` | `'one'` \| `'list'` | `'list'` | Somente para `findBy`. `'one'` retorna `T \| null`; `'list'` retorna `T[]`. |
619
- | `proxyTo` | `ValidMethodPatterns` | — | Delega a lógica para outro padrão de método válido. Útil para methods com nomes personalizados. |
619
+ | `proxyTo` | `Padrão de método válido` | — | Delega a lógica para outro padrão de método válido. Útil para methods com nomes personalizados. |
620
620
  | `pushWhere` | `WhereModel<M>` | — | Where extra adicionado à query além do `requiredWhere`. |
621
621
  | `injectOrdenation` | `OrdenationModel<M>` | — | Ordenação fixa injetada automaticamente na query. |
622
622
  | `injectPagination` | `PaginationModel<M>` | — | Paginação fixa injetada automaticamente na query. |
@@ -1,54 +1,54 @@
1
- /**
2
- * Literal types representing the library's internal error codes.
3
- */
4
- export type VSRepoErrorType =
5
- | 'VSREPO_CONFIG'
6
- | 'VSREPO_BUILD'
7
- | 'VSREPO_EXTEND'
8
- | 'VSREPO_RUNTIME';
9
-
10
- /**
11
- * Base class for all errors thrown by the Virtual Schema Repository.
12
- */
13
- export declare abstract class VSRepoError extends Error {
14
- /** Internal code used to identify the error category. */
15
- abstract readonly type: VSRepoErrorType;
16
-
17
- constructor(message: string, type: VSRepoErrorType);
18
- }
19
-
20
- /**
21
- * Thrown when an invalid configuration or setup inconsistency is detected
22
- * before or during repository initialization.
23
- */
24
- export declare class VSRepoConfigError extends VSRepoError {
25
- readonly type: 'VSREPO_CONFIG';
26
- constructor(message: string);
27
- }
28
-
29
- /**
30
- * Thrown when the Prisma instance injection fails or when the repository
31
- * cannot be finalized through `.build()`.
32
- */
33
- export declare class VSRepoBuildError extends VSRepoError {
34
- readonly type: 'VSREPO_BUILD';
35
- constructor(message: string);
36
- }
37
-
38
- /**
39
- * Thrown when an error occurs while injecting new methods into the
40
- * repository through `.extend()`.
41
- */
42
- export declare class VSRepoExtendError extends VSRepoError {
43
- readonly type: 'VSREPO_EXTEND';
44
- constructor(message: string);
45
- }
46
-
47
- /**
48
- * Thrown when dynamic operations fail at runtime, such as when invalid
49
- * arguments are passed to methods.
50
- */
51
- export declare class VSRepoRuntimeError extends VSRepoError {
52
- readonly type: 'VSREPO_RUNTIME';
53
- constructor(message: string);
54
- }
1
+ /**
2
+ * Tipos literais que representam os códigos de erro internos da biblioteca.
3
+ */
4
+ export type VSRepoErrorType =
5
+ | 'VSREPO_CONFIG'
6
+ | 'VSREPO_BUILD'
7
+ | 'VSREPO_EXTEND'
8
+ | 'VSREPO_RUNTIME';
9
+
10
+ /**
11
+ * Classe base para todos os erros lançados pelo Virtual Schema Repository.
12
+ */
13
+ export declare abstract class VSRepoError extends Error {
14
+ /** Código interno usado para identificar a categoria do erro. */
15
+ abstract readonly type: VSRepoErrorType;
16
+
17
+ constructor(message: string, type: VSRepoErrorType);
18
+ }
19
+
20
+ /**
21
+ * Lançado quando uma configuração inválida ou uma inconsistência de
22
+ * configuração é detectada antes ou durante a inicialização do repositório.
23
+ */
24
+ export declare class VSRepoConfigError extends VSRepoError {
25
+ readonly type: 'VSREPO_CONFIG';
26
+ constructor(message: string);
27
+ }
28
+
29
+ /**
30
+ * Lançado quando a injeção da instância do Prisma falha ou quando o
31
+ * repositório não pode ser finalizado por meio de `.build()`.
32
+ */
33
+ export declare class VSRepoBuildError extends VSRepoError {
34
+ readonly type: 'VSREPO_BUILD';
35
+ constructor(message: string);
36
+ }
37
+
38
+ /**
39
+ * Lançado quando ocorre um erro ao injetar novos métodos no repositório
40
+ * por meio de `.extend()`.
41
+ */
42
+ export declare class VSRepoExtendError extends VSRepoError {
43
+ readonly type: 'VSREPO_EXTEND';
44
+ constructor(message: string);
45
+ }
46
+
47
+ /**
48
+ * Lançado quando operações dinâmicas falham em tempo de execução, como
49
+ * quando argumentos inválidos são passados para métodos.
50
+ */
51
+ export declare class VSRepoRuntimeError extends VSRepoError {
52
+ readonly type: 'VSREPO_RUNTIME';
53
+ constructor(message: string);
54
+ }
@@ -1,8 +1,19 @@
1
- import { Prisma, PrismaClient } from '@vsrepo/prisma/types';
2
-
3
- export type DbClient = PrismaClient;
4
- export type DbTransaction = Prisma.TransactionClient;
5
- export type ClientOrTransaction = DbClient | DbTransaction;
1
+ import { Prisma, PrismaClient } from '@vsrepo/prisma/types';
2
+
3
+ /**
4
+ * Instância completa do Prisma Client usada para construir repositories.
5
+ */
6
+ export type DbClient = PrismaClient;
7
+
8
+ /**
9
+ * Cliente transacional do Prisma retornado por `prisma.$transaction`.
10
+ */
11
+ export type DbTransaction = Prisma.TransactionClient;
12
+
13
+ /**
14
+ * Aceita tanto o cliente principal do Prisma quanto um cliente de transação.
15
+ */
16
+ export type ClientOrTransaction = DbClient | DbTransaction;
6
17
 
7
18
  export * from './VSRepoError.js';
8
19
 
@@ -10,13 +21,26 @@ type OrderPattern = {
10
21
  [key: string]: 'asc' | 'desc' | { _count: 'asc' | 'desc' } | OrderPattern;
11
22
  };
12
23
 
13
- export type PaginationOptions<TCursor = unknown> = {
14
- skip?: number;
15
- take?: number;
16
- cursor?: TCursor;
17
- };
18
-
19
- export type OrderOptions = OrderPattern | OrderPattern[];
24
+ /**
25
+ * Opções de paginação aceitas pelos métodos com sufixo `Paginated`.
26
+ *
27
+ * @template TCursor Tipo do cursor usado pelo modelo Prisma.
28
+ */
29
+ export type PaginationOptions<TCursor = unknown> = {
30
+ /** Quantidade de registros a ignorar. */
31
+ skip?: number;
32
+ /** Quantidade máxima de registros retornados. */
33
+ take?: number;
34
+ /** Cursor tipado para paginação baseada em posição. */
35
+ cursor?: TCursor;
36
+ };
37
+
38
+ /**
39
+ * Ordenação aceita pelos métodos do repository.
40
+ *
41
+ * Pode ser uma única ordenação ou uma lista de ordenações encadeadas.
42
+ */
43
+ export type OrderOptions = OrderPattern | OrderPattern[];
20
44
 
21
45
  type ValidMethodPatterns =
22
46
  | `existsBy${string}` | `findBy${string}` | `findUniqueBy${string}`
@@ -27,14 +51,18 @@ type ValidMethodPatterns =
27
51
  | `deleteBy${string}` | `countBy${string}` | `count${string}`
28
52
  | `findWhere${string}` | `findListWhere${string}`;
29
53
 
30
- // Modificadores consolidados em Unions para processamento rápido
31
- type Modifiers =
32
- | 'NotStartsWith' | 'StartsWith' | 'NotEndsWith' | 'EndsWith'
33
- | 'NotContains' | 'Contains' | 'LessThanEqual' | 'LessThan'
34
- | 'GreaterThanEqual' | 'GreaterThan' | 'NotIn' | 'In' | 'Not'
35
- | 'Insensitive' | 'NotInsensitive' | 'InInsensitive' | 'ContainsInsensitive';
54
+ type StringModifiers =
55
+ | 'NotStartsWith' | 'StartsWith' | 'NotEndsWith' | 'EndsWith'
56
+ | 'NotContains' | 'Contains' | 'NotIn' | 'In' | 'Not';
36
57
 
37
- type StripModifier<S extends string> = S extends `${infer Base}${Modifiers}` ? Base : S;
58
+ type NumberModifiers =
59
+ | 'LessThanEqual' | 'LessThan' | 'GreaterThanEqual' | 'GreaterThan';
60
+
61
+ type StripModifier<S extends string> =
62
+ S extends `${infer Base}${`${StringModifiers}Insensitive`}` ? Base :
63
+ S extends `${infer Base}${StringModifiers | NumberModifiers}` ? Base :
64
+ S extends `${infer Base}Insensitive` ? Base :
65
+ S;
38
66
 
39
67
  type ExtractFieldName<S extends string> = Uncapitalize<StripModifier<S>>;
40
68
 
@@ -61,7 +89,6 @@ type GetFieldType<T, S extends string, I> = ExtractFieldName<S> extends infer Fi
61
89
  : unknown
62
90
  : unknown;
63
91
 
64
- // Otimização: Validação O(1) com Union Strings
65
92
  type NoArgModifiers = 'IsNull' | 'IsNotNull' | 'IsTrue' | 'IsFalse' | 'None' | 'Some' | 'Every' | 'Without';
66
93
 
67
94
  type IsNoArgModifier<S extends string> =
@@ -128,7 +155,6 @@ type ExtraArgs<M extends string, R extends string, I> = [
128
155
  : [])
129
156
  ];
130
157
 
131
- // A resolução do modelo é feita instantaneamente pela Engine nativa do Prisma Client usando `Prisma.Result`.
132
158
  type PrismaDelegate<M extends Prisma.ModelName> = Uncapitalize<M> extends keyof DbClient ? DbClient[Uncapitalize<M>] : never;
133
159
 
134
160
  type FullModelType<M extends Prisma.ModelName> =
@@ -150,13 +176,32 @@ type CleanFields<R extends string> =
150
176
  R extends `${infer F}Ordered` ? F :
151
177
  R extends `${infer F}SkipDuplicates` ? F : R;
152
178
 
153
- export type MethodOptions<S> = { selectModel?: S | false; db?: ClientOrTransaction };
154
- export type MethodOptionsModel<T> = MethodOptions<keyof T | false>;
179
+ /**
180
+ * Opções adicionais aceitas pelos métodos do repository.
181
+ *
182
+ * @template S Chaves disponíveis em `selectModels`.
183
+ */
184
+ export type MethodOptions<S> = {
185
+ /**
186
+ * Select model a ser aplicado na operação.
187
+ *
188
+ * Use `false` para retornar o payload completo do Prisma, sem select.
189
+ */
190
+ selectModel?: S | false;
191
+ /**
192
+ * Cliente Prisma ou transação que deve executar a operação.
193
+ */
194
+ db?: ClientOrTransaction;
195
+ };
196
+
197
+ /**
198
+ * Versão de `MethodOptions` derivada de um mapa de select models.
199
+ */
200
+ export type MethodOptionsModel<T> = MethodOptions<keyof T | false>;
155
201
 
156
202
  type MethodFn<MethodName extends string, T, M extends Prisma.ModelName, R extends string, SelectModels, DefaultSelect extends keyof SelectModels | false, I> =
157
203
  <S extends keyof SelectModels | false = DefaultSelect>(...args: [...ExtractFields<T, CleanFields<R>, I>, ...ExtraArgs<MethodName, R, I>, options?: MethodOptions<S>]) => Promise<ResolveReturnType<MethodName, SelectedModel<M, S, SelectModels>>>;
158
204
 
159
- // Otimização: Achatamento da inferência de padrões
160
205
  type GetMappedMethod<K extends string, MethodConf> =
161
206
  K extends `findBy${string}` ? (MethodConf extends { fbMode: 'one' } ? 'findByOne' : 'findByList') :
162
207
  K extends `existsBy${string}` ? 'existsBy' :
@@ -165,13 +210,13 @@ type GetMappedMethod<K extends string, MethodConf> =
165
210
  K extends `findManyBy${string}` | `findMany${string}` ? 'findMany' :
166
211
  K extends `createManyAndReturn${string}` ? 'createManyAndReturn' :
167
212
  K extends `createMany${string}` ? 'createMany' :
168
- K extends `create${string}` ? 'create' : // Precisa ficar depois dos createMany
213
+ K extends `create${string}` ? 'create' :
169
214
  K extends `updateManyAndReturnBy${string}` ? 'updateManyAndReturnBy' :
170
215
  K extends `updateManyBy${string}` ? 'updateManyBy' :
171
- K extends `updateBy${string}` ? 'updateBy' : // Precisa ficar depois dos updateMany
216
+ K extends `updateBy${string}` ? 'updateBy' :
172
217
  K extends `upsertBy${string}` ? 'upsertBy' :
173
218
  K extends `deleteManyBy${string}` ? 'deleteManyBy' :
174
- K extends `deleteBy${string}` ? 'deleteBy' : // Precisa ficar depois do deleteMany
219
+ K extends `deleteBy${string}` ? 'deleteBy' :
175
220
  K extends `countBy${string}` | `count${string}` ? 'count' :
176
221
  K extends `findListWhere${string}` ? 'findListWhere' :
177
222
  K extends `findWhere${string}` ? 'findWhere' :
@@ -201,52 +246,118 @@ type DynamicMethods<T, M extends Prisma.ModelName, Config, I> = Config extends {
201
246
  }
202
247
  : {};
203
248
 
204
- export type PrismaModelInputs<M extends Prisma.ModelName> = {
205
- select: Prisma.TypeMap['model'][M]['operations']['findMany']['args']['select'];
206
- createInput: Prisma.TypeMap['model'][M]['operations']['create']['args']['data'];
207
- createManyInput: Prisma.TypeMap['model'][M]['operations']['createMany']['args']['data'];
208
- updateInput: Prisma.TypeMap['model'][M]['operations']['update']['args']['data'];
209
- updateManyInput: Prisma.TypeMap['model'][M]['operations']['updateMany']['args']['data'];
210
- whereInput: Prisma.TypeMap['model'][M]['operations']['findMany']['args']['where'];
211
- orderByInput: Prisma.TypeMap['model'][M]['operations']['findMany']['args']['orderBy'];
212
- cursorInput: Prisma.TypeMap['model'][M]['operations']['findMany']['args']['cursor'];
213
- upsertCreateInput: Prisma.TypeMap['model'][M]['operations']['upsert']['args']['create'];
214
- upsertUpdateInput: Prisma.TypeMap['model'][M]['operations']['upsert']['args']['update'];
215
- };
216
-
217
- export type SelectModel<M extends Prisma.ModelName> = PrismaModelInputs<M>['select'];
218
- export type SelectModels<M extends Prisma.ModelName> = Record<string, SelectModel<M>>;
219
- export type WhereModel<M extends Prisma.ModelName> = PrismaModelInputs<M>['whereInput'];
220
- export type OrdenationModel<M extends Prisma.ModelName> = PrismaModelInputs<M>['orderByInput'];
221
- export type PaginationModel<M extends Prisma.ModelName> = PaginationOptions<PrismaModelInputs<M>['cursorInput']>;
222
- export type ModelUpsertInput<M extends Prisma.ModelName> = PrismaModelInputs<M>['upsertCreateInput'];
223
-
224
- export type MethodConfig<M extends Prisma.ModelName, SelectModels = any> = {
225
- readonly map: boolean;
226
- readonly selectModel?: keyof SelectModels | false;
227
- readonly whereType?: 'overwrite' | 'extending';
228
- readonly proxyTo?: ValidMethodPatterns;
229
- readonly pushWhere?: WhereModel<M>;
230
- readonly fbMode?: 'one' | 'list';
231
- readonly injectOrdenation?: OrdenationModel<M>;
232
- readonly injectPagination?: PaginationModel<M>;
233
- };
234
-
235
- type BaseMethodConfig<TSelectKeys extends PropertyKey = string> = {
236
- active?: boolean;
237
- defaultSelect?: TSelectKeys;
238
- ignoreRequiredWhere?: boolean;
239
- };
240
-
241
- export type BuildConfig<TSelectKeys extends PropertyKey = string> = {
242
- freeze?: boolean;
243
- showWorking?: boolean;
244
- baseMethods?: {
245
- get?: BaseMethodConfig<TSelectKeys>;
246
- remove?: BaseMethodConfig<TSelectKeys>;
247
- save?: BaseMethodConfig<TSelectKeys>;
248
- };
249
- };
249
+ /**
250
+ * Agrupa os principais tipos de input do Prisma derivados de um modelo.
251
+ *
252
+ * @template M Nome do modelo Prisma.
253
+ */
254
+ export type PrismaModelInputs<M extends Prisma.ModelName> = {
255
+ /** Tipo do argumento `select` usado em consultas do modelo. */
256
+ select: Prisma.TypeMap['model'][M]['operations']['findMany']['args']['select'];
257
+ /** Tipo do `data` usado em `create`. */
258
+ createInput: Prisma.TypeMap['model'][M]['operations']['create']['args']['data'];
259
+ /** Tipo do `data` usado em `createMany`. */
260
+ createManyInput: Prisma.TypeMap['model'][M]['operations']['createMany']['args']['data'];
261
+ /** Tipo do `data` usado em `update`. */
262
+ updateInput: Prisma.TypeMap['model'][M]['operations']['update']['args']['data'];
263
+ /** Tipo do `data` usado em `updateMany`. */
264
+ updateManyInput: Prisma.TypeMap['model'][M]['operations']['updateMany']['args']['data'];
265
+ /** Tipo do `where` usado nas buscas do modelo. */
266
+ whereInput: Prisma.TypeMap['model'][M]['operations']['findMany']['args']['where'];
267
+ /** Tipo do `orderBy` usado nas buscas do modelo. */
268
+ orderByInput: Prisma.TypeMap['model'][M]['operations']['findMany']['args']['orderBy'];
269
+ /** Tipo do cursor usado nas buscas do modelo. */
270
+ cursorInput: Prisma.TypeMap['model'][M]['operations']['findMany']['args']['cursor'];
271
+ /** Tipo do payload `create` usado em `upsert`. */
272
+ upsertCreateInput: Prisma.TypeMap['model'][M]['operations']['upsert']['args']['create'];
273
+ /** Tipo do payload `update` usado em `upsert`. */
274
+ upsertUpdateInput: Prisma.TypeMap['model'][M]['operations']['upsert']['args']['update'];
275
+ };
276
+
277
+ /**
278
+ * Tipo do objeto `select` de um modelo Prisma.
279
+ */
280
+ export type SelectModel<M extends Prisma.ModelName> = PrismaModelInputs<M>['select'];
281
+
282
+ /**
283
+ * Mapa de selects nomeados e reutilizáveis para um modelo Prisma.
284
+ */
285
+ export type SelectModels<M extends Prisma.ModelName> = Record<string, SelectModel<M>>;
286
+
287
+ /**
288
+ * Tipo do objeto `where` de um modelo Prisma.
289
+ */
290
+ export type WhereModel<M extends Prisma.ModelName> = PrismaModelInputs<M>['whereInput'];
291
+
292
+ /**
293
+ * Tipo do objeto `orderBy` de um modelo Prisma.
294
+ */
295
+ export type OrdenationModel<M extends Prisma.ModelName> = PrismaModelInputs<M>['orderByInput'];
296
+
297
+ /**
298
+ * Opções de paginação com cursor tipado para um modelo Prisma.
299
+ */
300
+ export type PaginationModel<M extends Prisma.ModelName> = PaginationOptions<PrismaModelInputs<M>['cursorInput']>;
301
+
302
+ /**
303
+ * Payload base usado para criar um registro no `save`/`upsert` do modelo.
304
+ */
305
+ export type ModelUpsertInput<M extends Prisma.ModelName> = PrismaModelInputs<M>['upsertCreateInput'];
306
+
307
+ /**
308
+ * Configuração de um método dinâmico definido em `methods`.
309
+ *
310
+ * @template M Nome do modelo Prisma.
311
+ * @template SelectModels Mapa de select models disponíveis no repository.
312
+ */
313
+ export type MethodConfig<M extends Prisma.ModelName, SelectModels = any> = {
314
+ /** Define se o método será exposto no repository. */
315
+ readonly map: boolean;
316
+ /** Sobrescreve o `defaultSelectModel` apenas para este método. */
317
+ readonly selectModel?: keyof SelectModels | false;
318
+ /** Controla se o método combina ou sobrescreve o `requiredWhere`. */
319
+ readonly whereType?: 'overwrite' | 'extending';
320
+ /** Redireciona a lógica para outro padrão de método válido. */
321
+ readonly proxyTo?: ValidMethodPatterns;
322
+ /** Adiciona um `where` extra além do `requiredWhere`. */
323
+ readonly pushWhere?: WhereModel<M>;
324
+ /** Define se `findBy` retorna um item (`one`) ou uma lista (`list`). */
325
+ readonly fbMode?: 'one' | 'list';
326
+ /** Injeta uma ordenação fixa automaticamente na query. */
327
+ readonly injectOrdenation?: OrdenationModel<M>;
328
+ /** Injeta uma paginação fixa automaticamente na query. */
329
+ readonly injectPagination?: PaginationModel<M>;
330
+ };
331
+
332
+ type BaseMethodConfig<TSelectKeys extends PropertyKey = string> = {
333
+ /** Ativa ou desativa o método base no `build`. */
334
+ active?: boolean;
335
+ /** Select model padrão usado pelo método base. */
336
+ defaultSelect?: TSelectKeys;
337
+ /** Ignora o `requiredWhere` no `save`. */
338
+ ignoreRequiredWhere?: boolean;
339
+ };
340
+
341
+ /**
342
+ * Configuração aplicada durante o `.build(prisma, config?)`.
343
+ *
344
+ * @template TSelectKeys Chaves válidas de `selectModels`.
345
+ */
346
+ export type BuildConfig<TSelectKeys extends PropertyKey = string> = {
347
+ /** Congela o objeto final do repository. */
348
+ freeze?: boolean;
349
+ /** Exibe logs internos de funcionamento no console. */
350
+ showWorking?: boolean;
351
+ /** Personaliza o comportamento dos métodos base automáticos. */
352
+ baseMethods?: {
353
+ /** Configuração do método `get`. */
354
+ get?: BaseMethodConfig<TSelectKeys>;
355
+ /** Configuração do método `remove`. */
356
+ remove?: BaseMethodConfig<TSelectKeys>;
357
+ /** Configuração do método `save`. */
358
+ save?: BaseMethodConfig<TSelectKeys>;
359
+ };
360
+ };
250
361
 
251
362
  type ResolveMethodDefaultSelect<Config, C, Method extends 'get' | 'remove' | 'save', TSelects = ExtractSelectModels<Config>> =
252
363
  C extends { baseMethods?: { [_ in Method]?: { defaultSelect?: infer D } } }
@@ -290,7 +401,10 @@ type InjectedRemove<
290
401
  ): Promise<ResolveCurrentReturn<M, TSelects, S, TDefault>>;
291
402
  };
292
403
 
293
- export type DistributiveOmit<T, K extends keyof any> = T extends any ? Omit<T, K> : never;
404
+ /**
405
+ * Versão distributiva de `Omit`, preservando unions ao remover propriedades.
406
+ */
407
+ export type DistributiveOmit<T, K extends keyof any> = T extends any ? Omit<T, K> : never;
294
408
  type ExtractUnionProp<T, K extends PropertyKey> = T extends any ? (K extends keyof T ? T[K] : never) : never;
295
409
 
296
410
  type ExtractNestedCreateInput<M extends Prisma.ModelName, K extends PropertyKey> =
@@ -304,10 +418,16 @@ type RelationPayload<TField, TRelationConfig, M extends Prisma.ModelName, K exte
304
418
  ? ExtractNestedCreateInput<M, K> | (TRelationConfig extends { mode: 'oto'; restriction: 'set' } | { mode: 'mto'; nullAble: true } ? null : never)
305
419
  : never;
306
420
 
307
- export type UpsertWithRelations<T, M extends Prisma.ModelName, TRelations> =
308
- DistributiveOmit<ModelUpsertInput<M>, keyof TRelations> & {
309
- [K in Extract<keyof TRelations, keyof T>]?: RelationPayload<T[K], TRelations[K], M, K>;
310
- };
421
+ /**
422
+ * Payload aceito pelo `save` quando o repository possui relações configuradas.
423
+ *
424
+ * Substitui os campos relacionais pelo formato compatível com os modos
425
+ * configurados em `relations`.
426
+ */
427
+ export type UpsertWithRelations<T, M extends Prisma.ModelName, TRelations> =
428
+ DistributiveOmit<ModelUpsertInput<M>, keyof TRelations> & {
429
+ [K in Extract<keyof TRelations, keyof T>]?: RelationPayload<T[K], TRelations[K], M, K>;
430
+ };
311
431
 
312
432
  type InjectedSave<
313
433
  T, M extends Prisma.ModelName, Config, C extends BuildConfig<any> | undefined,
@@ -329,65 +449,124 @@ type InjectedBaseMethods<T, M extends Prisma.ModelName, Config, C extends BuildC
329
449
  InjectedRemove<T, M, Config, C> &
330
450
  InjectedSave<T, M, Config, C>;
331
451
 
332
- export type ExtractRelationConfig<TField> = NonNullable<TField> extends infer NonNull
333
- ? NonNull extends Date | Buffer | Uint8Array ? never
334
- : NonNull extends any[] ? (NonNull[number] extends object ? { pk: keyof NonNull[number]; mode: 'otm' | 'mtm'; restriction: 'set' | 'add' } : never)
335
- : NonNull extends object ? ({ pk: keyof NonNull; mode: 'oto'; restriction: 'set' | 'add' } | { pk: keyof NonNull; mode: 'mto'; restriction: 'set' | 'add'; nullAble?: boolean })
336
- : never
337
- : never;
338
-
339
- export type RepositoryRelations<T> = {
340
- [K in keyof T as ExtractRelationConfig<T[K]> extends never ? never : K]?: ExtractRelationConfig<T[K]>;
341
- };
452
+ /**
453
+ * Infere automaticamente a configuração de relação possível a partir de um campo.
454
+ */
455
+ export type ExtractRelationConfig<TField> = NonNullable<TField> extends infer NonNull
456
+ ? NonNull extends Date | Buffer | Uint8Array ? never
457
+ : NonNull extends any[] ? (NonNull[number] extends object ? { pk: keyof NonNull[number]; mode: 'otm' | 'mtm'; restriction: 'set' | 'add' } : never)
458
+ : NonNull extends object ? ({ pk: keyof NonNull; mode: 'oto'; restriction: 'set' | 'add' } | { pk: keyof NonNull; mode: 'mto'; restriction: 'set' | 'add'; nullAble?: boolean })
459
+ : never
460
+ : never;
461
+
462
+ /**
463
+ * Mapa das relações configuráveis de um tipo de entidade.
464
+ */
465
+ export type RepositoryRelations<T> = {
466
+ [K in keyof T as ExtractRelationConfig<T[K]> extends never ? never : K]?: ExtractRelationConfig<T[K]>;
467
+ };
342
468
 
343
469
  type AnySelect<M extends Prisma.ModelName> = Prisma.TypeMap['model'][M]['operations']['findMany']['args']['select'];
344
470
 
345
- export type RepoConfig<T, M extends Prisma.ModelName, SM extends Record<string, AnySelect<M>> = Record<string, AnySelect<M>>> = {
346
- tableName: Uncapitalize<M>;
347
- pkName: keyof T;
348
- selectModels?: SM;
349
- defaultSelectModel?: Extract<keyof SM, string>;
350
- requiredWhere?: WhereModel<M>;
351
- relations?: RepositoryRelations<T>;
352
- methods?: Record<string, MethodConfig<M, SM>>;
353
- };
354
-
355
- export type BuiltRepository<T extends object, M extends Prisma.ModelName, Config extends RepoConfig<T, M, any>, C extends BuildConfig<any> | undefined> = {
356
- extend<E>(extensionFunc: (repo: BuiltRepository<T, M, Config, C>) => E): BuiltRepository<T, M, Config, C> & E;
357
- } & DynamicMethods<T, M, Config, PrismaModelInputs<M>> & InjectedBaseMethods<T, M, Config, C>;
358
-
359
- export declare class VSRepository<T extends object, M extends Prisma.ModelName, const Config extends RepoConfig<T, M, any> = RepoConfig<T, M, any>> {
360
- readonly config: Config;
361
- constructor(config: Config);
362
- build<C extends BuildConfig<any>>(prisma: DbClient, config?: C): BuiltRepository<T, M, Config, C>;
363
- vsrepocache: never;
364
- }
365
-
366
- export type RepositoryOf<TRepo, C extends BuildConfig<any> | undefined = undefined, E = unknown> =
367
- TRepo extends VSRepository<infer T, infer M, infer Config>
368
- ? BuiltRepository<T, M, Config, C> & E
369
- : never;
370
-
371
- export type ValidateRepoConfig<T extends object, M extends Prisma.ModelName, Config> = {
372
- tableName: Uncapitalize<M>;
373
- pkName: keyof T;
374
- selectModels?: SelectModels<M>;
375
- defaultSelectModel?: Config extends { selectModels: infer SM } ? (keyof SM extends never ? string : Extract<keyof SM, string>) : string;
376
- requiredWhere?: WhereModel<M>;
377
- relations?: RepositoryRelations<T>;
378
- methods?: {
379
- [K in keyof (Config extends { methods: infer Meth } ? Meth : {})]: K extends string
380
- ? HasMultipleANDs<K> extends true
381
- ? MethodConfig<M, Config extends { selectModels: infer SM } ? SM : any> & { proxyTo: ValidMethodPatterns }
382
- : MethodConfig<M, Config extends { selectModels: infer SM } ? SM : any> & (K extends ValidMethodPatterns ? {} : { proxyTo: ValidMethodPatterns })
383
- : never;
384
- };
385
- };
386
-
387
- export declare function setupVSRepo<T extends object, M extends Prisma.ModelName>(): <
388
- const SM extends Record<string, SelectModel<M>>,
389
- const Config extends RepoConfig<T, M, SM>
390
- >(
471
+ /**
472
+ * Configuração principal usada em `setupVSRepo<T, M>()(config)`.
473
+ *
474
+ * @template T Tipo da entidade manipulada pelo repository.
475
+ * @template M Nome do modelo Prisma.
476
+ * @template SM Mapa de select models nomeados.
477
+ */
478
+ export type RepoConfig<T, M extends Prisma.ModelName, SM extends Record<string, AnySelect<M>> = Record<string, AnySelect<M>>> = {
479
+ /** Nome da tabela/modelo no Prisma. */
480
+ tableName: Uncapitalize<M>;
481
+ /** Nome da chave primária da entidade. */
482
+ pkName: keyof T;
483
+ /** Projeções de dados nomeadas e reutilizáveis. */
484
+ selectModels?: SM;
485
+ /** Select model aplicado por padrão quando nenhum for informado. */
486
+ defaultSelectModel?: Extract<keyof SM, string>;
487
+ /** Filtros aplicados automaticamente em todas as queries do repository. */
488
+ requiredWhere?: WhereModel<M>;
489
+ /** Configuração das relações gerenciadas pelo `save`. */
490
+ relations?: RepositoryRelations<T>;
491
+ /** Métodos dinâmicos expostos pelo repository. */
492
+ methods?: Record<string, MethodConfig<M, SM>>;
493
+ };
494
+
495
+ /**
496
+ * Tipo final retornado por `.build(prisma)`.
497
+ *
498
+ * Combina métodos dinâmicos, métodos base e extensões personalizadas.
499
+ */
500
+ export type BuiltRepository<T extends object, M extends Prisma.ModelName, Config extends RepoConfig<T, M, any>, C extends BuildConfig<any> | undefined> = {
501
+ /**
502
+ * Estende o repository com métodos personalizados sem perder a tipagem.
503
+ */
504
+ extend<E>(extensionFunc: (repo: BuiltRepository<T, M, Config, C>) => E): BuiltRepository<T, M, Config, C> & E;
505
+ } & DynamicMethods<T, M, Config, PrismaModelInputs<M>> & InjectedBaseMethods<T, M, Config, C>;
506
+
507
+ /**
508
+ * Fábrica tipada de repositories baseada na configuração do modelo Prisma.
509
+ */
510
+ export declare class VSRepository<T extends object, M extends Prisma.ModelName, const Config extends RepoConfig<T, M, any> = RepoConfig<T, M, any>> {
511
+ /** Configuração original informada no `setupVSRepo`. */
512
+ readonly config: Config;
513
+ /**
514
+ * Cria uma instância configurável de `VSRepository`.
515
+ */
516
+ constructor(config: Config);
517
+ /**
518
+ * Constrói o repository final com os métodos base e dinâmicos.
519
+ */
520
+ build<C extends BuildConfig<any>>(prisma: DbClient, config?: C): BuiltRepository<T, M, Config, C>;
521
+ vsrepocache: never;
522
+ }
523
+
524
+ /**
525
+ * Infere o tipo de um repository já configurado a partir de uma instância de `VSRepository`.
526
+ *
527
+ * Também permite informar manualmente o `BuildConfig` e o tipo de extensões.
528
+ */
529
+ export type RepositoryOf<TRepo, C extends BuildConfig<any> | undefined = undefined, E = unknown> =
530
+ TRepo extends VSRepository<infer T, infer M, infer Config>
531
+ ? BuiltRepository<T, M, Config, C> & E
532
+ : never;
533
+
534
+ /**
535
+ * Tipo utilitário usado para validar a configuração de um repository em tempo de compilação.
536
+ */
537
+ export type ValidateRepoConfig<T extends object, M extends Prisma.ModelName, Config> = {
538
+ /** Nome da tabela/modelo no Prisma. */
539
+ tableName: Uncapitalize<M>;
540
+ /** Nome da chave primária da entidade. */
541
+ pkName: keyof T;
542
+ /** Mapa de select models disponíveis. */
543
+ selectModels?: SelectModels<M>;
544
+ /** Chave do select model padrão. */
545
+ defaultSelectModel?: Config extends { selectModels: infer SM } ? (keyof SM extends never ? string : Extract<keyof SM, string>) : string;
546
+ /** Filtros globais aplicados às queries do repository. */
547
+ requiredWhere?: WhereModel<M>;
548
+ /** Relações gerenciadas automaticamente pelo `save`. */
549
+ relations?: RepositoryRelations<T>;
550
+ /** Mapa dos métodos dinâmicos e suas regras de validação. */
551
+ methods?: {
552
+ [K in keyof (Config extends { methods: infer Meth } ? Meth : {})]: K extends string
553
+ ? HasMultipleANDs<K> extends true
554
+ ? MethodConfig<M, Config extends { selectModels: infer SM } ? SM : any> & { proxyTo: ValidMethodPatterns }
555
+ : MethodConfig<M, Config extends { selectModels: infer SM } ? SM : any> & (K extends ValidMethodPatterns ? {} : { proxyTo: ValidMethodPatterns })
556
+ : never;
557
+ };
558
+ };
559
+
560
+ /**
561
+ * Cria uma fábrica tipada para definir repositories fortemente tipados com Prisma.
562
+ *
563
+ * Use esta função para declarar `tableName`, `pkName`, `selectModels`,
564
+ * `requiredWhere`, `relations` e `methods` do seu repository.
565
+ */
566
+ export declare function setupVSRepo<T extends object, M extends Prisma.ModelName>(): <
567
+ const SM extends Record<string, SelectModel<M>>,
568
+ const Config extends RepoConfig<T, M, SM>
569
+ >(
391
570
  config: Config extends ValidateRepoConfig<T, M, Config>
392
571
  ? Config
393
572
  : ValidateRepoConfig<T, M, Config>
package/package.json CHANGED
@@ -1,7 +1,12 @@
1
1
  {
2
2
  "name": "vsrepo",
3
- "version": "1.0.5",
4
- "description": "Uma biblioteca de repositório virtual para Prisma",
3
+ "version": "1.0.7",
4
+ "description": "Uma biblioteca de repository pattern para Prisma",
5
+ "homepage": "https://github.com/jaobrabo123/VSRepository#readme",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/jaobrabo123/VSRepository"
9
+ },
5
10
  "main": "./VSRepository/index.js",
6
11
  "types": "./VSRepository/index.d.ts",
7
12
  "exports": {
@@ -42,7 +47,7 @@
42
47
  "vsrepo",
43
48
  "vsrepository"
44
49
  ],
45
- "author": "João Pedro Azevedo",
50
+ "author": "João Pedro Azevedo Freire Mecenas",
46
51
  "license": "MIT",
47
52
  "peerDependencies": {
48
53
  "@prisma/client": "^7.8.0"
@@ -169,6 +169,17 @@ for (const file of tsFiles) {
169
169
  console.log(`Gerado: ${path.relative(workspaceRoot, targetFile)}`);
170
170
  }
171
171
 
172
+ // Copia o README.md do pacote VSRepository para o diretório de output, se existir
173
+ const readmeSource = path.join(packageRoot, 'README.md');
174
+ const readmeTarget = path.join(outputDir, 'README.md');
175
+
176
+ if (fs.existsSync(readmeSource)) {
177
+ fs.copyFileSync(readmeSource, readmeTarget);
178
+ console.log(`Copiado: ${path.relative(workspaceRoot, readmeTarget)} (origem: ${path.relative(workspaceRoot, readmeSource)})`);
179
+ } else {
180
+ console.warn(`README.md do VSRepository nao encontrado em: ${path.relative(workspaceRoot, readmeSource)}. Ignorando a copia.`);
181
+ }
182
+
172
183
  console.log('\nVSRepository gerado com tipagem do Prisma.');
173
184
  console.log(`Output: ${outputDir}`);
174
185
  console.log(`Prisma usado em: ${prismaTargetPath}`);