vsrepo 1.2.9 → 1.3.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/README.md CHANGED
@@ -30,6 +30,7 @@ O VSRepository permite criar repositories fortemente tipados com:
30
30
  - [Merge](#merge)
31
31
  - [Configurando os métodos base](#configurando-os-métodos-base)
32
32
  - [Select Models](#select-models)
33
+ - [Include Models](#include-models)
33
34
  - [Required Where](#requiredwhere)
34
35
  - [Default Ordenation](#default-ordenation)
35
36
  - [Opção `see`](#opção-see)
@@ -464,6 +465,51 @@ const usuarioCompleto = await usuarioRepository.get(id, { selectModel: false });
464
465
 
465
466
  ---
466
467
 
468
+ ## Include Models
469
+
470
+ `includeModels` funciona de forma parecida com o `selectModels`, mas em vez de receber um `select`, ele recebe um `include` válido do Prisma.
471
+
472
+ ```ts
473
+ const usuarioRepository = setupVSRepo<Usuario, "usuario">()(({
474
+ tableName: "usuario",
475
+ pkName: "id",
476
+ selectModels: {
477
+ public: { id: true, nome: true, email: true },
478
+ },
479
+ defaultSelectModel: "public",
480
+ includeModels: {
481
+ comPosts: { posts: true },
482
+ comPostsEPerfil: { posts: true, perfil: true },
483
+ },
484
+ }).build(prisma);
485
+ ```
486
+
487
+ **Usando um `includeModel` na chamada:**
488
+
489
+ ```ts
490
+ const usuario = await usuarioRepository.get(id, { includeModel: "comPosts" });
491
+ ```
492
+
493
+ Nesse caso, o `select` padrão (`selectModels`/`defaultSelectModel`) é ignorado e apenas o `include` é enviado ao Prisma.
494
+
495
+ ### Diferenças em relação ao `selectModels`
496
+
497
+ - **Só pode ser passado na chamada do método**, via `options.includeModel`. Não existe `defaultIncludeModel` nem `defaultInclude` — não há como configurar um `includeModel` padrão no repository, diferente do que ocorre com `defaultSelectModel`.
498
+ - **`includeModel` e `selectModel` não podem ser passados juntos** na mesma chamada. Se um `includeModel` for informado, qualquer `selectModel` (incluindo o padrão) é ignorado.
499
+
500
+ ```ts
501
+ // CORRETO ✅ — apenas includeModel
502
+ await usuarioRepository.get(id, { includeModel: "comPosts" });
503
+
504
+ // CORRETO ✅ — apenas selectModel
505
+ await usuarioRepository.get(id, { selectModel: "public" });
506
+
507
+ // ERRADO ❌ — não é permitido combinar os dois
508
+ await usuarioRepository.get(id, { selectModel: "public", includeModel: "comPosts" });
509
+ ```
510
+
511
+ ---
512
+
467
513
  ## Required Where
468
514
 
469
515
  `requiredWhere` define filtros aplicados automaticamente em todas as queries do repository.
@@ -973,6 +1019,8 @@ type SeeMode = "active" | "removed" | "all";
973
1019
  import type {
974
1020
  SelectModel,
975
1021
  SelectModels,
1022
+ IncludeModel,
1023
+ IncludeModels,
976
1024
  WhereModel,
977
1025
  OrdenationModel,
978
1026
  PaginationModel,
@@ -986,14 +1034,16 @@ import type {
986
1034
  ```ts
987
1035
  import type { MethodOptions, MethodOptionsModel } from "../../generated/vsrepo";
988
1036
 
989
- // MethodOptions<S> — opções passadas nos métodos do repository
990
- type Opts = MethodOptions<"public" | "minimal">;
1037
+ // MethodOptions<S, IM> — opções passadas nos métodos do repository
1038
+ type Opts = MethodOptions<"public" | "minimal", "comPosts">;
991
1039
 
992
1040
  // MethodOptionsModel<TRepo> — derivado de uma instância VSRepository configurada
993
1041
  const usuarioVSRepo = setupVSRepo<Usuario, "usuario">()(config);
994
1042
  type OptsModel = MethodOptionsModel<typeof usuarioVSRepo>;
995
1043
  ```
996
1044
 
1045
+ > O segundo parâmetro de `MethodOptions` (`IM`) representa as chaves válidas de `includeModels`. Quando informado, `selectModel` e `includeModel` tornam-se mutuamente exclusivos no tipo — não é possível passar os dois na mesma chamada.
1046
+
997
1047
  ### Tipos de configuração
998
1048
 
999
1049
  ```ts
@@ -1049,8 +1099,9 @@ setupVSRepo<TPayload, TTableName>()({
1049
1099
  tableName: Uncapitalize<M>; // Nome da tabela no Prisma
1050
1100
  pkName: keyof T; // Nome da primary key
1051
1101
  softRemovekName?: keyof T & string; // Campo DateTime para soft-delete (opcional)
1052
- selectModels?: SelectModels<M>; // Projeções de dados nomeadas
1102
+ selectModels?: SelectModels<M>; // Projeções de dados nomeadas (select)
1053
1103
  defaultSelectModel?: keyof SM; // Select aplicado por padrão
1104
+ includeModels?: IncludeModels<M>; // Projeções de dados nomeadas (include) — sem default, só na chamada
1054
1105
  requiredWhere?: WhereModel<M>; // Filtros sempre aplicados
1055
1106
  defaultOrdenation?: OrdenationModel<M>; // Ordenação padrão para queries sem Ordered/injectOrdenation
1056
1107
  relations?: RepositoryRelations<T>; // Configuração de relações
@@ -1146,6 +1197,10 @@ Para reportar problemas ou sugerir novas funcionalidades, abra uma **Issue**.
1146
1197
 
1147
1198
  **Select model retorna campos inesperados** — Verifique se o select model define exatamente os campos que o seu tipo TypeScript espera. Campos com `false` não serão retornados pelo Prisma.
1148
1199
 
1200
+ **`selectModel` e `includeModel` juntos na mesma chamada** — Não é permitido. Escolha um ou outro: se `includeModel` for informado, o `select` (incluindo o `defaultSelectModel`) é ignorado e apenas o `include` é enviado ao Prisma.
1201
+
1202
+ **`includeModel` não aparece como opção padrão do repository** — Isso é esperado. Diferente de `defaultSelectModel`, não existe `defaultIncludeModel`/`defaultInclude`. Um `includeModel` só pode ser definido na chamada do método, via `options.includeModel`.
1203
+
1149
1204
  **`softRemovekName` lança erro no build** — O campo informado deve ser do tipo `DateTime` no schema do Prisma. Tipos como `Boolean` ou `String` não são aceitos.
1150
1205
 
1151
1206
  **`defaultOrdenation` não está sendo aplicada** — Verifique se o método não usa o sufixo `Ordered`, `OrderedAndPaginated` ou `PaginatedAndOrdered`, e se não possui `injectOrdenation` configurado. Ambos têm prioridade sobre a ordenação padrão.
@@ -50,5 +50,5 @@ export declare class VSRepoExtendError extends VSRepoError {
50
50
  */
51
51
  export declare class VSRepoRuntimeError extends VSRepoError {
52
52
  readonly type: 'VSREPO_RUNTIME';
53
- constructor(message: string, code?: string);
53
+ constructor(message: string, code: string);
54
54
  }
@@ -222,14 +222,22 @@ type PrecomputedSelects<M extends Prisma.ModelName, SelectModels> = {
222
222
  [S in keyof SelectModels]: Prisma.Result<PrismaDelegate<M>, { select: SelectModels[S] }, 'findMany'> extends Array<infer U> ? U : never
223
223
  };
224
224
 
225
- type SelectedModel<M extends Prisma.ModelName, S, SelectModels> =
226
- [S] extends [false]
227
- ? FullModelType<M>
228
- : [S] extends [never]
229
- ? FullModelType<M>
230
- : [S] extends [keyof SelectModels]
231
- ? PrecomputedSelects<M, SelectModels>[S]
232
- : FullModelType<M>;
225
+ type PrecomputedIncludes<M extends Prisma.ModelName, IncludeModels> = {
226
+ [I in keyof IncludeModels]: Prisma.Result<PrismaDelegate<M>, { include: IncludeModels[I] }, 'findMany'> extends Array<infer U> ? U : never
227
+ };
228
+
229
+ type SelectedModel<M extends Prisma.ModelName, S, SelectModels, IM = never, IncludeModels = {}> =
230
+ [IM] extends [never]
231
+ ? [S] extends [false]
232
+ ? FullModelType<M>
233
+ : [S] extends [never]
234
+ ? FullModelType<M>
235
+ : [S] extends [keyof SelectModels]
236
+ ? PrecomputedSelects<M, SelectModels>[S]
237
+ : FullModelType<M>
238
+ : IM extends keyof IncludeModels
239
+ ? PrecomputedIncludes<M, IncludeModels>[IM]
240
+ : FullModelType<M>;
233
241
 
234
242
  type CleanFields<R extends string> =
235
243
  R extends `${infer F}PaginatedAndOrdered` ? F :
@@ -242,17 +250,10 @@ type CleanFields<R extends string> =
242
250
  * Additional options accepted by repository methods.
243
251
  *
244
252
  * @template S Available keys in `selectModels`.
253
+ * @template IM Available keys in `includeModels`.
245
254
  */
246
- export type MethodOptions<S> = {
247
- /**
248
- * Select model to apply to the operation.
249
- *
250
- * @note Use `false` to return the full Prisma payload without a select.
251
- */
252
- selectModel?: S | false;
253
- /**
254
- * Prisma client or transaction to use for the operation.
255
- */
255
+ export type MethodOptions<S, IM extends PropertyKey = never> = {
256
+ /** Prisma client or transaction to use for the operation. */
256
257
  db?: ClientOrTransaction;
257
258
  /**
258
259
  * Visibility mode for records with soft-delete.
@@ -264,7 +265,17 @@ export type MethodOptions<S> = {
264
265
  * - `"all"` — returns all records, ignoring deletion status.
265
266
  */
266
267
  see?: SeeMode;
267
- };
268
+ } & (
269
+ [IM] extends [never]
270
+ ? {
271
+ /** Select model to apply to the operation. Use `false` to return the full payload. */
272
+ selectModel?: S | false;
273
+ /** Include model to apply to the operation. Cannot be used together with `selectModel`. */
274
+ includeModel?: never;
275
+ }
276
+ : | { selectModel?: S | false; includeModel?: never }
277
+ | { selectModel?: never; includeModel: IM }
278
+ );
268
279
 
269
280
  /**
270
281
  * Version of `MethodOptions` derived directly from a configured `VSRepository` instance.
@@ -277,11 +288,13 @@ export type MethodOptions<S> = {
277
288
  */
278
289
  export type MethodOptionsModel<TRepo> =
279
290
  TRepo extends VSRepository<any, any, infer Config>
280
- ? MethodOptions<keyof ExtractSelectModels<Config> | false>
291
+ ? MethodOptions<keyof ExtractSelectModels<Config> | false, keyof ExtractIncludeModels<Config>>
281
292
  : never;
282
293
 
283
- type MethodFn<MethodName extends string, T, M extends Prisma.ModelName, R extends string, SelectModels, DefaultSelect extends keyof SelectModels | false, I> =
284
- <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>>>;
294
+ type MethodFn<MethodName extends string, T, M extends Prisma.ModelName, R extends string, SelectModels, DefaultSelect extends keyof SelectModels | false, I, IncludeModels> =
295
+ <S extends keyof SelectModels | false = DefaultSelect, IM extends keyof IncludeModels = never>(
296
+ ...args: [...ExtractFields<T, CleanFields<R>, I>, ...ExtraArgs<MethodName, R, I>, options?: MethodOptions<S, keyof IncludeModels> & ({ includeModel: IM } | { includeModel?: never })]
297
+ ) => Promise<ResolveReturnType<MethodName, SelectedModel<M, S, SelectModels, IM, IncludeModels>>>;
285
298
 
286
299
  type GetMappedMethod<K extends string, MethodConf> =
287
300
  K extends `findBy${string}` ? (MethodConf extends { fbMode: 'one' } ? 'findByOne' : 'findByList') :
@@ -332,13 +345,13 @@ type ExtractPatternBase<K extends string> =
332
345
  K extends `updateManyAndReturnWhere${infer R}` ? R :
333
346
  K extends `deleteManyWhere${infer R}` ? R : '';
334
347
 
335
- type MethodFactory<T, M extends Prisma.ModelName, K extends string, SelectModels, DefaultSelect extends keyof SelectModels | false, I, MethodConf> =
348
+ type MethodFactory<T, M extends Prisma.ModelName, K extends string, SelectModels, DefaultSelect extends keyof SelectModels | false, I, MethodConf, IncludeModels> =
336
349
  K extends `findWhere${string}`
337
350
  ? {
338
351
  /** @deprecated Use findOneWhere instead. */
339
- <S extends keyof SelectModels | false = DefaultSelect>(...args: [...ExtractFields<T, CleanFields<ExtractPatternBase<K>>, I>, ...ExtraArgs<GetMappedMethod<K, MethodConf>, ExtractPatternBase<K>, I>, options?: MethodOptions<S>]): Promise<ResolveReturnType<GetMappedMethod<K, MethodConf>, SelectedModel<M, S, SelectModels>>>;
352
+ <S extends keyof SelectModels | false = DefaultSelect, IM extends keyof IncludeModels = never>(...args: [...ExtractFields<T, CleanFields<ExtractPatternBase<K>>, I>, ...ExtraArgs<GetMappedMethod<K, MethodConf>, ExtractPatternBase<K>, I>, options?: MethodOptions<S, keyof IncludeModels> & ({ includeModel: IM } | { includeModel?: never })]): Promise<ResolveReturnType<GetMappedMethod<K, MethodConf>, SelectedModel<M, S, SelectModels, IM, IncludeModels>>>;
340
353
  }
341
- : MethodFn<GetMappedMethod<K, MethodConf>, T, M, ExtractPatternBase<K>, SelectModels, DefaultSelect, I>;
354
+ : MethodFn<GetMappedMethod<K, MethodConf>, T, M, ExtractPatternBase<K>, SelectModels, DefaultSelect, I, IncludeModels>;
342
355
 
343
356
  type ResolveSelectModel<MethodConf, GlobalConf, SelectModels> =
344
357
  MethodConf extends { selectModel: infer S } ? (S extends false ? false : S extends keyof SelectModels ? S : never) :
@@ -346,6 +359,7 @@ type ResolveSelectModel<MethodConf, GlobalConf, SelectModels> =
346
359
 
347
360
  type ExtractPkName<T, Config> = Config extends { pkName: infer PK } ? (PK extends keyof T ? PK : never) : never;
348
361
  type ExtractSelectModels<Config> = Config extends { selectModels: infer SM } ? SM : {};
362
+ type ExtractIncludeModels<Config> = Config extends { includeModels: infer IM } ? IM : {};
349
363
  type ExtractDefaultSelect<Config> = Config extends { defaultSelectModel: infer D } ? D : never;
350
364
  type ExtractRelations<Config> = Config extends { relations: infer R } ? (R extends object ? R : {}) : {};
351
365
  type ExtractSoftRemovekName<Config> = Config extends { softRemovekName: infer S } ? S : never;
@@ -370,7 +384,7 @@ type DynamicMethods<T, M extends Prisma.ModelName, Config, I> = Config extends {
370
384
  : ResolvedKey extends 'groupBy'
371
385
  ? GroupByMethod<M>
372
386
  : ResolvedKey extends string
373
- ? MethodFactory<T, M, ResolvedKey, ExtractSelectModels<Config>, ResolveSelectModel<Methods[K], Config, ExtractSelectModels<Config>>, I, Methods[K]>
387
+ ? MethodFactory<T, M, ResolvedKey, ExtractSelectModels<Config>, ResolveSelectModel<Methods[K], Config, ExtractSelectModels<Config>>, I, Methods[K], ExtractIncludeModels<Config>>
374
388
  : never
375
389
  : never
376
390
  : never;
@@ -385,6 +399,8 @@ type DynamicMethods<T, M extends Prisma.ModelName, Config, I> = Config extends {
385
399
  export type PrismaModelInputs<M extends Prisma.ModelName> = {
386
400
  /** Type of the `select` argument used in model queries. */
387
401
  select: Prisma.TypeMap['model'][M]['operations']['findMany']['args']['select'];
402
+ /** Type of the `include` argument used in model queries. */
403
+ include: Prisma.TypeMap['model'][M]['operations']['findMany']['args']['include'];
388
404
  /** Type of the `data` used in `create`. */
389
405
  createInput: Prisma.TypeMap['model'][M]['operations']['create']['args']['data'];
390
406
  /** Type of the `data` used in `createMany`. */
@@ -415,6 +431,16 @@ export type SelectModel<M extends Prisma.ModelName> = PrismaModelInputs<M>['sele
415
431
  */
416
432
  export type SelectModels<M extends Prisma.ModelName> = Record<string, SelectModel<M>>;
417
433
 
434
+ /**
435
+ * Type of the `include` object of a Prisma model.
436
+ */
437
+ export type IncludeModel<M extends Prisma.ModelName> = PrismaModelInputs<M>['include'];
438
+
439
+ /**
440
+ * Map of named, reusable includes for a Prisma model.
441
+ */
442
+ export type IncludeModels<M extends Prisma.ModelName> = Record<string, IncludeModel<M>>;
443
+
418
444
  /**
419
445
  * Type of the `where` object of a Prisma model.
420
446
  */
@@ -452,8 +478,7 @@ export type MethodConfig<M extends Prisma.ModelName, SelectModels = any> = {
452
478
  readonly proxyTo?: ValidMethodPatterns;
453
479
  /** Adds an extra `where` on top of `requiredWhere`. */
454
480
  readonly pushWhere?: WhereModel<M>;
455
- /**
456
- * Defines whether `findBy` returns a single item (`one`) or a list (`list`).
481
+ /** * Defines whether `findBy` returns a single item (`one`) or a list (`list`).
457
482
  * @deprecated Use `findOneBy` if you want to return a single result.
458
483
  */
459
484
  readonly fbMode?: 'one' | 'list';
@@ -497,8 +522,12 @@ export type BuildConfig<TSelectKeys extends PropertyKey = string> = {
497
522
  remove?: BaseMethodConfig<TSelectKeys>;
498
523
  /** Configuration for the `save` method. */
499
524
  save?: BaseMethodConfig<TSelectKeys>;
525
+ /** Configuration for the `saveList` method (batch save via transaction). */
526
+ saveList?: BaseMethodConfig<TSelectKeys>;
500
527
  /** Configuration for the `patch` method. */
501
528
  patch?: BaseMethodConfig<TSelectKeys>;
529
+ /** Configuration for the `patchList` method (batch update via transaction). */
530
+ patchList?: BaseMethodConfig<TSelectKeys>;
502
531
  /** Configuration for the `merge` method. */
503
532
  merge?: BaseMethodConfig<TSelectKeys>;
504
533
  /** Configuration for the `removeList` method (batch deletion). Does not accept select. */
@@ -509,10 +538,6 @@ export type BuildConfig<TSelectKeys extends PropertyKey = string> = {
509
538
  total?: Omit<BaseMethodConfig<TSelectKeys>, 'defaultSelect'>;
510
539
  /** Configuration for the `has` method (existence check). Does not accept select. */
511
540
  has?: Omit<BaseMethodConfig<TSelectKeys>, 'defaultSelect'>;
512
- /** Configuration for the `saveList` method (batch save via transaction). */
513
- saveList?: BaseMethodConfig<TSelectKeys>;
514
- /** Configuration for the `patchList` method (batch update via transaction). */
515
- patchList?: BaseMethodConfig<TSelectKeys>;
516
541
  /** Configuration for the `softRemove` method. Only available if `softRemovekName` is configured. */
517
542
  softRemove?: BaseMethodConfig<TSelectKeys>;
518
543
  /** Configuration for the `softRemoveList` method. Does not accept select. Only available if `softRemovekName` is configured. */
@@ -535,12 +560,16 @@ type ResolveMethodDefaultSelect<Config, C, Method extends keyof NonNullable<Buil
535
560
  ? ExtractDefaultSelect<Config>
536
561
  : false;
537
562
 
538
- type ResolveCurrentReturn<M extends Prisma.ModelName, Models, S, D> =
539
- [S] extends [false]
540
- ? FullModelType<M>
541
- : [S] extends [never]
542
- ? ([D] extends [never] ? FullModelType<M> : SelectedModel<M, D, Models>)
543
- : SelectedModel<M, S, Models>;
563
+ type ResolveCurrentReturn<M extends Prisma.ModelName, Models, S, D, IM = never, Includes = {}> =
564
+ [IM] extends [never]
565
+ ? [S] extends [false]
566
+ ? FullModelType<M>
567
+ : [S] extends [never]
568
+ ? ([D] extends [never] ? FullModelType<M> : SelectedModel<M, D, Models>)
569
+ : SelectedModel<M, S, Models>
570
+ : IM extends keyof Includes
571
+ ? PrecomputedIncludes<M, Includes>[IM]
572
+ : FullModelType<M>;
544
573
 
545
574
  // ─── helpers reused within the mapped type ───────────────────────────────────
546
575
  // ─── relation payload types ──────────────────────────────────────────────────
@@ -603,13 +632,21 @@ type RelationUpdatePayload<TField, TRelationConfig, M extends Prisma.ModelName,
603
632
  : never;
604
633
 
605
634
  /**
606
- * Payload accepted by `patch` when the repository has configured relations.
635
+ * Payload accepted by `merge` when the repository has configured relations (uses update input).
607
636
  */
608
637
  type UpdateWithRelations<T, M extends Prisma.ModelName, TRelations> =
609
638
  DistributiveOmit<PrismaModelInputs<M>['updateInput'], keyof TRelations> & {
610
639
  [K in Extract<keyof TRelations, keyof T>]?: RelationUpdatePayload<T[K], TRelations[K], M, K>;
611
640
  };
612
641
 
642
+ /**
643
+ * Payload accepted by `patch` and `patchList` when the repository has configured relations (uses create input).
644
+ */
645
+ type PatchWithRelations<T, M extends Prisma.ModelName, TRelations> =
646
+ DistributiveOmit<PrismaModelInputs<M>['updateInput'], keyof TRelations> & {
647
+ [K in Extract<keyof TRelations, keyof T>]?: RelationPayload<T[K], TRelations[K], M, K>;
648
+ };
649
+
613
650
  /**
614
651
  * Extracts the payload type of the `save` method from a configured VSRepository instance.
615
652
  */
@@ -631,17 +668,18 @@ export type PatchObject<TInput, TRepo> =
631
668
  TRepo extends VSRepository<infer T, infer M, infer Config>
632
669
  ? (Config extends { relations: infer R } ? (R extends object ? R : {}) : {}) extends infer TRelations
633
670
  ? DistributiveOmit<TInput, keyof TRelations> & {
634
- [K in Extract<keyof TRelations, keyof T>]?: RelationUpdatePayload<T[K], TRelations[K], M, K>;
671
+ [K in Extract<keyof TRelations, keyof T>]?: RelationPayload<T[K], TRelations[K], M, K>;
635
672
  }
636
673
  : never
637
674
  : never;
638
675
 
639
676
 
640
677
  type _Pk<T, Config> = WidenField<T[ExtractPkName<T, Config> extends keyof T ? ExtractPkName<T, Config> : never]>;
641
- type _Ret<M extends Prisma.ModelName, TSelects, S, TDefault> = ResolveCurrentReturn<M, TSelects, S, TDefault>;
678
+ type _Ret<M extends Prisma.ModelName, TSelects, S, TDefault, IM = never, TIncludes = {}> = ResolveCurrentReturn<M, TSelects, S, TDefault, IM, TIncludes>;
642
679
  type _DS<Config, C, Method extends keyof NonNullable<BuildConfig['baseMethods']>, TSelects = ExtractSelectModels<Config>> =
643
680
  ResolveMethodDefaultSelect<Config, C, Method, TSelects>;
644
681
  type _Sel<Config> = ExtractSelectModels<Config>;
682
+ type _Inc<Config> = ExtractIncludeModels<Config>;
645
683
  type _Def<Config> = ExtractDefaultSelect<Config>;
646
684
  type _Rel<Config> = ExtractRelations<Config>;
647
685
  type _Soft<Config> = ExtractSoftRemovekName<Config>;
@@ -660,59 +698,60 @@ type AllBaseMethods<
660
698
  TRelations = _Rel<Config>,
661
699
  TSoftKey = _Soft<Config>,
662
700
  I = PrismaModelInputs<M>,
663
- TDefaultOrdenation = _DOrd<Config>
701
+ TDefaultOrdenation = _DOrd<Config>,
702
+ TIncludes = _Inc<Config>
664
703
  > = {
665
704
  /** Fetches a record by its primary key (PK). */
666
- get: <S extends keyof TSelects | false = _DS<Config, C, 'get', TSelects>>(
667
- pk: _Pk<T, Config>, options?: MethodOptions<S>
668
- ) => Promise<_Ret<M, TSelects, S, TDefault> | null>;
705
+ get: <S extends keyof TSelects | false = _DS<Config, C, 'get', TSelects>, IM extends keyof TIncludes = never>(
706
+ pk: _Pk<T, Config>, options?: MethodOptions<S, keyof TIncludes> & ({ includeModel: IM } | { includeModel?: never })
707
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes> | null>;
669
708
 
670
709
  /** Fetches a record by PK and throws `VSRepoRuntimeError` if not found. */
671
- getOrThrow: <S extends keyof TSelects | false = _DS<Config, C, 'getOrThrow', TSelects>>(
672
- pk: _Pk<T, Config>, options?: MethodOptions<S>
673
- ) => Promise<_Ret<M, TSelects, S, TDefault>>;
710
+ getOrThrow: <S extends keyof TSelects | false = _DS<Config, C, 'getOrThrow', TSelects>, IM extends keyof TIncludes = never>(
711
+ pk: _Pk<T, Config>, options?: MethodOptions<S, keyof TIncludes> & ({ includeModel: IM } | { includeModel?: never })
712
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes>>;
674
713
 
675
714
  /** Fetches multiple records by a list of primary keys (PKs). */
676
- getList: <S extends keyof TSelects | false = _DS<Config, C, 'getList', TSelects>>(
677
- pks: _Pk<T, Config>[], options?: MethodOptions<S>
678
- ) => Promise<_Ret<M, TSelects, S, TDefault>[]>;
715
+ getList: <S extends keyof TSelects | false = _DS<Config, C, 'getList', TSelects>, IM extends keyof TIncludes = never>(
716
+ pks: _Pk<T, Config>[], options?: MethodOptions<S, keyof TIncludes> & ({ includeModel: IM } | { includeModel?: never })
717
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes>[]>;
679
718
 
680
719
  /** Deletes a record identified by its primary key (PK). */
681
- remove: <S extends keyof TSelects | false = _DS<Config, C, 'remove', TSelects>>(
682
- pk: _Pk<T, Config>, options?: MethodOptions<S>
683
- ) => Promise<_Ret<M, TSelects, S, TDefault>>;
720
+ remove: <S extends keyof TSelects | false = _DS<Config, C, 'remove', TSelects>, IM extends keyof TIncludes = never>(
721
+ pk: _Pk<T, Config>, options?: MethodOptions<S, keyof TIncludes> & ({ includeModel: IM } | { includeModel?: never })
722
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes>>;
684
723
 
685
724
  /** Inserts or updates (upsert) a record. */
686
- save: <S extends keyof TSelects | false = _DS<Config, C, 'save', TSelects>>(
687
- obj: UpsertWithRelations<T, M, TRelations>, options?: MethodOptions<S>
688
- ) => Promise<_Ret<M, TSelects, S, TDefault>>;
725
+ save: <S extends keyof TSelects | false = _DS<Config, C, 'save', TSelects>, IM extends keyof TIncludes = never>(
726
+ obj: UpsertWithRelations<T, M, TRelations>, options?: MethodOptions<S, keyof TIncludes> & ({ includeModel: IM } | { includeModel?: never })
727
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes>>;
689
728
 
690
729
  /** Saves an array of objects in a single automatic transaction. */
691
- saveList: <S extends keyof TSelects | false = _DS<Config, C, 'saveList', TSelects>>(
692
- objs: UpsertWithRelations<T, M, TRelations>[], options?: Omit<MethodOptions<S>, 'db'> & { db?: DbTransaction }
693
- ) => Promise<_Ret<M, TSelects, S, TDefault>[]>;
730
+ saveList: <S extends keyof TSelects | false = _DS<Config, C, 'saveList', TSelects>, IM extends keyof TIncludes = never>(
731
+ objs: UpsertWithRelations<T, M, TRelations>[], options?: Omit<MethodOptions<S, keyof TIncludes>, 'db'> & ({ includeModel: IM } | { includeModel?: never }) & { db?: DbTransaction }
732
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes>[]>;
694
733
 
695
734
  /** Partially updates (patch) an existing record by its primary key (PK). */
696
- patch: <S extends keyof TSelects | false = _DS<Config, C, 'patch', TSelects>>(
697
- pk: _Pk<T, Config>, obj: UpdateWithRelations<T, M, TRelations>, options?: MethodOptions<S>
698
- ) => Promise<_Ret<M, TSelects, S, TDefault>>;
735
+ patch: <S extends keyof TSelects | false = _DS<Config, C, 'patch', TSelects>, IM extends keyof TIncludes = never>(
736
+ pk: _Pk<T, Config>, obj: PatchWithRelations<T, M, TRelations>, options?: MethodOptions<S, keyof TIncludes> & ({ includeModel: IM } | { includeModel?: never })
737
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes>>;
699
738
 
700
739
  /** Partially updates multiple records via `[pk, obj]` tuples in an automatic transaction. */
701
- patchList: <S extends keyof TSelects | false = _DS<Config, C, 'patchList', TSelects>>(
702
- tuples: [pk: _Pk<T, Config>, obj: UpdateWithRelations<T, M, TRelations>][], options?: Omit<MethodOptions<S>, 'db'> & { db?: DbTransaction }
703
- ) => Promise<_Ret<M, TSelects, S, TDefault>[]>;
740
+ patchList: <S extends keyof TSelects | false = _DS<Config, C, 'patchList', TSelects>, IM extends keyof TIncludes = never>(
741
+ tuples: [pk: _Pk<T, Config>, obj: PatchWithRelations<T, M, TRelations>][], options?: Omit<MethodOptions<S, keyof TIncludes>, 'db'> & ({ includeModel: IM } | { includeModel?: never }) & { db?: DbTransaction }
742
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes>[]>;
704
743
 
705
744
  /** Fetches a record by PK and deep-merges it with the provided object **in memory**. */
706
- merge: <S extends keyof TSelects | false = _DS<Config, C, 'merge', TSelects>>(
707
- pk: _Pk<T, Config>, obj: UpdateWithRelations<T, M, TRelations>, options?: MethodOptions<S>
708
- ) => Promise<_Ret<M, TSelects, S, TDefault> | null>;
745
+ merge: <S extends keyof TSelects | false = _DS<Config, C, 'merge', TSelects>, IM extends keyof TIncludes = never>(
746
+ pk: _Pk<T, Config>, obj: UpdateWithRelations<T, M, TRelations>, options?: MethodOptions<S, keyof TIncludes> & ({ includeModel: IM } | { includeModel?: never })
747
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes> | null>;
709
748
 
710
749
  /** Deletes multiple records by their primary keys. */
711
750
  removeList: (pks: _Pk<T, Config>[], options?: { db?: ClientOrTransaction }) => Promise<{ count: number }>;
712
751
 
713
752
  /** Fetches all records (respects `requiredWhere` when set). */
714
- getAll: <S extends keyof TSelects | false = _DS<Config, C, 'getAll', TSelects>>(
715
- options?: MethodOptions<S> & {
753
+ getAll: <S extends keyof TSelects | false = _DS<Config, C, 'getAll', TSelects>, IM extends keyof TIncludes = never>(
754
+ options?: MethodOptions<S, keyof TIncludes> & ({ includeModel: IM } | { includeModel?: never }) & {
716
755
  pagination?: PaginationOptions<I extends { cursorInput: infer Curs } ? Curs : unknown>;
717
756
  /**
718
757
  * Ordering to apply to the query.
@@ -721,7 +760,7 @@ type AllBaseMethods<
721
760
  */
722
761
  order?: I extends { orderByInput: infer OB } ? OB : OrderOptions;
723
762
  }
724
- ) => Promise<_Ret<M, TSelects, S, TDefault>[]>;
763
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes>[]>;
725
764
 
726
765
  /** Returns the total number of records. */
727
766
  total: (options?: { db?: ClientOrTransaction; see?: SeeMode }) => Promise<number>;
@@ -730,17 +769,17 @@ type AllBaseMethods<
730
769
  has: (pk: _Pk<T, Config>, options?: { db?: ClientOrTransaction; see?: SeeMode }) => Promise<boolean>;
731
770
 
732
771
  /** Marks a record as deleted (soft-delete). */
733
- softRemove: <S extends keyof TSelects | false = _DS<Config, C, 'softRemove', TSelects>>(
734
- pk: _Pk<T, Config>, options?: Omit<MethodOptions<S>, 'see'>
735
- ) => Promise<_Ret<M, TSelects, S, TDefault>>;
772
+ softRemove: <S extends keyof TSelects | false = _DS<Config, C, 'softRemove', TSelects>, IM extends keyof TIncludes = never>(
773
+ pk: _Pk<T, Config>, options?: Omit<MethodOptions<S, keyof TIncludes>, 'see'> & ({ includeModel: IM } | { includeModel?: never })
774
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes>>;
736
775
 
737
776
  /** Marks multiple records as deleted (soft-delete) in batch. */
738
777
  softRemoveList: (pks: _Pk<T, Config>[], options?: { db?: ClientOrTransaction }) => Promise<{ count: number }>;
739
778
 
740
779
  /** Restores a record previously marked as deleted (soft-delete). */
741
- restore: <S extends keyof TSelects | false = _DS<Config, C, 'restore', TSelects>>(
742
- pk: _Pk<T, Config>, options?: Omit<MethodOptions<S>, 'see'>
743
- ) => Promise<_Ret<M, TSelects, S, TDefault>>;
780
+ restore: <S extends keyof TSelects | false = _DS<Config, C, 'restore', TSelects>, IM extends keyof TIncludes = never>(
781
+ pk: _Pk<T, Config>, options?: Omit<MethodOptions<S, keyof TIncludes>, 'see'> & ({ includeModel: IM } | { includeModel?: never })
782
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes>>;
744
783
 
745
784
  /** Restores multiple records previously marked as deleted (soft-delete) in batch. */
746
785
  restoreList: (pks: _Pk<T, Config>[], options?: { db?: ClientOrTransaction }) => Promise<{ count: number }>;
@@ -757,9 +796,10 @@ type InjectedBaseMethods<
757
796
  TRelations = _Rel<Config>,
758
797
  TSoftKey = _Soft<Config>,
759
798
  I = PrismaModelInputs<M>,
760
- TDefaultOrdenation = _DOrd<Config>
799
+ TDefaultOrdenation = _DOrd<Config>,
800
+ TIncludes = _Inc<Config>
761
801
  > = Pick<
762
- AllBaseMethods<T, M, Config, C, TSelects, TDefault, TPk, TRelations, TSoftKey, I, TDefaultOrdenation>,
802
+ AllBaseMethods<T, M, Config, C, TSelects, TDefault, TPk, TRelations, TSoftKey, I, TDefaultOrdenation, TIncludes>,
763
803
  | (C extends { baseMethods: { get: { active: false } } } ? never : 'get')
764
804
  | (C extends { baseMethods: { getOrThrow: { active: false } } } ? never : 'getOrThrow')
765
805
  | (C extends { baseMethods: { getList: { active: false } } } ? never : 'getList')
@@ -861,6 +901,7 @@ export type RepoConfig<T, M extends Prisma.ModelName, SM extends Record<string,
861
901
  softRemovekName?: keyof T & string;
862
902
  selectModels?: SM;
863
903
  defaultSelectModel?: Extract<keyof SM, string>;
904
+ includeModels?: IncludeModels<M>;
864
905
  requiredWhere?: WhereModel<M>;
865
906
  defaultOrdenation?: OrdenationModel<M>;
866
907
  relations?: RepositoryRelations<T>;
@@ -946,6 +987,12 @@ export type ValidateRepoConfig<T extends object, M extends Prisma.ModelName, Con
946
987
  */
947
988
  defaultSelectModel?: string;
948
989
 
990
+ /**
991
+ * Defines named and reusable include projections.
992
+ * Similar to selectModels, but resolves Prisma `include` clauses.
993
+ */
994
+ includeModels?: IncludeModels<M>;
995
+
949
996
  /**
950
997
  * Defines global filters that will be automatically applied to all repository queries.
951
998
  * Useful for tenant isolation (multi-tenancy) or base restrictions (e.g., `isActive: true`).
@@ -35,6 +35,7 @@ class VSRepository {
35
35
  pkName;
36
36
  softRemovekName;
37
37
  selectModels;
38
+ includeModels;
38
39
  defaultSelectModel;
39
40
  requiredWhere;
40
41
  relations;
@@ -47,6 +48,7 @@ class VSRepository {
47
48
  this.pkName = validatedConfig.pkName;
48
49
  this.softRemovekName = validatedConfig.softRemovekName;
49
50
  this.selectModels = validatedConfig.selectModels;
51
+ this.includeModels = validatedConfig.includeModels;
50
52
  this.defaultSelectModel = validatedConfig.defaultSelectModel;
51
53
  this.relations = validatedConfig.relations;
52
54
  this.requiredWhere = validatedConfig.requiredWhere;
@@ -162,7 +164,7 @@ class VSRepository {
162
164
  const missingParams = dinamicMethodInfo.whereParams
163
165
  .concat(dinamicMethodInfo.otherParams)
164
166
  .slice(args.length);
165
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${buildInstance.tableName}: runtime) Missing parameters: ${missingParams.join(", ")}`);
167
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${buildInstance.tableName}: runtime) Missing parameters: ${missingParams.join(", ")}`, "48670");
166
168
  }
167
169
  else if (args.length > dinamicMethodInfo.argsCount) {
168
170
  const optionsArg = args[args.length - 1];
@@ -21,7 +21,7 @@ function resolveBaseMethods(instance, config) {
21
21
  if (baseMethods.get.active) {
22
22
  instance.get = async (pk, options) => {
23
23
  if (pk == undefined)
24
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pk' must be provided.`);
24
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pk' must be provided.`, "65706");
25
25
  const { db, prismaArgs } = (0, dbAndPrismaArgs_resolve_1.resolveDbAndPrismaArgs)({
26
26
  instance,
27
27
  baseConfig: baseMethods.get,
@@ -41,7 +41,7 @@ function resolveBaseMethods(instance, config) {
41
41
  if (baseMethods.getOrThrow.active) {
42
42
  instance.getOrThrow = async (pk, options) => {
43
43
  if (pk == undefined)
44
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pk' must be provided.`);
44
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pk' must be provided.`, "65706");
45
45
  const { db, prismaArgs } = (0, dbAndPrismaArgs_resolve_1.resolveDbAndPrismaArgs)({
46
46
  instance,
47
47
  baseConfig: baseMethods.getOrThrow,
@@ -64,7 +64,7 @@ function resolveBaseMethods(instance, config) {
64
64
  if (baseMethods.getList.active) {
65
65
  instance.getList = async (pks, options) => {
66
66
  if (!Array.isArray(pks) || pks.some(pk => pk == undefined))
67
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pks' must an array of primary keys.`);
67
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pks' must an array of primary keys.`, "65706");
68
68
  const { db, prismaArgs } = (0, dbAndPrismaArgs_resolve_1.resolveDbAndPrismaArgs)({
69
69
  instance,
70
70
  baseConfig: baseMethods.getList,
@@ -84,7 +84,7 @@ function resolveBaseMethods(instance, config) {
84
84
  if (baseMethods.getAll.active) {
85
85
  instance.getAll = async (options) => {
86
86
  if (options !== undefined && !(0, is_object_validate_1.isObject)(options))
87
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'options' must be a valid object.`);
87
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'options' must be a valid object.`, "65706");
88
88
  const { pagination, order, ...restOptions } = options ?? {};
89
89
  const { db, prismaArgs } = (0, dbAndPrismaArgs_resolve_1.resolveDbAndPrismaArgs)({
90
90
  instance,
@@ -107,7 +107,7 @@ function resolveBaseMethods(instance, config) {
107
107
  if (baseMethods.remove.active) {
108
108
  instance.remove = async (pk, options) => {
109
109
  if (pk == undefined)
110
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pk' must be provided.`);
110
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pk' must be provided.`, "65706");
111
111
  const { db, prismaArgs } = (0, dbAndPrismaArgs_resolve_1.resolveDbAndPrismaArgs)({
112
112
  instance,
113
113
  baseConfig: baseMethods.remove,
@@ -127,7 +127,7 @@ function resolveBaseMethods(instance, config) {
127
127
  if (baseMethods.removeList.active) {
128
128
  instance.removeList = async (pks, options) => {
129
129
  if (!Array.isArray(pks) || pks.some(pk => pk == undefined))
130
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pks' must an array of primary keys.`);
130
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pks' must an array of primary keys.`, "65706");
131
131
  const { db, prismaArgs } = (0, dbAndPrismaArgs_resolve_1.resolveDbAndPrismaArgs)({
132
132
  instance,
133
133
  baseConfig: baseMethods.removeList,
@@ -166,7 +166,7 @@ function resolveBaseMethods(instance, config) {
166
166
  if (baseMethods.has.active) {
167
167
  instance.has = async (pk, options) => {
168
168
  if (pk == undefined)
169
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pk' must be provided.`);
169
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pk' must be provided.`, "65706");
170
170
  const { db, prismaArgs } = (0, dbAndPrismaArgs_resolve_1.resolveDbAndPrismaArgs)({
171
171
  instance,
172
172
  baseConfig: baseMethods.has,
@@ -187,9 +187,9 @@ function resolveBaseMethods(instance, config) {
187
187
  if (baseMethods.merge.active) {
188
188
  instance.merge = async (pk, obj, options) => {
189
189
  if (pk == undefined)
190
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pk' must be provided.`);
190
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pk' must be provided.`, "65706");
191
191
  if (!(0, is_object_validate_1.isObject)(obj)) {
192
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'obj' must be a valid object.`);
192
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'obj' must be a valid object.`, "65706");
193
193
  }
194
194
  (0, obj_with_relations_validate_1.validateObjWithRelations)(instance, obj, relationsKeys);
195
195
  const { db, prismaArgs } = (0, dbAndPrismaArgs_resolve_1.resolveDbAndPrismaArgs)({
@@ -273,7 +273,7 @@ function resolveBaseMethods(instance, config) {
273
273
  if (baseMethods.softRemove.active && softRemovekName) {
274
274
  instance.softRemove = async (pk, options) => {
275
275
  if (pk == undefined)
276
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pk' must be provided.`);
276
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pk' must be provided.`, "65706");
277
277
  const { db, prismaArgs } = (0, dbAndPrismaArgs_resolve_1.resolveDbAndPrismaArgs)({
278
278
  instance,
279
279
  baseConfig: baseMethods.softRemove,
@@ -295,7 +295,7 @@ function resolveBaseMethods(instance, config) {
295
295
  if (baseMethods.softRemoveList.active && softRemovekName) {
296
296
  instance.softRemoveList = async (pks, options) => {
297
297
  if (!Array.isArray(pks) || pks.some(pk => pk == undefined))
298
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pks' must an array of primary keys.`);
298
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pks' must an array of primary keys.`, "65706");
299
299
  const { db, prismaArgs } = (0, dbAndPrismaArgs_resolve_1.resolveDbAndPrismaArgs)({
300
300
  instance,
301
301
  baseConfig: baseMethods.softRemoveList,
@@ -318,7 +318,7 @@ function resolveBaseMethods(instance, config) {
318
318
  if (baseMethods.restore.active && softRemovekName) {
319
319
  instance.restore = async (pk, options) => {
320
320
  if (pk == undefined)
321
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pk' must be provided.`);
321
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pk' must be provided.`, "65706");
322
322
  const { db, prismaArgs } = (0, dbAndPrismaArgs_resolve_1.resolveDbAndPrismaArgs)({
323
323
  instance,
324
324
  baseConfig: baseMethods.restore,
@@ -340,7 +340,7 @@ function resolveBaseMethods(instance, config) {
340
340
  if (baseMethods.restoreList.active && softRemovekName) {
341
341
  instance.restoreList = async (pks, options) => {
342
342
  if (!Array.isArray(pks) || pks.some(pk => pk == undefined))
343
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pks' must an array of primary keys.`);
343
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pks' must an array of primary keys.`, "65706");
344
344
  const { db, prismaArgs } = (0, dbAndPrismaArgs_resolve_1.resolveDbAndPrismaArgs)({
345
345
  instance,
346
346
  baseConfig: baseMethods.restoreList,
@@ -363,7 +363,7 @@ function resolveBaseMethods(instance, config) {
363
363
  if (baseMethods.save.active) {
364
364
  instance.save = async (obj, options) => {
365
365
  if (!(0, is_object_validate_1.isObject)(obj)) {
366
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'obj' must be a valid object.`);
366
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'obj' must be a valid object.`, "65706");
367
367
  }
368
368
  (0, obj_with_relations_validate_1.validateObjWithRelations)(instance, obj, relationsKeys);
369
369
  const objAny = obj;
@@ -407,7 +407,7 @@ function resolveBaseMethods(instance, config) {
407
407
  if (baseMethods.saveList.active) {
408
408
  instance.saveList = async (objs, options) => {
409
409
  if (!Array.isArray(objs) || objs.some(ob => !(0, is_object_validate_1.isObject)(ob))) {
410
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'objs' must be an array of valid objects.`);
410
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'objs' must be an array of valid objects.`, "65706");
411
411
  }
412
412
  const validatedOptions = (0, method_options_validate_1.validateMethodOptions)(options, instance);
413
413
  const argsList = [];
@@ -466,9 +466,9 @@ function resolveBaseMethods(instance, config) {
466
466
  if (baseMethods.patch.active) {
467
467
  instance.patch = async (pk, obj, options) => {
468
468
  if (pk == undefined)
469
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pk' must be provided.`);
469
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'pk' must be provided.`, "65706");
470
470
  if (!(0, is_object_validate_1.isObject)(obj)) {
471
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'obj' must be a valid object.`);
471
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'obj' must be a valid object.`, "65706");
472
472
  }
473
473
  (0, obj_with_relations_validate_1.validateObjWithRelations)(instance, obj, relationsKeys);
474
474
  const { updatePayload } = (0, create_update_payloads_with_relations_resolve_1.resolveCreateUpdatePayloadsWithRelations)(instance, obj, relationsKeys);
@@ -493,7 +493,7 @@ function resolveBaseMethods(instance, config) {
493
493
  instance.patchList = async (tuples, options) => {
494
494
  if (!Array.isArray(tuples) ||
495
495
  tuples.some(tuple => tuple[0] == undefined || !(0, is_object_validate_1.isObject)(tuple[1]))) {
496
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'tuples' must be a valid array of tuples [pk, obj].`);
496
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${tableName}: runtime) 'tuples' must be a valid array of tuples [pk, obj].`, "65706");
497
497
  }
498
498
  const validatedOptions = (0, method_options_validate_1.validateMethodOptions)(options, instance);
499
499
  const argsList = [];
@@ -6,7 +6,7 @@ const merge_wheres_resolve_1 = require("./merge-wheres.resolve");
6
6
  const select_resolve_1 = require("./select.resolve");
7
7
  function resolveDbAndPrismaArgs(data) {
8
8
  const { baseConfig, instance, options, wherePkValue, withoutSelect, withoutWhere, specificSelect, dataPayload, createPayload, updatePayload, alreadyValidatedOptions, specificWhere, pushWhere, ordenation, pagination, skipDuplicates, forceSeeMode, withOrdenationAndPagination, } = data;
9
- const validatedOptions = (alreadyValidatedOptions && options)
9
+ const validatedOptions = alreadyValidatedOptions && options
10
10
  ? options
11
11
  : (0, method_options_validate_1.validateMethodOptions)(options, instance);
12
12
  const db = validatedOptions.db ?? instance.prisma;
@@ -18,9 +18,15 @@ function resolveDbAndPrismaArgs(data) {
18
18
  }, wherePkValue != undefined ? { [instance.pkName]: wherePkValue } : specificWhere, pushWhere, instance.requiredWhere, instance.softRemovekName);
19
19
  }
20
20
  if (!withoutSelect) {
21
- prismaArgs.select =
22
- specificSelect ??
23
- (0, select_resolve_1.resolveSelect)(instance, validatedOptions.selectModel, baseConfig.defaultSelect);
21
+ if (specificSelect) {
22
+ prismaArgs.select = specificSelect;
23
+ }
24
+ else if (validatedOptions.includeModel) {
25
+ prismaArgs.include = instance.includeModels?.[validatedOptions.includeModel];
26
+ }
27
+ else {
28
+ prismaArgs.select = (0, select_resolve_1.resolveSelect)(instance, validatedOptions.selectModel, baseConfig.defaultSelect);
29
+ }
24
30
  }
25
31
  if (dataPayload) {
26
32
  prismaArgs.data = dataPayload;
@@ -14,6 +14,7 @@ function validateConstructorConfig(config) {
14
14
  pkName: schemas_util_1.stringSchema,
15
15
  softRemovekName: schemas_util_1.stringSchema.optional(),
16
16
  selectModels: zod_1.default.record(schemas_util_1.stringSchema, schemas_util_1.objectSchema).optional(),
17
+ includeModels: zod_1.default.record(schemas_util_1.stringSchema, schemas_util_1.objectSchema).optional(),
17
18
  defaultSelectModel: schemas_util_1.stringSchema.optional(),
18
19
  requiredWhere: schemas_util_1.objectSchema.optional(),
19
20
  relations: zod_1.default
@@ -8,19 +8,27 @@ const zod_1 = __importDefault(require("zod"));
8
8
  const schemas_util_1 = require("../utils/schemas.util");
9
9
  const vs_repo_error_1 = require("../errors/vs-repo.error");
10
10
  function validateMethodOptions(options, instance) {
11
- const optionsSchema = zod_1.default.strictObject({
11
+ const optionsSchema = zod_1.default
12
+ .strictObject({
12
13
  db: schemas_util_1.objectSchema.optional(),
13
14
  selectModel: zod_1.default
14
15
  .literal(false)
15
16
  .or(zod_1.default.enum(Object.keys(instance.selectModels ?? {})))
16
17
  .optional(),
18
+ includeModel: zod_1.default.enum(Object.keys(instance.includeModels ?? {})).optional(),
17
19
  see: zod_1.default.enum(["active", "removed", "all"]).default("active"),
20
+ })
21
+ .refine(data => {
22
+ return !(data.selectModel !== undefined && data.includeModel !== undefined);
23
+ }, {
24
+ message: "cannot be provided with 'selectModel'.",
25
+ path: ["includeModel"],
18
26
  });
19
27
  const optionsParsed = optionsSchema.safeParse(options ?? {});
20
28
  if (!optionsParsed.success) {
21
29
  const firstIssue = optionsParsed.error.issues[0];
22
30
  const path = firstIssue?.path.length ? firstIssue.path.join(".") : "options";
23
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${instance.tableName}: runtime) ${path}: ${firstIssue?.message}`);
31
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${instance.tableName}: runtime) ${path}: ${firstIssue?.message}`, "67542");
24
32
  }
25
33
  return optionsParsed.data;
26
34
  }
@@ -14,23 +14,23 @@ function validateObjWithRelations(instance, obj, relationsKeys) {
14
14
  const relation = relations[key];
15
15
  if (relation.mode === "mtm" || relation.mode === "otm") {
16
16
  if (obj[key] === null) {
17
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${instance.tableName}: runtime) '${key}' cannot be 'null' when relation mode is "mtm" or "otm", use an empty array instead.`);
17
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${instance.tableName}: runtime) '${key}' cannot be 'null' when relation mode is "mtm" or "otm", use an empty array instead.`, "91868");
18
18
  }
19
19
  else if (!Array.isArray(obj[key]) || obj[key].some(val => !(0, is_object_validate_1.isObject)(val))) {
20
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${instance.tableName}: runtime) '${key}' must be a valid array of objects when relation mode is "mtm" or "otm".`);
20
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${instance.tableName}: runtime) '${key}' must be a valid array of objects when relation mode is "mtm" or "otm".`, "91868");
21
21
  }
22
22
  }
23
23
  else {
24
24
  if (obj[key] === null) {
25
25
  if (relation.mode === "oto" && relation.restriction !== "set") {
26
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${instance.tableName}: runtime) '${key}' can be 'null' only if the relation restriction is "set" and mode is "oto".`);
26
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${instance.tableName}: runtime) '${key}' can be 'null' only if the relation restriction is "set" and mode is "oto".`, "91868");
27
27
  }
28
28
  else if (relation.mode === "mto" && !relation.nullable && !relation.nullAble) {
29
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${instance.tableName}: runtime) '${key}' can be 'null' only if the relation 'nullable' is 'true' and mode is "mto".`);
29
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${instance.tableName}: runtime) '${key}' can be 'null' only if the relation 'nullable' is 'true' and mode is "mto".`, "91868");
30
30
  }
31
31
  }
32
32
  else if (!(0, is_object_validate_1.isObject)(obj[key])) {
33
- throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${instance.tableName}: runtime) '${key}' must be a valid object when relation mode is "oto" or "mto".`);
33
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${instance.tableName}: runtime) '${key}' must be a valid object when relation mode is "oto" or "mto".`, "91868");
34
34
  }
35
35
  }
36
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vsrepo",
3
- "version": "1.2.9",
3
+ "version": "1.3.0",
4
4
  "description": "Uma biblioteca de repository pattern para Prisma",
5
5
  "homepage": "https://github.com/jaobrabo123/VSRepository#readme",
6
6
  "repository": {