vsrepo 1.2.1 → 1.2.2

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
@@ -1018,8 +1018,9 @@ import type { MethodOptions, MethodOptionsModel } from "../../generated/vsrepo";
1018
1018
  // S = chave do select model ou false
1019
1019
  type Opts = MethodOptions<"public" | "minimal">;
1020
1020
 
1021
- // MethodOptionsModel<T> — versão derivada do tipo do repository
1022
- type OptsModel = MethodOptionsModel<typeof usuarioSelectModels>;
1021
+ // MethodOptionsModel<TRepo> — derivado diretamente de uma instância VSRepository configurada
1022
+ const usuarioVSRepo = setupVSRepo<Usuario, "usuario">()(config);
1023
+ type OptsModel = MethodOptionsModel<typeof usuarioVSRepo>;
1023
1024
  ```
1024
1025
 
1025
1026
  ### Tipos de configuração
@@ -1031,7 +1032,6 @@ import type {
1031
1032
  BuildConfig,
1032
1033
  RepositoryRelations,
1033
1034
  ExtractRelationConfig,
1034
- UpsertWithRelations,
1035
1035
  } from "../../generated/vsrepo";
1036
1036
 
1037
1037
  // Configuração de um método dinâmico
@@ -1048,18 +1048,12 @@ type UsuarioRelations = RepositoryRelations<Usuario>;
1048
1048
 
1049
1049
  // Configuração de relação inferida a partir de um campo
1050
1050
  type PerfilRelationConfig = ExtractRelationConfig<Usuario["perfil"]>;
1051
-
1052
- // Payload do save com relações
1053
- type UsuarioComRelacoes = UpsertWithRelations<Usuario, "usuario", typeof relations>;
1054
1051
  ```
1055
1052
 
1056
1053
  ### Tipo do repository construído
1057
1054
 
1058
1055
  ```ts
1059
- import type { BuiltRepository, RepositoryOf } from "../../generated/vsrepo";
1060
-
1061
- // Tipo completo de um repository construído
1062
- type MeuRepo = BuiltRepository<Usuario, "usuario", typeof config, typeof buildConfig>;
1056
+ import type { RepositoryOf } from "../../generated/vsrepo";
1063
1057
 
1064
1058
  // Inferência a partir de uma instância VSRepository (útil para injeção de dependência)
1065
1059
  const usuarioVSRepo = setupVSRepo<Usuario, "usuario">()({ ... });
@@ -1080,15 +1074,31 @@ const extension = { buscarPorDominio: (dominio: string) => Promise<Usuario[]> };
1080
1074
  type UsuarioRepositoryExtended = RepositoryOf<typeof usuarioVSRepo, undefined, typeof extension>;
1081
1075
  ```
1082
1076
 
1083
- ### Tipo auxiliar
1077
+ ### Tipos do payload dos métodos `save` e `patch`
1078
+
1079
+ Use `SaveObject` e `PatchObject` para extrair o tipo do payload esperado pelos métodos `save` e `patch` diretamente a partir de uma instância `VSRepository` configurada. Esses tipos já levam em conta as relações configuradas.
1084
1080
 
1085
1081
  ```ts
1086
- import type { DistributiveOmit } from "../../generated/vsrepo";
1082
+ import type { SaveObject, PacthObject } from "../../generated/vsrepo";
1087
1083
 
1088
- // Omit distributivo — preserva unions ao omitir propriedades
1089
- type SemEmail = DistributiveOmit<Usuario | Perfil, "email">;
1084
+ const usuarioVSRepo = setupVSRepo<Usuario, "usuario">()({
1085
+ tableName: "usuario",
1086
+ pkName: "id",
1087
+ relations: {
1088
+ perfil: { pk: "id", mode: "oto", restriction: "set" },
1089
+ postagens: { pk: "id", mode: "otm", restriction: "add" },
1090
+ },
1091
+ });
1092
+
1093
+ // Tipo do objeto aceito pelo .save()
1094
+ type UsuarioSavePayload = SaveObject<typeof usuarioVSRepo>;
1095
+
1096
+ // Tipo do objeto aceito pelo .patch()
1097
+ type UsuarioPatchPayload = PacthObject<typeof usuarioVSRepo>;
1090
1098
  ```
