vsrepo 1.3.3 → 1.3.5

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.
@@ -228,20 +228,22 @@ type PrecomputedIncludes<M extends PrismaModelName, IncludeModels> = {
228
228
  [I in keyof IncludeModels]: Prisma.Result<PrismaDelegate<M>, { include: IncludeModels[I] }, 'findMany'> extends Array<infer U> ? U : never
229
229
  };
230
230
 
231
- type SelectedModel<M extends PrismaModelName, S, SelectModels, IM = never, IncludeModels = {}, RI = never> =
232
- [RI] extends [never]
233
- ? [IM] extends [never]
234
- ? [S] extends [false]
235
- ? FullModelType<M>
236
- : [S] extends [never]
237
- ? FullModelType<M>
238
- : [S] extends [keyof SelectModels]
239
- ? PrecomputedSelects<M, SelectModels>[S]
240
- : FullModelType<M>
241
- : IM extends keyof IncludeModels
242
- ? PrecomputedIncludes<M, IncludeModels>[IM]
243
- : FullModelType<M>
244
- : Prisma.Result<PrismaDelegate<M>, { include: RI }, 'findMany'> extends Array<infer U> ? U : never;
231
+ type SelectedModel<M extends PrismaModelName, S, SelectModels, IM = never, IncludeModels = {}, RI = never, RS = never> =
232
+ [RS] extends [never]
233
+ ? [RI] extends [never]
234
+ ? [IM] extends [never]
235
+ ? [S] extends [false]
236
+ ? FullModelType<M>
237
+ : [S] extends [never]
238
+ ? FullModelType<M>
239
+ : [S] extends [keyof SelectModels]
240
+ ? PrecomputedSelects<M, SelectModels>[S]
241
+ : FullModelType<M>
242
+ : IM extends keyof IncludeModels
243
+ ? PrecomputedIncludes<M, IncludeModels>[IM]
244
+ : FullModelType<M>
245
+ : Prisma.Result<PrismaDelegate<M>, { include: RI }, 'findMany'> extends Array<infer U> ? U : never
246
+ : Prisma.Result<PrismaDelegate<M>, { select: RS }, 'findMany'> extends Array<infer U> ? U : never;
245
247
 
246
248
  /**
247
249
  * Strips the `Distinct{Fields}` suffix used by read methods (e.g. `findManyDistinctIdadeAndCargo`).
@@ -265,7 +267,7 @@ type CleanFields<R extends string> =
265
267
  * @template S Available keys in `selectModels`.
266
268
  * @template IM Available keys in `includeModels`.
267
269
  */
268
- export type MethodOptions<S, IM extends PropertyKey = never, M extends PrismaModelName = never, RI = never> = {
270
+ export type MethodOptions<S, IM extends PropertyKey = never, M extends PrismaModelName = never, RI = never, RS = never> = {
269
271
  /** Prisma client or transaction to use for the operation. */
270
272
  db?: ClientOrTransaction;
271
273
  /**
@@ -287,15 +289,25 @@ export type MethodOptions<S, IM extends PropertyKey = never, M extends PrismaMod
287
289
  includeModel?: never;
288
290
  /** Raw Prisma `include`. Cannot be used together with `selectModel` or `includeModel`. */
289
291
  include?: never;
292
+ /** Raw Prisma `select`. Cannot be used together with `selectModel`, `includeModel` or `include`. */
293
+ select?: never;
290
294
  }
291
295
  | {
292
296
  selectModel?: never;
293
297
  includeModel?: never;
294
298
  include: RI;
299
+ select?: never;
300
+ }
301
+ | {
302
+ selectModel?: never;
303
+ includeModel?: never;
304
+ include?: never;
305
+ select: RS;
295
306
  }
296
- : | { selectModel?: S | false; includeModel?: never; include?: never }
297
- | { selectModel?: never; includeModel: IM; include?: never }
298
- | { selectModel?: never; includeModel?: never; include: RI }
307
+ : | { selectModel?: S | false; includeModel?: never; include?: never; select?: never }
308
+ | { selectModel?: never; includeModel: IM; include?: never; select?: never }
309
+ | { selectModel?: never; includeModel?: never; include: RI; select?: never }
310
+ | { selectModel?: never; includeModel?: never; include?: never; select: RS }
299
311
  );
300
312
 
