vsrepo 1.1.5 → 1.1.6

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
@@ -1,7 +1,7 @@
1
1
  # VSRepository
2
2
 
3
3
  ![npm](https://img.shields.io/npm/v/vsrepo?style=flat-square)
4
- ![license](https://img.shields.io/github/license/jaobrabo123/vsrepository?style=flat-square)
4
+ ![license](https://img.shields.io/github/license/jaobrabo123/vsrepository?style=flat-square&v=1)
5
5
  ![NPM Downloads](https://img.shields.io/npm/d18m/vsrepo.svg)
6
6
 
7
7
  Biblioteca de repository pattern para projetos que usam **Prisma**, com suporte completo a **TypeScript** e **type inference** automático.
@@ -35,7 +35,7 @@ O VSRepository permite criar repositories fortemente tipados com:
35
35
  - [Configuração de métodos](#configuração-de-métodos)
36
36
  - [Relações no save](#relações-no-save)
37
37
  - [Transações](#transações)
38
- - [Extendendo um repository](#extendendo-um-repository)
38
+ - [Estendendo um repository](#estendendo-um-repository)
39
39
  - [Tratamento de erros](#tratamento-de-erros)
40
40
  - [Tipos utilitários](#tipos-utilitários)
41
41
  - [API Reference](#api-reference)
@@ -334,6 +334,7 @@ Ao chamar `.build(prisma)` os métodos base abaixo são automaticamente disponib
334
334
  | `get(pk)` | Busca um registro pela primary key |
335
335
  | `getOrThrow(pk)` | Busca um registro pela primary key e lança erro se não encontrar |
336
336
  | `save(obj)` | Cria ou atualiza (se o objeto passado tiver a `pk` faz `upsert`, se não faz `create`) |
337
+ | `patch(pk, obj)` | Atualiza parcialmente um registro pela primary key (equivalente ao `update` com payload parcial) |
337
338
  | `remove(pk)` | Remove um registro pela primary key |
338
339
  | `removeList(pks)` | Remove vários registros pela lista de primary keys — retorna `{ count }` |
339
340
  | `getAll()` | Retorna todos os registros (aceita `pagination` e `order` no `options`) |
@@ -357,9 +358,13 @@ usuarioVSRepo.build(prisma, {
357
358
  remove: {
358
359
  active: true,
359
360
  defaultSelect: "minimal",
361
+ ignoreRequiredWhere: false, // Aplica o requiredWhere no remove (padrão = false)
360
362
  },
361
363
  save: {
362
- ignoreRequiredWhere: true, // Não aplica requiredWhere no save
364
+ ignoreRequiredWhere: true, // Não aplica requiredWhere no save
365
+ },
366
+ patch: {
367
+ defaultSelect: "minimal",
363
368
  },
364
369
  has: {
365
370
  active: false, // Desativa o 'has' (padrão = true)
@@ -721,7 +726,7 @@ methods: {
721
726
 
722
727
  ## Relações no save
723
728
 
724
- Configure relações para que o `save` as gerencie automaticamente. Para que as relações apareçam no autocomplete, o tipo genérico deve incluir as relações usando `GetPayload`:
729
+ Configure relações para que o `save` as gerencie automaticamente. Essas mesmas relações também são usadas no `patch`. Para que as relações apareçam no autocomplete, o tipo genérico deve incluir as relações usando `GetPayload`:
725
730
 
726
731
  ```ts
727
732
  import type { Prisma } from "../../generated/prisma/client";
@@ -743,12 +748,39 @@ const usuarioRepository = setupVSRepo<Usuario, "usuario">()({
743
748
  postagens: {
744
749
  pk: "id",
745
750
  mode: "otm",
746
- restriction: "set",
751
+ restriction: "add",
747
752
  },
748
753
  },
749
754
  }).build(prisma);
750
755
  ```
751
756
 
757
+ Exemplos de uso com relações:
758
+
759
+ ```ts
760
+ await usuarioRepository.save({
761
+ nome: "Maria",
762
+ email: "maria@email.com",
763
+ senha: "password",
764
+ perfil: {
765
+ id: 1,
766
+ bio: "Bio da Maria",
767
+ },
768
+ postagens: [
769
+ { titulo: "Primeiro post", conteudo: "Olá!" },
770
+ ],
771
+ });
772
+
773
+ await usuarioRepository.patch(1, {
774
+ perfil: {
775
+ id: 1,
776
+ bio: "Bio atualizada",
777
+ },
778
+ postagens: [
779
+ { id: 10, titulo: "Post revisado", conteudo: "Conteúdo ajustado" },
780
+ ],
781
+ });
782
+ ```
783
+
752
784
  > **Dica:** Se o tipo genérico não incluir `include: { relação: true }`, o VSRepository ainda funcionará, mas o autocomplete não sugerirá as relações no `save`. O tipo recomendado é sempre `GetPayload<{ include: { /* suas relações */ } }>` para melhor experiência de desenvolvimento.
753
785
 
754
786
  **Modos de relação:**
@@ -774,23 +806,24 @@ const usuarioRepository = setupVSRepo<Usuario, "usuario">()({
774
806
  Todos os métodos aceitam `options.db` para participar de uma transação:
775
807
 
776
808
  ```ts
777
- await prisma.$transaction(async (tx) => {
809
+ await usuarioRepository.prisma.$transaction(async (tx) => {
778
810
  const usuario = await usuarioRepository.save(
779
811
  { nome: "Maria", email: "maria@email.com", senha: "password" },
780
812
  { db: tx }
781
813
  );
782
814
 
783
- await usuarioRepository.updateById(
784
- usuario.id,
785
- { ativo: true },
815
+ await usuarioLogsRepository.save(
816
+ { acao: "Cadastro de usuário", data: { usuarioCadastrado: usuario.id } },
786
817
  { db: tx }
787
818
  );
788
819
  });
789
820
  ```
790
821
 
822
+ Observe que é possível diferentes repositories participarem da mesma transação.
823
+
791
824
  ---
792
825
 
793
- ## Extendendo um repository
826
+ ## Estendendo um repository
794
827
 
795
828
  ```ts
796
829
  const usuarioRepository = setupVSRepo<Usuario, "usuario">()({
@@ -1011,6 +1044,7 @@ vsRepo.build(prisma, {
1011
1044
  getOrThrow?:{ active?: boolean; defaultSelect?: string; ignoreRequiredWhere?: boolean };
1012
1045
  remove?: { active?: boolean; defaultSelect?: string; ignoreRequiredWhere?: boolean };
1013
1046
  save?: { active?: boolean; defaultSelect?: string; ignoreRequiredWhere?: boolean };
1047
+ patch?: { active?: boolean; defaultSelect?: string; ignoreRequiredWhere?: boolean };
1014
1048
  getAll?: { active?: boolean; defaultSelect?: string; ignoreRequiredWhere?: boolean };
1015
1049
 
1016
1050
  // Métodos que NÃO aceitam `defaultSelect`
@@ -372,6 +372,8 @@ export type BuildConfig<TSelectKeys extends PropertyKey = string> = {
372
372
  remove?: BaseMethodConfig<TSelectKeys>;
373
373
  /** Configuração do método `save`. */
374
374
  save?: BaseMethodConfig<TSelectKeys>;
375
+ /** Configuração do método `patch`. */
376
+ patch?: BaseMethodConfig<TSelectKeys>;
375
377
  /** Configuração do método `removeList` (exclusão em lote). Não aceita select. */
376
378
  removeList?: Omit<BaseMethodConfig<TSelectKeys>, 'defaultSelect'>;
377
379
  /** Configuração do método `getAll` (listagem total). */
@@ -383,7 +385,7 @@ export type BuildConfig<TSelectKeys extends PropertyKey = string> = {
383
385
  };
384
386
  };
385
387
 
386
- type ResolveMethodDefaultSelect<Config, C, Method extends 'get' | 'getOrThrow' | 'remove' | 'save' | 'getAll', TSelects = ExtractSelectModels<Config>> =
388
+ type ResolveMethodDefaultSelect<Config, C, Method extends 'get' | 'getOrThrow' | 'remove' | 'save' | 'getAll' | 'patch', TSelects = ExtractSelectModels<Config>> =
387
389
  C extends { baseMethods?: { [_ in Method]?: { defaultSelect?: infer D } } }
388
390
  ? D extends keyof TSelects
389
391
  ? D
@@ -483,6 +485,21 @@ type InjectedSave<
483
485
  ): Promise<RefineSaveResult<ResolveCurrentReturn<M, TSelects, S, TDefault>, O>>;
484
486
  };
485
487
 
488
+ type InjectedPatch<
489
+ T, M extends Prisma.ModelName, Config, C extends BuildConfig<any> | undefined,
490
+ TSelects = ExtractSelectModels<Config>,
491
+ TDefault = ExtractDefaultSelect<Config>,
492
+ TPk = ExtractPkName<T, Config>,
493
+ I = PrismaModelInputs<M>
494
+ > = C extends { baseMethods: { patch: { active: false } } } ? {} : {
495
+ /** Atualiza parcialmente um registro existente através da sua chave primária (PK). */
496
+ patch<S extends keyof TSelects | false = ResolveMethodDefaultSelect<Config, C, 'patch', TSelects>>(
497
+ pk: T[TPk extends keyof T ? TPk : never],
498
+ obj: I extends { updateInput: infer U } ? U : Record<string, any>,
499
+ options?: MethodOptions<S>
500
+ ): Promise<ResolveCurrentReturn<M, TSelects, S, TDefault>>;
501
+ };
502
+
486
503
  type InjectedRemoveList<
487
504
  T, M extends Prisma.ModelName, Config, C extends BuildConfig<any> | undefined,
488
505
  TPk = ExtractPkName<T, Config>
@@ -532,6 +549,7 @@ type InjectedBaseMethods<T, M extends Prisma.ModelName, Config, C extends BuildC
532
549
  InjectedGetOrThrow<T, M, Config, C> &
533
550
  InjectedRemove<T, M, Config, C> &
534
551
  InjectedSave<T, M, Config, C> &
552
+ InjectedPatch<T, M, Config, C> &
535
553
  InjectedRemoveList<T, M, Config, C> &
536
554
  InjectedGetAll<T, M, Config, C> &
537
555
  InjectedTotal<T, M, Config, C> &
@@ -1055,138 +1055,287 @@ export class VSRepository {
1055
1055
  console.log(`[VSRepository] (runtime) Fatal error when trying to save on ${buildInstance.tableName}:\n`, JSON.stringify({ prismaArgs }, null, 2));
1056
1056
  throw err;
1057
1057
  }
1058
- }
1059
- if(config.baseMethods?.removeList?.active !== false) {
1060
- buildInstance.removeList = async (pks, options = {}) => {
1061
- let db = options?.db ?? prisma;
1062
- const prismaArgs = {};
1063
-
1064
- const where = { [buildInstance.pkName]: { in: pks } };
1065
- if(buildInstance.requiredWhere && !config.baseMethods?.removeList?.ignoreRequiredWhere) {
1066
- Object.assign(where, buildInstance.requiredWhere);
1067
- }
1068
- prismaArgs.where = where;
1058
+ }
1059
+ }
1060
+ if(config.baseMethods?.removeList?.active !== false) {
1061
+ buildInstance.removeList = async (pks, options = {}) => {
1062
+ let db = options?.db ?? prisma;
1063
+ const prismaArgs = {};
1064
+
1065
+ const where = { [buildInstance.pkName]: { in: pks } };
1066
+ if(buildInstance.requiredWhere && !config.baseMethods?.removeList?.ignoreRequiredWhere) {
1067
+ Object.assign(where, buildInstance.requiredWhere);
1068
+ }
1069
+ prismaArgs.where = where;
1069
1070
 
1070
- let start;
1071
- if(showWorking){
1072
- console.log(`[VSRepository] (runtime) Executing removeList on ${buildInstance.tableName}.`);
1073
- console.log(`[VSRepository] (runtime) Built arguments to removeList on ${buildInstance.tableName}:\n`, JSON.stringify(prismaArgs, null, 2));
1074
- start = performance.now();
1075
- }
1076
- try {
1077
- const result = await db[buildInstance.tableName].deleteMany(prismaArgs);
1078
- if(showWorking) {
1079
- const end = performance.now();
1080
- console.log(`[VSRepository] (runtime) Executed removeList on ${buildInstance.tableName} (took: ${(end - start).toFixed(2)}ms).`);
1081
- }
1082
- return result;
1083
- } catch (err) {
1084
- console.log(`[VSRepository] (runtime) Fatal error when trying to removeList on ${buildInstance.tableName}:\n`, JSON.stringify({ prismaArgs }, null, 2));
1085
- throw err;
1071
+ let start;
1072
+ if(showWorking){
1073
+ console.log(`[VSRepository] (runtime) Executing removeList on ${buildInstance.tableName}.`);
1074
+ console.log(`[VSRepository] (runtime) Built arguments to removeList on ${buildInstance.tableName}:\n`, JSON.stringify(prismaArgs, null, 2));
1075
+ start = performance.now();
1076
+ }
1077
+ try {
1078
+ const result = await db[buildInstance.tableName].deleteMany(prismaArgs);
1079
+ if(showWorking) {
1080
+ const end = performance.now();
1081
+ console.log(`[VSRepository] (runtime) Executed removeList on ${buildInstance.tableName} (took: ${(end - start).toFixed(2)}ms).`);
1086
1082
  }
1083
+ return result;
1084
+ } catch (err) {
1085
+ console.log(`[VSRepository] (runtime) Fatal error when trying to removeList on ${buildInstance.tableName}:\n`, JSON.stringify({ prismaArgs }, null, 2));
1086
+ throw err;
1087
1087
  }
1088
1088
  }
1089
- if(config.baseMethods?.getAll?.active !== false) {
1090
- buildInstance.getAll = async (options = {}) => {
1091
- let db = options?.db ?? prisma;
1092
- const prismaArgs = {};
1089
+ }
1090
+ if(config.baseMethods?.getAll?.active !== false) {
1091
+ buildInstance.getAll = async (options = {}) => {
1092
+ let db = options?.db ?? prisma;
1093
+ const prismaArgs = {};
1093
1094
 
1094
- if(buildInstance.requiredWhere && !config.baseMethods?.getAll?.ignoreRequiredWhere) {
1095
- prismaArgs.where = { ...buildInstance.requiredWhere };
1096
- }
1095
+ if(buildInstance.requiredWhere && !config.baseMethods?.getAll?.ignoreRequiredWhere) {
1096
+ prismaArgs.where = { ...buildInstance.requiredWhere };
1097
+ }
1097
1098
 
1098
- let selectModelKey = options?.selectModel ?? config.baseMethods?.getAll?.defaultSelect ?? buildInstance.defaultSelectModel;
1099
- if(selectModelKey){
1100
- prismaArgs.select = buildInstance.selectModels[selectModelKey];
1101
- }
1099
+ let selectModelKey = options?.selectModel ?? config.baseMethods?.getAll?.defaultSelect ?? buildInstance.defaultSelectModel;
1100
+ if(selectModelKey){
1101
+ prismaArgs.select = buildInstance.selectModels[selectModelKey];
1102
+ }
1102
1103
 
1103
- if(options.pagination) {
1104
- prismaArgs.skip = options.pagination.skip;
1105
- prismaArgs.take = options.pagination.take;
1106
- prismaArgs.cursor = options.pagination.cursor;
1107
- }
1108
- if(options.order) {
1109
- prismaArgs.orderBy = options.order;
1110
- }
1104
+ if(options.pagination) {
1105
+ prismaArgs.skip = options.pagination.skip;
1106
+ prismaArgs.take = options.pagination.take;
1107
+ prismaArgs.cursor = options.pagination.cursor;
1108
+ }
1109
+ if(options.order) {
1110
+ prismaArgs.orderBy = options.order;
1111
+ }
1111
1112
 
1112
- let start;
1113
- if(showWorking){
1114
- console.log(`[VSRepository] (runtime) Executing getAll on ${buildInstance.tableName}.`);
1115
- console.log(`[VSRepository] (runtime) Built arguments to getAll on ${buildInstance.tableName}:\n`, JSON.stringify(prismaArgs, null, 2));
1116
- start = performance.now();
1117
- }
1118
- try {
1119
- const result = await db[buildInstance.tableName].findMany(prismaArgs);
1120
- if(showWorking) {
1121
- const end = performance.now();
1122
- console.log(`[VSRepository] (runtime) Executed getAll on ${buildInstance.tableName} (took: ${(end - start).toFixed(2)}ms).`);
1123
- }
1124
- return result;
1125
- } catch (err) {
1126
- console.log(`[VSRepository] (runtime) Fatal error when trying to getAll on ${buildInstance.tableName}:\n`, JSON.stringify({ prismaArgs }, null, 2));
1127
- throw err;
1113
+ let start;
1114
+ if(showWorking){
1115
+ console.log(`[VSRepository] (runtime) Executing getAll on ${buildInstance.tableName}.`);
1116
+ console.log(`[VSRepository] (runtime) Built arguments to getAll on ${buildInstance.tableName}:\n`, JSON.stringify(prismaArgs, null, 2));
1117
+ start = performance.now();
1118
+ }
1119
+ try {
1120
+ const result = await db[buildInstance.tableName].findMany(prismaArgs);
1121
+ if(showWorking) {
1122
+ const end = performance.now();
1123
+ console.log(`[VSRepository] (runtime) Executed getAll on ${buildInstance.tableName} (took: ${(end - start).toFixed(2)}ms).`);
1128
1124
  }
1125
+ return result;
1126
+ } catch (err) {
1127
+ console.log(`[VSRepository] (runtime) Fatal error when trying to getAll on ${buildInstance.tableName}:\n`, JSON.stringify({ prismaArgs }, null, 2));
1128
+ throw err;
1129
1129
  }
1130
1130
  }
1131
- if(config.baseMethods?.total?.active !== false) {
1132
- buildInstance.total = async (options = {}) => {
1133
- let db = options?.db ?? prisma;
1134
- const prismaArgs = {};
1131
+ }
1132
+ if(config.baseMethods?.total?.active !== false) {
1133
+ buildInstance.total = async (options = {}) => {
1134
+ let db = options?.db ?? prisma;
1135
+ const prismaArgs = {};
1135
1136
 
1136
- if(buildInstance.requiredWhere && !config.baseMethods?.total?.ignoreRequiredWhere) {
1137
- prismaArgs.where = { ...buildInstance.requiredWhere };
1138
- }
1137
+ if(buildInstance.requiredWhere && !config.baseMethods?.total?.ignoreRequiredWhere) {
1138
+ prismaArgs.where = { ...buildInstance.requiredWhere };
1139
+ }
1139
1140
 
1140
- let start;
1141
- if(showWorking){
1142
- console.log(`[VSRepository] (runtime) Executing total on ${buildInstance.tableName}.`);
1143
- console.log(`[VSRepository] (runtime) Built arguments to total on ${buildInstance.tableName}:\n`, JSON.stringify(prismaArgs, null, 2));
1144
- start = performance.now();
1141
+ let start;
1142
+ if(showWorking){
1143
+ console.log(`[VSRepository] (runtime) Executing total on ${buildInstance.tableName}.`);
1144
+ console.log(`[VSRepository] (runtime) Built arguments to total on ${buildInstance.tableName}:\n`, JSON.stringify(prismaArgs, null, 2));
1145
+ start = performance.now();
1146
+ }
1147
+ try {
1148
+ const result = await db[buildInstance.tableName].count(prismaArgs);
1149
+ if(showWorking) {
1150
+ const end = performance.now();
1151
+ console.log(`[VSRepository] (runtime) Executed total on ${buildInstance.tableName} (took: ${(end - start).toFixed(2)}ms).`);
1145
1152
  }
1146
- try {
1147
- const result = await db[buildInstance.tableName].count(prismaArgs);
1148
- if(showWorking) {
1149
- const end = performance.now();
1150
- console.log(`[VSRepository] (runtime) Executed total on ${buildInstance.tableName} (took: ${(end - start).toFixed(2)}ms).`);
1151
- }
1152
- return result;
1153
- } catch (err) {
1154
- console.log(`[VSRepository] (runtime) Fatal error when trying to total on ${buildInstance.tableName}:\n`, JSON.stringify({ prismaArgs }, null, 2));
1155
- throw err;
1153
+ return result;
1154
+ } catch (err) {
1155
+ console.log(`[VSRepository] (runtime) Fatal error when trying to total on ${buildInstance.tableName}:\n`, JSON.stringify({ prismaArgs }, null, 2));
1156
+ throw err;
1157
+ }
1158
+ }
1159
+ }
1160
+ if(config.baseMethods?.has?.active !== false) {
1161
+ buildInstance.has = async (pk, options = {}) => {
1162
+ let db = options?.db ?? prisma;
1163
+ const prismaArgs = {};
1164
+
1165
+ const where = { [buildInstance.pkName]: pk };
1166
+ if(buildInstance.requiredWhere && !config.baseMethods?.has?.ignoreRequiredWhere) {
1167
+ Object.assign(where, buildInstance.requiredWhere);
1168
+ }
1169
+ prismaArgs.where = where;
1170
+ prismaArgs.select = { [buildInstance.pkName]: true };
1171
+
1172
+ let start;
1173
+ if(showWorking){
1174
+ console.log(`[VSRepository] (runtime) Executing has on ${buildInstance.tableName}.`);
1175
+ console.log(`[VSRepository] (runtime) Built arguments to has on ${buildInstance.tableName}:\n`, JSON.stringify(prismaArgs, null, 2));
1176
+ start = performance.now();
1177
+ }
1178
+ try {
1179
+ const result = await db[buildInstance.tableName].findUnique(prismaArgs);
1180
+ if(showWorking) {
1181
+ const end = performance.now();
1182
+ console.log(`[VSRepository] (runtime) Executed has on ${buildInstance.tableName} (took: ${(end - start).toFixed(2)}ms).`);
1156
1183
  }
1184
+ return !!result;
1185
+ } catch (err) {
1186
+ console.log(`[VSRepository] (runtime) Fatal error when trying to has on ${buildInstance.tableName}:\n`, JSON.stringify({ prismaArgs }, null, 2));
1187
+ throw err;
1157
1188
  }
1158
1189
  }
1159
- if(config.baseMethods?.has?.active !== false) {
1160
- buildInstance.has = async (pk, options = {}) => {
1161
- let db = options?.db ?? prisma;
1162
- const prismaArgs = {};
1163
-
1190
+ }
1191
+ if(config.baseMethods?.patch?.active !== false) {
1192
+ buildInstance.patch = async (pk, obj, options = {}) => {
1193
+ let db = options?.db ?? prisma;
1194
+ const prismaArgs = {};
1195
+
1196
+ let selectModelKey = options?.selectModel ?? config.baseMethods?.patch?.defaultSelect ?? buildInstance.defaultSelectModel;
1197
+ if(selectModelKey){
1198
+ prismaArgs.select = buildInstance.selectModels[selectModelKey];
1199
+ }
1200
+
1201
+ let start;
1202
+ if(showWorking){
1203
+ console.log(`[VSRepository] (runtime) Executing patch on ${buildInstance.tableName}.`);
1204
+ start = performance.now();
1205
+ }
1206
+
1207
+ try {
1208
+ let result;
1209
+ prismaArgs.data = {};
1210
+
1211
+ const keys = Object.keys(obj);
1212
+ for (let i = 0; i < keys.length; i++) {
1213
+ const key = keys[i];
1214
+ const field = obj[key];
1215
+
1216
+ if(field === undefined) continue;
1217
+
1218
+ if(relationsKeys.includes(key)){
1219
+ const relation = buildInstance.relations[key];
1220
+ const relationMode = relation.mode;
1221
+ const relationRestriction = relation.restriction;
1222
+ const relationPk = relation.pk;
1223
+
1224
+ if(relationMode === 'oto' || relationMode === 'mto') {
1225
+ if(field === null) {
1226
+ if(relationMode === 'oto' && relationRestriction === 'set') {
1227
+ prismaArgs.data[key] = { delete: true };
1228
+ } else if(relationMode === 'mto' && relation.nullAble) {
1229
+ prismaArgs.data[key] = { disconnect: true };
1230
+ }
1231
+ } else if (field !== undefined) {
1232
+ const relationFieldPk = field[relationPk];
1233
+ if(relationFieldPk){
1234
+ const connectOrCreate = {
1235
+ where: { [relationPk]: relationFieldPk },
1236
+ create: field
1237
+ };
1238
+
1239
+ if(relationRestriction === 'add') {
1240
+ prismaArgs.data[key] = { connectOrCreate };
1241
+ } else {
1242
+ const update = {...field};
1243
+ delete update[relationPk];
1244
+
1245
+ prismaArgs.data[key] = {
1246
+ upsert: {
1247
+ where: { [relationPk]: relationFieldPk },
1248
+ create: field,
1249
+ update: update
1250
+ }
1251
+ };
1252
+ }
1253
+ } else {
1254
+ prismaArgs.data[key] = { create: field };
1255
+ }
1256
+ }
1257
+ } else if(Array.isArray(field)) {
1258
+ const dataWithPk = field.filter(data=>data[relationPk]!==undefined);
1259
+ const dataWithoutPk = field.filter(data=>data[relationPk]===undefined);
1260
+
1261
+ const connectOrCreate = dataWithPk.map(data=>({
1262
+ where: { [relationPk]: data[relationPk] },
1263
+ create: data
1264
+ }));
1265
+
1266
+ if(relationRestriction === 'add') {
1267
+ if(relationMode === 'mtm') {
1268
+ prismaArgs.data[key] = {
1269
+ create: dataWithoutPk,
1270
+ connectOrCreate
1271
+ }
1272
+ } else {
1273
+ prismaArgs.data[key] = {
1274
+ create: dataWithoutPk,
1275
+ upsert: dataWithPk.map(data=>{
1276
+ const update = { ...data };
1277
+ delete update[relationPk];
1278
+ return {
1279
+ where: { [relationPk]: data[relationPk] },
1280
+ create: data, update
1281
+ }
1282
+ })
1283
+ }
1284
+ }
1285
+ } else {
1286
+ if(relationMode === 'mtm') {
1287
+ prismaArgs.data[key] = {
1288
+ set: [],
1289
+ create: dataWithoutPk,
1290
+ connectOrCreate
1291
+ }
1292
+ } else {
1293
+ prismaArgs.data[key] = {
1294
+ deleteMany: { [relationPk]: { notIn: dataWithPk.map(data=>data[relationPk]) } },
1295
+ create: dataWithoutPk,
1296
+ upsert: dataWithPk.map(data=>{
1297
+ const update = { ...data };
1298
+ delete update[relationPk];
1299
+ return {
1300
+ where: { [relationPk]: data[relationPk] },
1301
+ create: data, update
1302
+ }
1303
+ })
1304
+ }
1305
+ }
1306
+ }
1307
+ }
1308
+ } else {
1309
+ if (key !== buildInstance.pkName) {
1310
+ prismaArgs.data[key] = field;
1311
+ }
1312
+ }
1313
+ }
1314
+
1164
1315
  const where = { [buildInstance.pkName]: pk };
1165
- if(buildInstance.requiredWhere && !config.baseMethods?.has?.ignoreRequiredWhere) {
1316
+ if(buildInstance.requiredWhere && !config.baseMethods?.patch?.ignoreRequiredWhere) {
1166
1317
  Object.assign(where, buildInstance.requiredWhere);
1167
1318
  }
1168
1319
  prismaArgs.where = where;
1169
- prismaArgs.select = { [buildInstance.pkName]: true };
1170
1320
 
1171
- let start;
1172
- if(showWorking){
1173
- console.log(`[VSRepository] (runtime) Executing has on ${buildInstance.tableName}.`);
1174
- console.log(`[VSRepository] (runtime) Built arguments to has on ${buildInstance.tableName}:\n`, JSON.stringify(prismaArgs, null, 2));
1175
- start = performance.now();
1321
+ if(showWorking) {
1322
+ console.log(`[VSRepository] (runtime) Built arguments to patch on ${buildInstance.tableName}:\n`, JSON.stringify(prismaArgs, null, 2));
1176
1323
  }
1177
- try {
1178
- const result = await db[buildInstance.tableName].findUnique(prismaArgs);
1179
- if(showWorking) {
1180
- const end = performance.now();
1181
- console.log(`[VSRepository] (runtime) Executed has on ${buildInstance.tableName} (took: ${(end - start).toFixed(2)}ms).`);
1182
- }
1183
- return !!result;
1184
- } catch (err) {
1185
- console.log(`[VSRepository] (runtime) Fatal error when trying to has on ${buildInstance.tableName}:\n`, JSON.stringify({ prismaArgs }, null, 2));
1186
- throw err;
1324
+
1325
+ result = await db[buildInstance.tableName].update(prismaArgs);
1326
+
1327
+ if(showWorking) {
1328
+ const end = performance.now();
1329
+ const duration = (end - start).toFixed(2);
1330
+ console.log(`[VSRepository] (runtime) Executed patch on ${buildInstance.tableName} (took: ${duration}ms).`);
1187
1331
  }
1332
+
1333
+ return result;
1334
+ } catch (err) {
1335
+ console.log(`[VSRepository] (runtime) Fatal error when trying to patch on ${buildInstance.tableName}:\n`, JSON.stringify({ prismaArgs }, null, 2));
1336
+ throw err;
1188
1337
  }
1189
- }
1338
+ }
1190
1339
  }
1191
1340
 
1192
1341
  buildInstance.prisma = prisma;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vsrepo",
3
- "version": "1.1.5",
3
+ "version": "1.1.6",
4
4
  "description": "Uma biblioteca de repository pattern para Prisma",
5
5
  "homepage": "https://github.com/jaobrabo123/VSRepository#readme",
6
6
  "repository": {