1091
1099
 
1100
+ > Útil para tipar DTOs, funções auxiliares ou serviços que chamam `save`/`patch` e precisam do tipo correto do payload sem referenciar diretamente os tipos internos do Prisma.
1101
+
1092
1102
  ---
1093
1103
 
1094
1104
  ## API Reference
@@ -55,12 +55,18 @@ type ValidMethodPatterns =
55
55
  | `findWhere${string}` | `findListWhere${string}`
56
56
  | 'aggregate' | 'groupBy';
57
57
 
58
- type StringModifiers =
59
- | 'NotStartsWith' | 'StartsWith' | 'NotEndsWith' | 'EndsWith'
60
- | 'NotContains' | 'Contains' | 'NotIn' | 'In' | 'Not';
61
-
62
58
  type StripModifier<S extends string> =
63
- S extends `${infer Base}${StringModifiers}Insensitive` ? Base :
59
+ // Expansão explícita para resolver o problema do 'Insensitive'
60
+ S extends `${infer Base}NotStartsWithInsensitive` ? Base :
61
+ S extends `${infer Base}StartsWithInsensitive` ? Base :
62
+ S extends `${infer Base}NotEndsWithInsensitive` ? Base :
63
+ S extends `${infer Base}EndsWithInsensitive` ? Base :
64
+ S extends `${infer Base}NotContainsInsensitive` ? Base :
65
+ S extends `${infer Base}ContainsInsensitive` ? Base :
66
+ S extends `${infer Base}NotInInsensitive` ? Base :
67
+ S extends `${infer Base}InInsensitive` ? Base :
68
+ S extends `${infer Base}NotInsensitive` ? Base :
69
+ // Modificadores normais
64
70
  S extends `${infer Base}NotStartsWith` ? Base :
65
71
  S extends `${infer Base}StartsWith` ? Base :
66
72
  S extends `${infer Base}NotEndsWith` ? Base :
@@ -94,7 +100,7 @@ type GetFieldType<T, S extends string, I> = ExtractFieldName<S> extends infer Fi
94
100
  ? T[FieldName][]
95
101
  : NonNullable<T[FieldName]> extends object | any[]
96
102
  ? I extends { whereInput: infer W }
97
- ? FieldName extends keyof NonNullable<W> ? NonNullable<W>[FieldName] : T[FieldName]
103
+ ? FieldName extends keyof NonNullable<W> ? Exclude<NonNullable<W>[FieldName], undefined> : T[FieldName]
98
104
  : T[FieldName]
99
105
  : T[FieldName]
100
106
  : ParseRelation<S> extends [infer Rel extends keyof T, any, infer Rest extends string]
@@ -125,8 +131,6 @@ type MapToContractTypes<T, Arr extends string[], I> =
125
131
  : never
126
132
  : [];
127
133
 
128
- type HasMultipleANDs<S extends string> = S extends `${string}AND${string}AND${string}` ? true : false;
129
-
130
134
  type SplitAllTokens<S extends string> =
131
135
  S extends `${infer L}AND${infer R}` ? [...SplitAllTokens<L>, ...SplitAllTokens<R>] :
132
136
  S extends `${infer L}And${infer R}` ? [...SplitAllTokens<L>, ...SplitAllTokens<R>] :
@@ -153,18 +157,26 @@ type ResolveReturnType<M extends string, TSelected> =
153
157
  M extends 'findUniqueOrThrow' | 'findFirstOrThrow' | 'create' | 'updateBy' | 'upsertBy' | 'deleteBy' ? TSelected :
154
158
  M extends 'count' | 'countWhere' ? number : never;
155
159
 