301
313
  /**
@@ -318,14 +330,15 @@ type MethodOptionsWithInclude<
318
330
  TIncludes,
319
331
  M extends PrismaModelName,
320
332
  RI = never,
321
- Excluded extends keyof MethodOptions<S, keyof TIncludes, M, RI> = never
322
- > = DistributiveOmit<MethodOptions<S, keyof TIncludes, M, RI>, Excluded>
333
+ RS = never,
334
+ Excluded extends keyof MethodOptions<S, keyof TIncludes, M, RI, RS> = never
335
+ > = DistributiveOmit<MethodOptions<S, keyof TIncludes, M, RI, RS>, Excluded>
323
336
  & ({ includeModel: IM } | { includeModel?: never });
324
337
 
325
338
  type MethodFn<MethodName extends string, T, M extends PrismaModelName, R extends string, SelectModels, DefaultSelect extends keyof SelectModels | false, I, IncludeModels> =
326
- <S extends keyof SelectModels | false = DefaultSelect, IM extends keyof IncludeModels = never, RI extends IncludeModel<M> = never>(
327
- ...args: [...ExtractFields<T, CleanFields<R>, I>, ...ExtraArgs<MethodName, R, I>, options?: MethodOptionsWithInclude<S, IM, IncludeModels, M, RI>]
328
- ) => Promise<ResolveReturnType<MethodName, SelectedModel<M, S, SelectModels, IM, IncludeModels, RI>>>;
339
+ <S extends keyof SelectModels | false = DefaultSelect, IM extends keyof IncludeModels = never, RI extends IncludeModel<M> = never, RS extends SelectModel<M> = never>(
340
+ ...args: [...ExtractFields<T, CleanFields<R>, I>, ...ExtraArgs<MethodName, R, I>, options?: MethodOptionsWithInclude<S, IM, IncludeModels, M, RI, RS>]
341
+ ) => Promise<ResolveReturnType<MethodName, SelectedModel<M, S, SelectModels, IM, IncludeModels, RI, RS>>>;
329
342
 
330
343
  type GetMappedMethod<K extends string, MethodConf> =
331
344
  K extends `findBy${string}` ? (MethodConf extends { fbMode: 'one' } ? 'findByOne' : 'findByList') :
@@ -380,9 +393,9 @@ type MethodFactory<T, M extends PrismaModelName, K extends string, SelectModels,
380
393
  K extends `findWhere${string}`
381
394
  ? {
382
395
  /** @deprecated Use findOneWhere instead. */
383
- <S extends keyof SelectModels | false = DefaultSelect, IM extends keyof IncludeModels = never, RI extends IncludeModel<M> = never>(
384
- ...args: [...ExtractFields<T, CleanFields<ExtractPatternBase<K>>, I>, ...ExtraArgs<GetMappedMethod<K, MethodConf>, ExtractPatternBase<K>, I>, options?: MethodOptionsWithInclude<S, IM, IncludeModels, M, RI>]
385
- ): Promise<ResolveReturnType<GetMappedMethod<K, MethodConf>, SelectedModel<M, S, SelectModels, IM, IncludeModels, RI>>>;
396
+ <S extends keyof SelectModels | false = DefaultSelect, IM extends keyof IncludeModels = never, RI extends IncludeModel<M> = never, RS extends SelectModel<M> = never>(
397
+ ...args: [...ExtractFields<T, CleanFields<ExtractPatternBase<K>>, I>, ...ExtraArgs<GetMappedMethod<K, MethodConf>, ExtractPatternBase<K>, I>, options?: MethodOptionsWithInclude<S, IM, IncludeModels, M, RI, RS>]
398
+ ): Promise<ResolveReturnType<GetMappedMethod<K, MethodConf>, SelectedModel<M, S, SelectModels, IM, IncludeModels, RI, RS>>>;
386
399
  }
387
400
  : MethodFn<GetMappedMethod<K, MethodConf>, T, M, ExtractPatternBase<K>, SelectModels, DefaultSelect, I, IncludeModels>;
388
401
 
@@ -408,18 +421,47 @@ type GroupByMethod<M extends PrismaModelName> = <A extends Prisma.TypeMap['model
408
421
  options?: { db?: ClientOrTransaction }
409
422
  ) => Promise<Prisma.Result<PrismaDelegate<M>, A, 'groupBy'>>;
410
423
 
424
+ /**
425
+ * Function type generated for a dynamic method configured with `query` (non-modifying).
426
+ *
427
+ * The result of a raw SQL `SELECT` isn't statically known, so the method itself
428
+ * resolves to `any` by default, but exposes a generic parameter so the caller can
429
+ * infer/assert the shape of the result: `repo.myRawQuery<User[]>({ args: [...] })`.
430
+ *
431
+ * @template TReturn Return type asserted at the call site. Defaults to `any`.
432
+ */
433
+ type QueryMethodFn = <TReturn = any>(
434
+ arg: { args: any[]; db?: ClientOrTransaction },
435
+ ) => Promise<TReturn>;
436
+
437
+ /**
438
+ * Function type generated for a dynamic method configured with `query` and
439
+ * `modifying: true`.
440
+ *
441
+ * Modifying raw queries run through `$executeRawUnsafe` and always resolve to the
442
+ * number of affected rows, so — unlike `QueryMethodFn` — no generic return type is
443
+ * exposed here.
444
+ */
445
+ type QueryMethodModifyingFn = (
446
+ arg: { args: any[]; db?: ClientOrTransaction },
447
+ ) => Promise<number>;
448
+
411
449
  type DynamicMethods<T, M extends PrismaModelName, Config, I> = Config extends { methods: infer Methods }