160
+ type GetUpdateInput<I> = I extends { updateInput: infer U } ? U : unknown;
161
+ type GetCreateInput<I> = I extends { createInput: infer C } ? C : unknown;
162
+ type GetCreateManyInput<I> = I extends { createManyInput: infer CM } ? CM : unknown;
163
+ type GetUpdateManyInput<I> = I extends { updateManyInput: infer UM } ? UM : unknown;
164
+ type GetWhereInput<I> = I extends { whereInput: infer W } ? NonNullable<W> : unknown;
165
+ type GetCursorInput<I> = I extends { cursorInput: infer C } ? C : unknown;
166
+ type GetOrderByInput<I> = I extends { orderByInput: infer OB } ? OB : OrderOptions;
167
+
156
168
  type ExtraArgs<M extends string, R extends string, I> = [
157
- ...(M extends 'upsertBy' ? [update: I extends { updateInput: infer U } ? U : unknown, create: I extends { createInput: infer C } ? C : unknown]
158
- : M extends 'create' ? [data: I extends { createInput: infer C } ? C : unknown]
159
- : M extends 'updateBy' ? [data: I extends { updateInput: infer U } ? U : unknown]
160
- : M extends 'createMany' | 'createManyAndReturn' ? [data: I extends { createManyInput: infer CM } ? CM : unknown]
161
- : M extends 'updateManyBy' | 'updateManyAndReturnBy' ? [data: I extends { updateManyInput: infer UM } ? UM : unknown]
162
- : M extends 'findWhere' | 'findListWhere' | 'countWhere' ? [where: I extends { whereInput: infer W } ? NonNullable<W> : unknown]
169
+ ...(M extends 'upsertBy' ? [update: GetUpdateInput<I>, create: GetCreateInput<I>]
170
+ : M extends 'create' ? [data: GetCreateInput<I>]
171
+ : M extends 'updateBy' ? [data: GetUpdateInput<I>]
172
+ : M extends 'createMany' | 'createManyAndReturn' ? [data: GetCreateManyInput<I>]
173
+ : M extends 'updateManyBy' | 'updateManyAndReturnBy' ? [data: GetUpdateManyInput<I>]
174
+ : M extends 'findWhere' | 'findListWhere' | 'countWhere' ? [where: GetWhereInput<I>]
163
175
  : []),
164
- ...(R extends `${string}PaginatedAndOrdered` ? [pagination: PaginationOptions<I extends { cursorInput: infer C } ? C : unknown>, order: I extends { orderByInput: infer OB } ? OB : OrderOptions]
165
- : R extends `${string}OrderedAndPaginated` ? [order: I extends { orderByInput: infer OB } ? OB : OrderOptions, pagination: PaginationOptions<I extends { cursorInput: infer C } ? C : unknown>]
166
- : R extends `${string}Paginated` ? [pagination: PaginationOptions<I extends { cursorInput: infer C } ? C : unknown>]
167
- : R extends `${string}Ordered` ? [order: I extends { orderByInput: infer OB } ? OB : OrderOptions]
176
+ ...(R extends `${string}PaginatedAndOrdered` ? [pagination: PaginationOptions<GetCursorInput<I>>, order: GetOrderByInput<I>]
177
+ : R extends `${string}OrderedAndPaginated` ? [order: GetOrderByInput<I>, pagination: PaginationOptions<GetCursorInput<I>>]
178
+ : R extends `${string}Paginated` ? [pagination: PaginationOptions<GetCursorInput<I>>]
179
+ : R extends `${string}Ordered` ? [order: GetOrderByInput<I>]
168
180
  : [])
169
181
  ];
170
182
 
@@ -173,13 +185,17 @@ type PrismaDelegate<M extends Prisma.ModelName> = Uncapitalize<M> extends keyof
173
185
  type FullModelType<M extends Prisma.ModelName> =
174
186
  Prisma.Result<PrismaDelegate<M>, {}, 'findMany'> extends Array<infer U> ? U : never;
175
187
 
188
+ type PrecomputedSelects<M extends Prisma.ModelName, SelectModels> = {
189
+ [S in keyof SelectModels]: Prisma.Result<PrismaDelegate<M>, { select: SelectModels[S] }, 'findMany'> extends Array<infer U> ? U : never
190
+ };
191
+
176
192
  type SelectedModel<M extends Prisma.ModelName, S, SelectModels> =
177
193
  [S] extends [false]
178
194
  ? FullModelType<M>
179
195
  : [S] extends [never]
180
196
  ? FullModelType<M>
181
197
  : [S] extends [keyof SelectModels]
182
- ? (Prisma.Result<PrismaDelegate<M>, { select: SelectModels[S] }, 'findMany'> extends Array<infer U> ? U : never)
198
+ ? PrecomputedSelects<M, SelectModels>[S]
183
199
  : FullModelType<M>;
184
200
 
185
201
  type CleanFields<R extends string> =
@@ -208,9 +224,18 @@ export type MethodOptions<S> = {
208
224
  };
209
225
 
210
226
  /**
211
- * Versão de `MethodOptions` derivada de um mapa de select models.
227
+ * Versão de `MethodOptions` derivada diretamente de uma instância configurada de `VSRepository`.
228
+ *
229
+ * @template TRepo Instância de `VSRepository` configurada (use `typeof meuVSRepo`).
230
+ *
231
+ * @example
232
+ * const usuarioVSRepo = setupVSRepo<Usuario, "usuario">()(config);
233
+ * type Opts = MethodOptionsModel<typeof usuarioVSRepo>;
212
234
  */
213
- export type MethodOptionsModel<T> = MethodOptions<keyof T | false>;
235
+ export type MethodOptionsModel<TRepo> =
236
+ TRepo extends VSRepository<any, any, infer Config>
237
+ ? MethodOptions<keyof ExtractSelectModels<Config> | false>
238
+ : never;
214
239
 
215
240
  type MethodFn<MethodName extends string, T, M extends Prisma.ModelName, R extends string, SelectModels, DefaultSelect extends keyof SelectModels | false, I> =
216
241
  <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>>>;
@@ -494,7 +519,7 @@ type InjectedRemove<
494
519
  /**
495
520
  * Versão distributiva de `Omit`, preservando unions ao remover propriedades.
496
521
  */
497
- export type DistributiveOmit<T, K extends keyof any> = T extends any ? Omit<T, K> : never;
522
+ type DistributiveOmit<T, K extends keyof any> = T extends any ? Omit<T, K> : never;
498
523
  type ExtractUnionProp<T, K extends PropertyKey> = T extends any ? (K extends keyof T ? T[K] : never) : never;
499
524
 
500
525
  type ExtractNestedCreateInput<M extends Prisma.ModelName, K extends PropertyKey> =
@@ -514,7 +539,7 @@ type RelationPayload<TField, TRelationConfig, M extends Prisma.ModelName, K exte
514
539
  * Substitui os campos relacionais pelo formato compatível com os modos
515
540
  * configurados em `relations`.
516
541
  */
517
- export type UpsertWithRelations<T, M extends Prisma.ModelName, TRelations> =
542
+ type UpsertWithRelations<T, M extends Prisma.ModelName, TRelations> =
518
543
  DistributiveOmit<ModelUpsertInput<M>, keyof TRelations> & {
519
544
  [K in Extract<keyof TRelations, keyof T>]?: RelationPayload<T[K], TRelations[K], M, K>;
520
545
  };
@@ -542,11 +567,27 @@ type RelationUpdatePayload<TField, TRelationConfig, M extends Prisma.ModelName,
542
567
  * Substitui os campos relacionais pelo formato compatível com os modos
543
568
  * configurados em `relations` para fluxos de Update.
544
569
  */
545
- export type UpdateWithRelations<T, M extends Prisma.ModelName, TRelations> =
570
+ type UpdateWithRelations<T, M extends Prisma.ModelName, TRelations> =
546
571
  DistributiveOmit<PrismaModelInputs<M>['updateInput'], keyof TRelations> & {
547
572
  [K in Extract<keyof TRelations, keyof T>]?: RelationUpdatePayload<T[K], TRelations[K], M, K>;
548
573
  };
549
574
 
575
+ /**
576
+ * Extrai o tipo de payload do método `save` a partir de uma instância de VSRepository configurada.
577
+ */
578
+ export type SaveObject<TRepo> =
579
+ TRepo extends VSRepository<infer T, infer M, infer Config>
580
+ ? UpsertWithRelations<T, M, Config extends { relations: infer R } ? (R extends object ? R : {}) : {}>
581
+ : never;
582
+
583
+ /**
584
+ * Extrai o tipo de payload do método `patch` a partir de uma instância de VSRepository configurada.
585
+ */
586
+ export type PacthObject<TRepo> =
587
+ TRepo extends VSRepository<infer T, infer M, infer Config>
588
+ ? UpdateWithRelations<T, M, Config extends { relations: infer R } ? (R extends object ? R : {}) : {}>
589
+ : never;
590
+
550
591
  type InjectedSave<
551
592
  T, M extends Prisma.ModelName, Config, C extends BuildConfig<any> | undefined,
552
593
  TSelects = ExtractSelectModels<Config>,
@@ -560,7 +601,7 @@ type InjectedSave<
560
601
  * @returns O registro salvo com tipos refinados conforme a entrada.
561
602
  */
562
603
  save<
563
- O extends UpsertWithRelations<T, M, TRelations>,
604
+ O,
564
605
  S extends keyof TSelects | false = ResolveMethodDefaultSelect<Config, C, 'save', TSelects>
565
606
  >(
566
607
  obj: O & UpsertWithRelations<T, M, TRelations>,
@@ -583,7 +624,7 @@ type InjectedPatch<
583
624
  * @returns O registro atualizado refinado conforme a entrada.
584
625
  */
585
626
  patch<
586
- O extends UpdateWithRelations<T, M, TRelations>,
627
+ O,
587
628
  S extends keyof TSelects | false = ResolveMethodDefaultSelect<Config, C, 'patch', TSelects>
588
629
  >(
589
630
  pk: T[TPk extends keyof T ? TPk : never],
@@ -757,7 +798,7 @@ export type RepoConfig<T, M extends Prisma.ModelName, SM extends Record<string,
757
798
  *
758
799
  * Combina métodos dinâmicos, métodos base e extensões personalizadas.
759
800
  */
760
- export type BuiltRepository<T extends object, M extends Prisma.ModelName, Config extends RepoConfig<T, M, any>, C extends BuildConfig<any> | undefined> = {
801
+ type BuiltRepository<T extends object, M extends Prisma.ModelName, Config extends RepoConfig<T, M, any>, C extends BuildConfig<any> | undefined> = {
761
802
  /**
762
803
  * Estende o repository com métodos personalizados sem perder a tipagem.
763
804
  */
@@ -815,9 +856,7 @@ export type ValidateRepoConfig<T extends object, M extends Prisma.ModelName, Con
815
856
  /** Mapa dos métodos dinâmicos e suas regras de validação. */
816
857
  methods?: {
817
858
  [K in keyof (Config extends { methods: infer Meth } ? Meth : {})]: K extends string
818
- ? HasMultipleANDs<K> extends true
819
- ? MethodConfig<M, Config extends { selectModels: infer SM } ? SM : any> & { proxyTo: ValidMethodPatterns }
820
- : MethodConfig<M, Config extends { selectModels: infer SM } ? SM : any> & (K extends ValidMethodPatterns ? {} : { proxyTo: ValidMethodPatterns })
859
+ ? MethodConfig<M, Config extends { selectModels: infer SM } ? SM : any> & (K extends ValidMethodPatterns ? {} : { proxyTo: ValidMethodPatterns })
821
860
  : never;
822
861
  };
823
862
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vsrepo",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "description": "Uma biblioteca de repository pattern para Prisma",
5
5
  "homepage": "https://github.com/jaobrabo123/VSRepository#readme",
6
6
  "repository": {
@@ -38,8 +38,7 @@
38
38
  "node": ">=18"
39
39
  },
40
40
  "scripts": {
41
- "vsrepo": "node ./scripts/configure-prisma-import.mjs",
42
- "configure:prisma-import": "node ./scripts/configure-prisma-import.mjs"
41
+ "vsrepo": "node ./scripts/configure-prisma-import.mjs"
43
42
  },
44
43
  "keywords": [
45
44
  "prisma",
@@ -47,7 +46,8 @@
47
46
  "orm",
48
47
  "typescript",
49
48
  "vsrepo",
50
- "vsrepository"
49
+ "vsrepository",
50
+ "jparepository"
51
51
  ],
52
52
  "author": "João Pedro Azevedo Freire Mecenas",
53
53
  "license": "MIT",