412
450
  ? {
413
451
  [K in keyof Methods as Methods[K] extends { map: true } ? K : never]: K extends string
414
- ? (Methods[K] extends { proxyTo: infer P extends string } ? P : K) extends infer ResolvedKey
415
- ? ResolvedKey extends 'aggregate'
416
- ? AggregateMethod<M>
417
- : ResolvedKey extends 'groupBy'
418
- ? GroupByMethod<M>
419
- : ResolvedKey extends string
420
- ? MethodFactory<T, M, ResolvedKey, ExtractSelectModels<Config>, ResolveSelectModel<Methods[K], Config, ExtractSelectModels<Config>>, I, Methods[K], ExtractIncludeModels<Config>>
452
+ ? Methods[K] extends { query: { modifying: true } }
453
+ ? QueryMethodModifyingFn
454
+ : Methods[K] extends { query: infer Q }
455
+ ? QueryMethodFn
456
+ : (Methods[K] extends { proxyTo: infer P extends string } ? P : K) extends infer ResolvedKey
457
+ ? ResolvedKey extends 'aggregate'
458
+ ? AggregateMethod<M>
459
+ : ResolvedKey extends 'groupBy'
460
+ ? GroupByMethod<M>
461
+ : ResolvedKey extends string
462
+ ? MethodFactory<T, M, ResolvedKey, ExtractSelectModels<Config>, ResolveSelectModel<Methods[K], Config, ExtractSelectModels<Config>>, I, Methods[K], ExtractIncludeModels<Config>>
463
+ : never
421
464
  : never
422
- : never
423
465
  : never;
424
466
  }
425
467
  : {};
@@ -524,6 +566,53 @@ export type MethodConfig<M extends PrismaModelName, SelectModels = any> = {
524
566
  readonly injectOrdenation?: OrdenationModel<M>;
525
567
  /** Injects a fixed pagination automatically into the query. */
526
568
  readonly injectPagination?: PaginationModel<M>;
569
+ /**
570
+ * Turns this method into a **raw SQL query method**, bypassing name-based parsing
571
+ * entirely. The method executes the given SQL directly through Prisma, with
572
+ * parameters injected positionally via the `args` array passed at the call site
573
+ * (`$1`, `$2`, ... placeholders), so no other option in `MethodConfig` applies
574
+ * (`selectModels`, `requiredWhere`, `pushWhere`, etc. are all ignored).
575
+ *
576
+ * - `modifying: false` (default) runs through `$queryRawUnsafe` and the method
577
+ * resolves to `TReturn` (`any` by default), inferable/assertable via a generic
578
+ * at the call site.
579
+ * - `modifying: true` runs through `$executeRawUnsafe` and the method **always**
580
+ * resolves to `number` (the count of affected rows).
581
+ *
582
+ * @example
583
+ * ```typescript
584
+ * methods: {
585
+ * findActiveUsersRaw: {
586
+ * map: true,
587
+ * query: { value: 'SELECT * FROM "user" WHERE active = $1' },
588
+ * },
589
+ * deactivateUsersOlderThanRaw: {
590
+ * map: true,
591
+ * query: { value: 'UPDATE "user" SET active = false WHERE "createdAt" < $1', modifying: true },
592
+ * },
593
+ * }
594
+ *
595
+ * // Uso:
596
+ * const users = await repo.findActiveUsersRaw<User[]>({ args: [true] });
597
+ * const affected = await repo.deactivateUsersOlderThanRaw({ args: [cutoffDate] });
598
+ * ```
599
+ */
600
+ readonly query?: {
601
+ /**
602
+ * Raw SQL statement to execute. Use positional placeholders (`$1`, `$2`, ...)
603
+ * for the values passed in `args`, never string-interpolate the values
604
+ * directly, or you'll re-introduce the SQL injection risk this API exists to avoid.
605
+ */
606
+ readonly value: string;
607
+ /**
608
+ * When `true`, executes via `$executeRawUnsafe` and the method always resolves
609
+ * to `number` (rows affected). When `false`/omitted, executes via
610
+ * `$queryRawUnsafe` and the method resolves to `TReturn` (`any` by default).
611
+ *
612
+ * @default false
613
+ */
614
+ readonly modifying?: boolean;
615
+ };
527
616
  };
528
617
 
529
618
  type BaseMethodConfig<TSelectKeys extends PropertyKey = string> = {
@@ -598,18 +687,20 @@ type ResolveMethodDefaultSelect<Config, C, Method extends keyof NonNullable<Buil
598
687
  ? ExtractDefaultSelect<Config>
599
688
  : false;
600
689
 
601
- type ResolveCurrentReturn<M extends PrismaModelName, Models, S, D, IM = never, Includes = {}, RI = never> =
602
- [RI] extends [never]
603
- ? [IM] extends [never]
604
- ? [S] extends [false]
605
- ? FullModelType<M>
606
- : [S] extends [never]
607
- ? ([D] extends [never] ? FullModelType<M> : SelectedModel<M, D, Models>)
608
- : SelectedModel<M, S, Models>
609
- : IM extends keyof Includes
610
- ? PrecomputedIncludes<M, Includes>[IM]
611
- : FullModelType<M>
612
- : Prisma.Result<PrismaDelegate<M>, { include: RI }, 'findMany'> extends Array<infer U> ? U : never;
690
+ type ResolveCurrentReturn<M extends PrismaModelName, Models, S, D, IM = never, Includes = {}, RI = never, RS = never> =
691
+ [RS] extends [never]
692
+ ? [RI] extends [never]
693
+ ? [IM] extends [never]
694
+ ? [S] extends [false]
695
+ ? FullModelType<M>
696
+ : [S] extends [never]
697
+ ? ([D] extends [never] ? FullModelType<M> : SelectedModel<M, D, Models>)
698
+ : SelectedModel<M, S, Models>
699
+ : IM extends keyof Includes
700
+ ? PrecomputedIncludes<M, Includes>[IM]
701
+ : FullModelType<M>
702
+ : Prisma.Result<PrismaDelegate<M>, { include: RI }, 'findMany'> extends Array<infer U> ? U : never
703
+ : Prisma.Result<PrismaDelegate<M>, { select: RS }, 'findMany'> extends Array<infer U> ? U : never;
613
704
 
614
705
  // ─── helpers reused within the mapped type ───────────────────────────────────
615
706
  // ─── relation payload types ──────────────────────────────────────────────────
@@ -715,7 +806,7 @@ export type PatchObject<TInput, TRepo> =
715
806
 
716
807
 
717
808
  type _Pk<T, Config> = WidenField<T[ExtractPkName<T, Config> extends keyof T ? ExtractPkName<T, Config> : never]>;
718
- type _Ret<M extends PrismaModelName, TSelects, S, TDefault, IM = never, TIncludes = {}, RI = never> = ResolveCurrentReturn<M, TSelects, S, TDefault, IM, TIncludes, RI>;
809
+ type _Ret<M extends PrismaModelName, TSelects, S, TDefault, IM = never, TIncludes = {}, RI = never, RS = never> = ResolveCurrentReturn<M, TSelects, S, TDefault, IM, TIncludes, RI, RS>;
719
810
  type _DS<Config, C, Method extends keyof NonNullable<BuildConfig['baseMethods']>, TSelects = ExtractSelectModels<Config>> =
720
811
  ResolveMethodDefaultSelect<Config, C, Method, TSelects>;
721
812
  type _Sel<Config> = ExtractSelectModels<Config>;
@@ -742,56 +833,56 @@ type AllBaseMethods<
742
833
  TIncludes = _Inc<Config>
743
834
  > = {
744
835
  /** Fetches a record by its primary key (PK). */
745
- get: <S extends keyof TSelects | false = _DS<Config, C, 'get', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never>(
746
- pk: _Pk<T, Config>, options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI>
747
- ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI> | null>;
836
+ get: <S extends keyof TSelects | false = _DS<Config, C, 'get', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never, RS extends SelectModel<M> = never>(
837
+ pk: _Pk<T, Config>, options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI, RS>
838
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI, RS> | null>;
748
839
 
749
840
  /** Fetches a record by PK and throws `VSRepoRuntimeError` if not found. */
750
- getOrThrow: <S extends keyof TSelects | false = _DS<Config, C, 'getOrThrow', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never>(
751
- pk: _Pk<T, Config>, options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI>
752
- ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI>>;
841
+ getOrThrow: <S extends keyof TSelects | false = _DS<Config, C, 'getOrThrow', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never, RS extends SelectModel<M> = never>(
842
+ pk: _Pk<T, Config>, options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI, RS>
843
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI, RS>>;
753
844
 
754
845
  /** Fetches multiple records by a list of primary keys (PKs). */
755
- getList: <S extends keyof TSelects | false = _DS<Config, C, 'getList', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never>(
756
- pks: _Pk<T, Config>[], options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI>
757
- ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI>[]>;
846
+ getList: <S extends keyof TSelects | false = _DS<Config, C, 'getList', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never, RS extends SelectModel<M> = never>(
847
+ pks: _Pk<T, Config>[], options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI, RS>
848
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI, RS>[]>;
758
849
 
759
850
  /** Deletes a record identified by its primary key (PK). */
760
- remove: <S extends keyof TSelects | false = _DS<Config, C, 'remove', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never>(
761
- pk: _Pk<T, Config>, options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI>
762
- ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI>>;
851
+ remove: <S extends keyof TSelects | false = _DS<Config, C, 'remove', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never, RS extends SelectModel<M> = never>(
852
+ pk: _Pk<T, Config>, options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI, RS>
853
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI, RS>>;
763
854
 
764
855
  /** Inserts or updates (upsert) a record. */
765
- save: <S extends keyof TSelects | false = _DS<Config, C, 'save', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never>(
766
- obj: UpsertWithRelations<T, M, TRelations>, options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI>
767
- ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI>>;
856
+ save: <S extends keyof TSelects | false = _DS<Config, C, 'save', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never, RS extends SelectModel<M> = never>(
857
+ obj: UpsertWithRelations<T, M, TRelations>, options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI, RS>
858
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI, RS>>;
768
859
 
769
860
  /** Saves an array of objects in a single automatic transaction. */
770
- saveList: <S extends keyof TSelects | false = _DS<Config, C, 'saveList', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never>(
771
- objs: UpsertWithRelations<T, M, TRelations>[], options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI, 'db'> & { db?: DbTransaction }
772
- ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI>[]>;
861
+ saveList: <S extends keyof TSelects | false = _DS<Config, C, 'saveList', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never, RS extends SelectModel<M> = never>(
862
+ objs: UpsertWithRelations<T, M, TRelations>[], options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI, RS, 'db'> & { db?: DbTransaction }
863
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI, RS>[]>;
773
864
 
774
865
  /** Partially updates (patch) an existing record by its primary key (PK). */
775
- patch: <S extends keyof TSelects | false = _DS<Config, C, 'patch', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never>(
776
- pk: _Pk<T, Config>, obj: PatchWithRelations<T, M, TRelations>, options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI>
777
- ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI>>;
866
+ patch: <S extends keyof TSelects | false = _DS<Config, C, 'patch', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never, RS extends SelectModel<M> = never>(
867
+ pk: _Pk<T, Config>, obj: PatchWithRelations<T, M, TRelations>, options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI, RS>
868
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI, RS>>;
778
869
 
779
870
  /** Partially updates multiple records via `[pk, obj]` tuples in an automatic transaction. */
780
- patchList: <S extends keyof TSelects | false = _DS<Config, C, 'patchList', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never>(
781
- tuples: [pk: _Pk<T, Config>, obj: PatchWithRelations<T, M, TRelations>][], options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI, 'db'> & { db?: DbTransaction }
782
- ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI>[]>;
871
+ patchList: <S extends keyof TSelects | false = _DS<Config, C, 'patchList', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never, RS extends SelectModel<M> = never>(
872
+ tuples: [pk: _Pk<T, Config>, obj: PatchWithRelations<T, M, TRelations>][], options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI, RS, 'db'> & { db?: DbTransaction }
873
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI, RS>[]>;
783
874
 
784
875
  /** Fetches a record by PK and deep-merges it with the provided object **in memory**. */
785
- merge: <S extends keyof TSelects | false = _DS<Config, C, 'merge', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never>(
786
- pk: _Pk<T, Config>, obj: UpdateWithRelations<T, M, TRelations>, options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI>
787
- ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI> | null>;
876
+ merge: <S extends keyof TSelects | false = _DS<Config, C, 'merge', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never, RS extends SelectModel<M> = never>(
877
+ pk: _Pk<T, Config>, obj: UpdateWithRelations<T, M, TRelations>, options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI, RS>
878
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI, RS> | null>;
788
879
 
789
880
  /** Deletes multiple records by their primary keys. */
790
881
  removeList: (pks: _Pk<T, Config>[], options?: { db?: ClientOrTransaction }) => Promise<{ count: number }>;
791
882
 
792
883
  /** Fetches all records (respects `requiredWhere` when set). */
793
- getAll: <S extends keyof TSelects | false = _DS<Config, C, 'getAll', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never>(
794
- options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI> & {
884
+ getAll: <S extends keyof TSelects | false = _DS<Config, C, 'getAll', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never, RS extends SelectModel<M> = never>(
885
+ options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI, RS> & {
795
886
  pagination?: PaginationOptions<I extends { cursorInput: infer Curs } ? Curs : unknown>;
796
887
  /**
797
888
  * Ordering to apply to the query.
@@ -800,7 +891,7 @@ type AllBaseMethods<
800
891
  */
801
892
  order?: I extends { orderByInput: infer OB } ? OB : OrderOptions;
802
893
  }
803
- ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI>[]>;
894
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI, RS>[]>;
804
895
 
805
896
  /** Returns the total number of records. */
806
897
  total: (options?: { db?: ClientOrTransaction; see?: SeeMode }) => Promise<number>;
@@ -809,17 +900,17 @@ type AllBaseMethods<
809
900
  has: (pk: _Pk<T, Config>, options?: { db?: ClientOrTransaction; see?: SeeMode }) => Promise<boolean>;
810
901
 
811
902
  /** Marks a record as deleted (soft-delete). */
812
- softRemove: <S extends keyof TSelects | false = _DS<Config, C, 'softRemove', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never>(
813
- pk: _Pk<T, Config>, options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI, 'see'>
814
- ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI>>;
903
+ softRemove: <S extends keyof TSelects | false = _DS<Config, C, 'softRemove', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never, RS extends SelectModel<M> = never>(
904
+ pk: _Pk<T, Config>, options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI, RS, 'see'>
905
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI, RS>>;
815
906
 
816
907
  /** Marks multiple records as deleted (soft-delete) in batch. */
817
908
  softRemoveList: (pks: _Pk<T, Config>[], options?: { db?: ClientOrTransaction }) => Promise<{ count: number }>;
818
909
 
819
910
  /** Restores a record previously marked as deleted (soft-delete). */
820
- restore: <S extends keyof TSelects | false = _DS<Config, C, 'restore', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never>(
821
- pk: _Pk<T, Config>, options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI, 'see'>
822
- ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI>>;
911
+ restore: <S extends keyof TSelects | false = _DS<Config, C, 'restore', TSelects>, IM extends keyof TIncludes = never, RI extends IncludeModel<M> = never, RS extends SelectModel<M> = never>(
912
+ pk: _Pk<T, Config>, options?: MethodOptionsWithInclude<S, IM, TIncludes, M, RI, RS, 'see'>
913
+ ) => Promise<_Ret<M, TSelects, S, TDefault, IM, TIncludes, RI, RS>>;
823
914
 
824
915
  /** Restores multiple records previously marked as deleted (soft-delete) in batch. */
825
916
  restoreList: (pks: _Pk<T, Config>[], options?: { db?: ClientOrTransaction }) => Promise<{ count: number }>;
@@ -1062,7 +1153,14 @@ export type ValidateRepoConfig<T extends object, M extends PrismaModelName, Conf
1062
1153
  */
1063
1154
  methods?: {
1064
1155
  [K in keyof (Config extends { methods: infer Meth } ? Meth : {})]: K extends string
1065
- ? MethodConfig<M, Config extends { selectModels: infer SM } ? SM : any> & (K extends ValidMethodPatterns ? {} : { proxyTo: ValidMethodPatterns })
1156
+ ? MethodConfig<M, Config extends { selectModels: infer SM } ? SM : any> &
1157
+ (K extends ValidMethodPatterns
1158
+ ? {}
1159
+ : (Config extends { methods: infer Meth }
1160
+ ? (K extends keyof Meth ? Meth[K] : never)
1161
+ : never) extends { query: any }
1162
+ ? {}
1163
+ : { proxyTo: ValidMethodPatterns })
1066
1164
  : never;
1067
1165
  };
1068
1166
  };
@@ -29,6 +29,7 @@ const pretty_wheres_resolve_1 = require("./internal/resolvers/pretty-wheres.reso
29
29
  const specific_where_resolve_1 = require("./internal/resolvers/specific-where.resolve");
30
30
  const dbAndPrismaArgs_resolve_1 = require("./internal/resolvers/dbAndPrismaArgs.resolve");
31
31
  const method_options_validate_1 = require("./internal/validation/method-options.validate");
32
+ const query_method_arg_validate_1 = require("./internal/validation/query-method-arg.validate");
32
33
  class VSRepository {
33
34
  vsrepocache;
34
35
  tableName;
@@ -82,6 +83,27 @@ class VSRepository {
82
83
  (0, logger_util_1.logger)("Keys to map:", "build", buildInstance.tableName, methodsToMap);
83
84
  for (let methodToMap of methodsToMap) {
84
85
  const originalKey = methodToMap;
86
+ if (methods[originalKey]?.query) {
87
+ const modifyingQueryMethod = methods[originalKey].query.modifying;
88
+ const valueQueryMethod = methods[originalKey].query.value;
89
+ buildInstance[originalKey] = async (arg) => {
90
+ const queryArgValidated = (0, query_method_arg_validate_1.validateQueryMethodArg)(arg, buildInstance);
91
+ const db = queryArgValidated.db ?? buildInstance.prisma;
92
+ const start = showWorking
93
+ ? (0, logger_util_1.performanceLoggerStart)(buildInstance.tableName, `Query method: ${originalKey} (Modifying: ${modifyingQueryMethod})`, queryArgValidated.args)
94
+ : undefined;
95
+ try {
96
+ const result = await db[modifyingQueryMethod ? "$executeRawUnsafe" : "$queryRawUnsafe"](valueQueryMethod, ...queryArgValidated.args);
97
+ if (showWorking)
98
+ (0, logger_util_1.performanceLoggerEnd)(buildInstance.tableName, `Query method: ${originalKey} (Modifying: ${modifyingQueryMethod})`, start);
99
+ return result;
100
+ }
101
+ catch (err) {
102
+ throw err;
103
+ }
104
+ };
105
+ continue;
106
+ }
85
107
  methodToMap = methods[originalKey]?.proxyTo ?? methodToMap;
86
108
  const dinamicMethodInfo = (0, dinamic_method_info_resolve_1.resolveDinamicMethodInfo)(buildInstance, methodToMap, originalKey);
87
109
  const dinamicMethodCustomization = (0, dinamic_method_customization_resolve_1.resolveDinamicMethodCustomization)(buildInstance, dinamicMethodInfo, originalKey);
@@ -8,7 +8,7 @@ function DynamicMethod(config) {
8
8
  const validatedConfig = config ? (0, dynamic_method_config_validate_1.validateDynamicMethodConfig)(config) : undefined;
9
9
  return (target, propertyKey) => {
10
10
  const methods = Reflect.getMetadata(dinamic_methods_key_constant_1.DINAMIC_METHODS_KEY, target) ?? [];
11
- methods.push(new dynamic_method_metadata_entity_1.DynamicMethodMetadata(propertyKey, validatedConfig?.map ?? true, validatedConfig?.proxyTo, validatedConfig?.whereType, validatedConfig?.pushWhere, validatedConfig?.fbMode, validatedConfig?.injectOrdenation, validatedConfig?.injectPagination));
11
+ methods.push(new dynamic_method_metadata_entity_1.DynamicMethodMetadata(propertyKey, true, validatedConfig?.proxyTo, validatedConfig?.whereType, validatedConfig?.pushWhere, validatedConfig?.fbMode, validatedConfig?.injectOrdenation, validatedConfig?.injectPagination));
12
12
  Reflect.defineMetadata(dinamic_methods_key_constant_1.DINAMIC_METHODS_KEY, methods, target);
13
13
  };
14
14
  }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QueryMethod = QueryMethod;
4
+ const dinamic_methods_key_constant_1 = require("../constants/dinamic-methods-key.constant");
5
+ const dynamic_method_metadata_entity_1 = require("../entities/dynamic-method-metadata.entity");
6
+ const vs_repo_error_1 = require("../errors/vs-repo.error");
7
+ const query_method_options_validate_1 = require("../validation/query-method-options.validate");
8
+ function QueryMethod(value, options) {
9
+ if (typeof value !== "string") {
10
+ throw new vs_repo_error_1.VSRepoDecoratorError(`[VSRepository] (unknown: decorator) 'value' must be a valid string`);
11
+ }
12
+ const validatedConfig = options
13
+ ? (0, query_method_options_validate_1.validateQueryMethodOptions)(options)
14
+ : { modifying: false };
15
+ return (target, propertyKey) => {
16
+ const methods = Reflect.getMetadata(dinamic_methods_key_constant_1.DINAMIC_METHODS_KEY, target) ?? [];
17
+ methods.push(new dynamic_method_metadata_entity_1.DynamicMethodMetadata(propertyKey, true, undefined, undefined, undefined, undefined, undefined, undefined, { value, ...validatedConfig }));
18
+ Reflect.defineMetadata(dinamic_methods_key_constant_1.DINAMIC_METHODS_KEY, methods, target);
19
+ };
20
+ }
@@ -10,7 +10,8 @@ class DynamicMethodMetadata {
10
10
  fbMode;
11
11
  injectOrdenation;
12
12
  injectPagination;
13
- constructor(propertyKey, map, proxyTo, whereType, pushWhere, fbMode, injectOrdenation, injectPagination) {
13
+ query;
14
+ constructor(propertyKey, map, proxyTo, whereType, pushWhere, fbMode, injectOrdenation, injectPagination, query) {
14
15
  this.propertyKey = propertyKey;
15
16
  this.map = map;
16
17
  this.proxyTo = proxyTo;
@@ -19,6 +20,7 @@ class DynamicMethodMetadata {
19
20
  this.fbMode = fbMode;
20
21
  this.injectOrdenation = injectOrdenation;
21
22
  this.injectPagination = injectPagination;
23
+ this.query = query;
22
24
  }
23
25
  }
24
26
  exports.DynamicMethodMetadata = DynamicMethodMetadata;
@@ -21,6 +21,9 @@ function resolveDbAndPrismaArgs(data) {
21
21
  if (specificSelect) {
22
22
  prismaArgs.select = specificSelect;
23
23
  }
24
+ else if (validatedOptions.select) {
25
+ prismaArgs.select = validatedOptions.select;
26
+ }
24
27
  else if (validatedOptions.includeModel) {
25
28
  prismaArgs.include = instance.includeModels?.[validatedOptions.includeModel];
26
29
  }
@@ -3,11 +3,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.methodSchema = exports.booleanSchema = exports.objectSchema = exports.stringSchema = void 0;
6
+ exports.methodSchema = exports.queryOptionsSchema = exports.booleanSchema = exports.objectSchema = exports.stringSchema = void 0;
7
7
  const zod_1 = __importDefault(require("zod"));
8
8
  exports.stringSchema = zod_1.default.string().trim().nonempty();
9
9
  exports.objectSchema = zod_1.default.looseObject({});
10
10
  exports.booleanSchema = zod_1.default.boolean();
11
+ exports.queryOptionsSchema = zod_1.default.strictObject({
12
+ value: exports.stringSchema,
13
+ modifying: exports.booleanSchema.default(false),
14
+ });
11
15
  exports.methodSchema = zod_1.default.strictObject({
12
16
  map: exports.booleanSchema,
13
17
  selectModel: exports.stringSchema.or(zod_1.default.literal(false)).optional(),
@@ -17,4 +21,5 @@ exports.methodSchema = zod_1.default.strictObject({
17
21
  fbMode: zod_1.default.enum(["one", "list"]).optional(),
18
22
  injectOrdenation: exports.objectSchema.or(zod_1.default.array(exports.objectSchema)).optional(),
19
23
  injectPagination: exports.objectSchema.optional(),
24
+ query: exports.queryOptionsSchema.optional(),
20
25
  });
@@ -18,12 +18,19 @@ function validateMethodOptions(options, instance) {
18
18
  includeModel: zod_1.default.enum(Object.keys(instance.includeModels ?? {})).optional(),
19
19
  see: zod_1.default.enum(["active", "removed", "all"]).default("active"),
20
20
  include: schemas_util_1.objectSchema.optional(),
21
+ select: schemas_util_1.objectSchema.optional(),
21
22
  })
22
23
  .refine(data => {
23
- return !(data.selectModel !== undefined && data.includeModel !== undefined);
24
+ const provided = [
25
+ data.select !== undefined,
26
+ data.selectModel !== undefined,
27
+ data.include !== undefined,
28
+ data.includeModel !== undefined,
29
+ ].filter(Boolean).length;
30
+ return provided <= 1;
24
31
  }, {
25
- message: "cannot be provided with 'selectModel'.",
26
- path: ["includeModel"],
32
+ message: "'select', 'selectModel', 'include' and 'includeModel' are mutually exclusive — only one can be provided.",
33
+ path: ["options"],
27
34
  });
28
35
  const optionsParsed = optionsSchema.safeParse(options ?? {});
29
36
  if (!optionsParsed.success) {
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.validateQueryMethodArg = validateQueryMethodArg;
7
+ const zod_1 = __importDefault(require("zod"));
8
+ const schemas_util_1 = require("../utils/schemas.util");
9
+ const vs_repo_error_1 = require("../errors/vs-repo.error");
10
+ function validateQueryMethodArg(arg, instance) {
11
+ const queryArgSchema = zod_1.default.strictObject({
12
+ args: zod_1.default.array(zod_1.default.any()),
13
+ db: schemas_util_1.objectSchema.optional(),
14
+ });
15
+ const argParsed = queryArgSchema.safeParse(arg);
16
+ if (!argParsed.success) {
17
+ const firstIssue = argParsed.error.issues[0];
18
+ const path = firstIssue?.path.length ? firstIssue.path.join(".") : "options";
19
+ throw new vs_repo_error_1.VSRepoRuntimeError(`[VSRepository] (${instance.tableName}: runtime) ${path}: ${firstIssue?.message}`, "67542");
20
+ }
21
+ return argParsed.data;
22
+ }
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.validateQueryMethodOptions = validateQueryMethodOptions;
7
+ const zod_1 = __importDefault(require("zod"));
8
+ const vs_repo_error_1 = require("../errors/vs-repo.error");
9
+ const is_object_validate_1 = require("./is-object.validate");
10
+ const schemas_util_1 = require("../utils/schemas.util");
11
+ function validateQueryMethodOptions(options) {
12
+ if (!(0, is_object_validate_1.isObject)(options)) {
13
+ throw new vs_repo_error_1.VSRepoDecoratorError(`[VSRepository] (unknown: decorator) 'options' must be a valid object`);
14
+ }
15
+ const optionsParsed = zod_1.default
16
+ .strictObject({ modifying: schemas_util_1.booleanSchema.default(false) })
17
+ .safeParse(options);
18
+ if (!optionsParsed.success) {
19
+ const firstIssue = optionsParsed.error.issues[0];
20
+ const path = firstIssue?.path.length ? firstIssue.path.join(".") : "options";
21
+ throw new vs_repo_error_1.VSRepoDecoratorError(`[VSRepository] (unknown: decorator) ${path}: ${firstIssue?.message}`);
22
+ }
23
+ return optionsParsed.data;
24
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });