vsrepo 1.3.3 → 1.3.4

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.
@@ -91,7 +91,9 @@ type DynamicTransformCreatePayload<U, T, M extends PrismaModelName, TRelations>
91
91
  export type DynamicSaveInput<TEntity, UName extends PrismaModelName, WRelations = undefined> =
92
92
  ModelUpsertInput<UName> extends infer U
93
93
  ? U extends any
94
- ? Simplify<DynamicTransformCreatePayload<U, TEntity, UName, ResolveRelations<WRelations>>>
94
+ ? Simplify<
95
+ DynamicTransformCreatePayload<U, TEntity, UName, ResolveRelations<WRelations>>
96
+ >
95
97
  : never
96
98
  : never;
97
99
 
@@ -108,12 +110,14 @@ export type DynamicPatchInput<
108
110
  UName extends PrismaModelName,
109
111
  WRelations = undefined,
110
112
  > = Simplify<
111
- DistributiveOmit<PrismaModelInputs<UName>["updateInput"], keyof ResolveRelations<WRelations>> & {
112
- [K in Extract<keyof ResolveRelations<WRelations>, keyof TEntity>]?: DynamicRelationCreatePayload<
113
- TEntity[K],
114
- UName,
115
- K
116
- >;
113
+ DistributiveOmit<
114
+ PrismaModelInputs<UName>["updateInput"],
115
+ keyof ResolveRelations<WRelations>
116
+ > & {
117
+ [K in Extract<
118
+ keyof ResolveRelations<WRelations>,
119
+ keyof TEntity
120
+ >]?: DynamicRelationCreatePayload<TEntity[K], UName, K>;
117
121
  }
118
122
  >;
119
123
 
@@ -129,12 +133,14 @@ export type DynamicMergeInput<
129
133
  UName extends PrismaModelName,
130
134
  WRelations = undefined,
131
135
  > = Simplify<
132
- DistributiveOmit<PrismaModelInputs<UName>["updateInput"], keyof ResolveRelations<WRelations>> & {
133
- [K in Extract<keyof ResolveRelations<WRelations>, keyof TEntity>]?: DynamicRelationUpdatePayload<
134
- TEntity[K],
135
- UName,
136
- K
137
- >;
136
+ DistributiveOmit<
137
+ PrismaModelInputs<UName>["updateInput"],
138
+ keyof ResolveRelations<WRelations>
139
+ > & {
140
+ [K in Extract<
141
+ keyof ResolveRelations<WRelations>,
142
+ keyof TEntity
143
+ >]?: DynamicRelationUpdatePayload<TEntity[K], UName, K>;
138
144
  }
139
145
  >;
140
146
 
@@ -395,7 +401,7 @@ export type DynamicMethodConfig<M extends PrismaModelName = PrismaModelName> = {
395
401
  * class UserRepository extends DynamicRepository<User, "User", string> {
396
402
  * `@DynamicMethod()`
397
403
  * declare findOneByEmail: (email: string) => Promise<User | null>;
398
- *
404
+ *
399
405
  * @DynamicMethod<"User">({ injectOrdenation: { createdAt: "desc" } })
400
406
  * declare findByAge: (email: number) => Promise<User[]>;
401
407
  * }
@@ -404,3 +410,67 @@ export type DynamicMethodConfig<M extends PrismaModelName = PrismaModelName> = {
404
410
  export declare function DynamicMethod<M extends PrismaModelName = PrismaModelName>(
405
411
  config?: DynamicMethodConfig<M>,
406
412
  ): PropertyDecorator;
413
+
414
+ /**
415
+ * Single argument accepted by a method declared with `@QueryMethod`.
416
+ *
417
+ * `args` are injected positionally into the raw SQL statement (`$1`, `$2`, ...),
418
+ * exactly like Prisma's `$queryRawUnsafe`/`$executeRawUnsafe` parameters — this is
419
+ * what allows safe parameter injection instead of string-concatenating values into
420
+ * the SQL text.
421
+ *
422
+ * @template T Tuple type of the positional SQL parameters, e.g. `[email: string]`.
423
+ *
424
+ * @example
425
+ * ```typescript
426
+ * declare findByEmail: (arg: QueryMethodArg<[email: string]>) => Promise<User[]>;
427
+ * ```
428
+ */
429
+ export type QueryMethodArg<T extends Array<any>> = {
430
+ /** Positional parameters injected into the SQL placeholders (`$1`, `$2`, ...). */
431
+ args: T;
432
+ /** Transaction client to run this query in, instead of the repository's default client. */
433
+ db?: ClientOrTransaction;
434
+ };
435
+
436
+ /**
437
+ * Options accepted by the `@QueryMethod` decorator.
438
+ */
439
+ export type QueryMethodOptions = {
440
+ /**
441
+ * When `true`, the SQL is executed with `$executeRawUnsafe` (INSERT/UPDATE/DELETE)
442
+ * and the decorated method must resolve to `number` (the count of affected rows).
443
+ * When `false`/omitted, the SQL is executed with `$queryRawUnsafe` and the method
444
+ * resolves to whatever return type you declare on the field.
445
+ *
446
+ * @default false
447
+ */
448
+ modifying?: boolean;
449
+ };
450
+
451
+ /**
452
+ * Property decorator used to declare a **raw SQL query method** on a `DynamicRepository`
453
+ * subclass, bypassing name-based method parsing entirely.
454
+ *
455
+ * Applied to a `declare` class field, it executes `value` directly through Prisma
456
+ * (`$queryRawUnsafe` or `$executeRawUnsafe`, depending on `options.modifying`), with
457
+ * parameters injected positionally via `QueryMethodArg["args"]`. Since the SQL result
458
+ * isn't statically known, the field's own declared function type is what determines
459
+ * the method's return type — for `modifying: true` it must always resolve to `number`.
460
+ *
461
+ * @param value Raw SQL statement to execute. Use `$1`, `$2`, ... placeholders for the
462
+ * values that will be passed via `args` — never interpolate values directly into `value`.
463
+ * @param options Optional configuration; set `modifying: true` for `INSERT`/`UPDATE`/`DELETE` statements.
464
+ *
465
+ * @example
466
+ * ```typescript
467
+ * class UserRepository extends DynamicRepository<User, "User", string> {
468
+ * @QueryMethod('SELECT * FROM "user" WHERE email = $1')
469
+ * declare findByEmailRaw: (arg: QueryMethodArg<[email: string]>) => Promise<User[]>;
470
+ *
471
+ * @QueryMethod('UPDATE "user" SET active = true WHERE id = $1', { modifying: true })
472
+ * declare activateUser: (arg: QueryMethodArg<[id: string]>) => Promise<number>;
473
+ * }
474
+ * ```
475
+ */
476
+ export declare function QueryMethod(value: string, options?: QueryMethodOptions): PropertyDecorator;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.DynamicRepository = exports.DynamicMethod = void 0;
3
+ exports.DynamicRepository = exports.QueryMethod = exports.DynamicMethod = void 0;
4
4
  const dynamic_methods_metadata_resolve_1 = require("./internal/resolvers/dynamic-methods-metadata.resolve");
5
5
  const build_config_validate_1 = require("./internal/validation/build-config.validate");
6
6
  const is_object_validate_1 = require("./internal/validation/is-object.validate");
@@ -8,6 +8,8 @@ const VSRepository_1 = require("./VSRepository");
8
8
  require("reflect-metadata");
9
9
  var dynamic_method_decorator_1 = require("./internal/decorators/dynamic-method.decorator");
10
10
  Object.defineProperty(exports, "DynamicMethod", { enumerable: true, get: function () { return dynamic_method_decorator_1.DynamicMethod; } });
11
+ var query_method_decorator_1 = require("./internal/decorators/query-method.decorator");
12
+ Object.defineProperty(exports, "QueryMethod", { enumerable: true, get: function () { return query_method_decorator_1.QueryMethod; } });
11
13
  class DynamicRepository extends VSRepository_1.VSRepository {
12
14
  constructor(prisma, config) {
13
15
  if (!(0, is_object_validate_1.isObject)(config)) {
@@ -22,33 +24,3 @@ class DynamicRepository extends VSRepository_1.VSRepository {
22
24
  }
23
25
  }
24
26
  exports.DynamicRepository = DynamicRepository;
25
- // export class UserRepository extends DynamicRepository {
26
- // constructor() {
27
- // super(
28
- // { $transaction: {} },
29
- // {
30
- // tableName: "user",
31
- // pkName: "id",
32
- // requiredWhere: { active: true },
33
- // softRemovekName: "createdAt",
34
- // build: { showWorking: true },
35
- // },
36
- // );
37
- // }
38
- // @DynamicMethod()
39
- // declare findByAge: (age: number) => Promise<object[]>;
40
- // @DynamicMethod()
41
- // declare findOneByEmail: (email: number) => Promise<object[]>;
42
- // @DynamicMethod()
43
- // declare findByNameStartsWithInsensitive: (email: number) => Promise<object[]>;
44
- // @DynamicMethod()
45
- // declare findByDescriptionIsNull: (email: number) => Promise<object[]>;
46
- // @DynamicMethod({ whereType: "overwrite" })
47
- // declare findByNameContainsInsensitiveOrderedAndPaginated: (email: number) => Promise<object[]>;
48
- // @DynamicMethod({
49
- // injectOrdenation: [{ address: { state: "asc" } }, { address: { city: "asc" } }],
50
- // })
51
- // declare findByAddressWithCountry: (email: number) => Promise<object[]>;
52
- // }
53
- // const userRepository = new UserRepository();
54
- // console.log(userRepository);
@@ -408,18 +408,47 @@ type GroupByMethod<M extends PrismaModelName> = <A extends Prisma.TypeMap['model
408
408
  options?: { db?: ClientOrTransaction }
409
409
  ) => Promise<Prisma.Result<PrismaDelegate<M>, A, 'groupBy'>>;
410
410
 
411
+ /**
412
+ * Function type generated for a dynamic method configured with `query` (non-modifying).
413
+ *
414
+ * The result of a raw SQL `SELECT` isn't statically known, so the method itself
415
+ * resolves to `any` by default, but exposes a generic parameter so the caller can
416
+ * infer/assert the shape of the result: `repo.myRawQuery<User[]>({ args: [...] })`.
417
+ *
418
+ * @template TReturn Return type asserted at the call site. Defaults to `any`.
419
+ */
420
+ type QueryMethodFn = <TReturn = any>(
421
+ arg: { args: any[]; db?: ClientOrTransaction },
422
+ ) => Promise<TReturn>;
423
+
424
+ /**
425
+ * Function type generated for a dynamic method configured with `query` and
426
+ * `modifying: true`.
427
+ *
428
+ * Modifying raw queries run through `$executeRawUnsafe` and always resolve to the
429
+ * number of affected rows, so — unlike `QueryMethodFn` — no generic return type is
430
+ * exposed here.
431
+ */
432
+ type QueryMethodModifyingFn = (
433
+ arg: { args: any[]; db?: ClientOrTransaction },
434
+ ) => Promise<number>;
435
+
411
436
  type DynamicMethods<T, M extends PrismaModelName, Config, I> = Config extends { methods: infer Methods }
412
437
  ? {
413
438
  [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>>
439
+ ? Methods[K] extends { query: { modifying: true } }
440
+ ? QueryMethodModifyingFn
441
+ : Methods[K] extends { query: infer Q }
442
+ ? QueryMethodFn
443
+ : (Methods[K] extends { proxyTo: infer P extends string } ? P : K) extends infer ResolvedKey
444
+ ? ResolvedKey extends 'aggregate'
445
+ ? AggregateMethod<M>
446
+ : ResolvedKey extends 'groupBy'
447
+ ? GroupByMethod<M>
448
+ : ResolvedKey extends string
449
+ ? MethodFactory<T, M, ResolvedKey, ExtractSelectModels<Config>, ResolveSelectModel<Methods[K], Config, ExtractSelectModels<Config>>, I, Methods[K], ExtractIncludeModels<Config>>
450
+ : never
421
451
  : never
422
- : never
423
452
  : never;
424
453
  }
425
454
  : {};
@@ -524,6 +553,53 @@ export type MethodConfig<M extends PrismaModelName, SelectModels = any> = {
524
553
  readonly injectOrdenation?: OrdenationModel<M>;
525
554
  /** Injects a fixed pagination automatically into the query. */
526
555
  readonly injectPagination?: PaginationModel<M>;
556
+ /**
557
+ * Turns this method into a **raw SQL query method**, bypassing name-based parsing
558
+ * entirely. The method executes the given SQL directly through Prisma, with
559
+ * parameters injected positionally via the `args` array passed at the call site
560
+ * (`$1`, `$2`, ... placeholders), so no other option in `MethodConfig` applies
561
+ * (`selectModels`, `requiredWhere`, `pushWhere`, etc. are all ignored).
562
+ *
563
+ * - `modifying: false` (default) runs through `$queryRawUnsafe` and the method
564
+ * resolves to `TReturn` (`any` by default), inferable/assertable via a generic
565
+ * at the call site.
566
+ * - `modifying: true` runs through `$executeRawUnsafe` and the method **always**
567
+ * resolves to `number` (the count of affected rows).
568
+ *
569
+ * @example
570
+ * ```typescript
571
+ * methods: {
572
+ * findActiveUsersRaw: {
573
+ * map: true,
574
+ * query: { value: 'SELECT * FROM "user" WHERE active = $1' },
575
+ * },
576
+ * deactivateUsersOlderThanRaw: {
577
+ * map: true,
578
+ * query: { value: 'UPDATE "user" SET active = false WHERE "createdAt" < $1', modifying: true },
579
+ * },
580
+ * }
581
+ *
582
+ * // Uso:
583
+ * const users = await repo.findActiveUsersRaw<User[]>({ args: [true] });
584
+ * const affected = await repo.deactivateUsersOlderThanRaw({ args: [cutoffDate] });
585
+ * ```
586
+ */
587
+ readonly query?: {
588
+ /**
589
+ * Raw SQL statement to execute. Use positional placeholders (`$1`, `$2`, ...)
590
+ * for the values passed in `args`, never string-interpolate the values
591
+ * directly, or you'll re-introduce the SQL injection risk this API exists to avoid.
592
+ */
593
+ readonly value: string;
594
+ /**
595
+ * When `true`, executes via `$executeRawUnsafe` and the method always resolves
596
+ * to `number` (rows affected). When `false`/omitted, executes via
597
+ * `$queryRawUnsafe` and the method resolves to `TReturn` (`any` by default).
598
+ *
599
+ * @default false
600
+ */
601
+ readonly modifying?: boolean;
602
+ };
527
603
  };
528
604
 
529
605
  type BaseMethodConfig<TSelectKeys extends PropertyKey = string> = {
@@ -1062,7 +1138,14 @@ export type ValidateRepoConfig<T extends object, M extends PrismaModelName, Conf
1062
1138
  */
1063
1139
  methods?: {
1064
1140
  [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 })
1141
+ ? MethodConfig<M, Config extends { selectModels: infer SM } ? SM : any> &
1142
+ (K extends ValidMethodPatterns
1143
+ ? {}
1144
+ : (Config extends { methods: infer Meth }
1145
+ ? (K extends keyof Meth ? Meth[K] : never)
1146
+ : never) extends { query: any }
1147
+ ? {}
1148
+ : { proxyTo: ValidMethodPatterns })
1066
1149
  : never;
1067
1150
  };
1068
1151
  };
@@ -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,16 @@
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 query_method_options_validate_1 = require("../validation/query-method-options.validate");
7
+ function QueryMethod(value, options) {
8
+ const validatedConfig = options
9
+ ? (0, query_method_options_validate_1.validateQueryMethodOptions)(options)
10
+ : { modifying: false };
11
+ return (target, propertyKey) => {
12
+ const methods = Reflect.getMetadata(dinamic_methods_key_constant_1.DINAMIC_METHODS_KEY, target) ?? [];
13
+ methods.push(new dynamic_method_metadata_entity_1.DynamicMethodMetadata(propertyKey, true, undefined, undefined, undefined, undefined, undefined, undefined, { value, ...validatedConfig }));
14
+ Reflect.defineMetadata(dinamic_methods_key_constant_1.DINAMIC_METHODS_KEY, methods, target);
15
+ };
16
+ }
@@ -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;
@@ -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
  });
@@ -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 });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vsrepo",
3
- "version": "1.3.3",
3
+ "version": "1.3.4",
4
4
  "description": "A repository pattern library for Prisma",
5
5
  "homepage": "https://github.com/jaobrabo123/VSRepository#readme",
6
6
  "repository": {
@@ -179,16 +179,19 @@ export type * from './VSRepository.types';
179
179
  fileName: 'DynamicRepository.ts',
180
180
  content: `import {
181
181
  DynamicRepository as DynamicRepositoryRuntime,
182
- DynamicMethod as DynamicMethodRuntime
182
+ DynamicMethod as DynamicMethodRuntime,
183
+ QueryMethod as QueryMethodRuntime,
183
184
  } from 'vsrepo/DynamicRepository';
184
185
 
185
186
  import type {
186
187
  DynamicRepository as DynamicRepositoryType,
187
- DynamicMethod as DynamicMethodType
188
+ DynamicMethod as DynamicMethodType,
189
+ QueryMethod as QueryMethodType,
188
190
  } from './DynamicRepository.types';
189
191
 
190
192
  export const DynamicRepository = DynamicRepositoryRuntime as typeof DynamicRepositoryType;
191
193
  export const DynamicMethod = DynamicMethodRuntime as typeof DynamicMethodType;
194
+ export const QueryMethod = QueryMethodRuntime as typeof QueryMethodType;
192
195
 
193
196
  export type * from './DynamicRepository.types';
194
197
  `,
@@ -210,7 +213,8 @@ export {
210
213
 
211
214
  export {
212
215
  DynamicRepository,
213
- DynamicMethod
216
+ DynamicMethod,
217
+ QueryMethod,
214
218
  } from './DynamicRepository.js';
215
219
 
216
220
  export type * from './VSRepoError.types';
@@ -229,15 +233,15 @@ for (const file of tsFiles) {
229
233
  }
230
234
 
231
235
  // Copia o README.md do pacote VSRepository para o diretório de output, se existir
232
- const readmeSource = path.join(packageRoot, 'README.md');
233
- const readmeTarget = path.join(outputDir, 'README.md');
234
-
235
- if (fs.existsSync(readmeSource)) {
236
- fs.copyFileSync(readmeSource, readmeTarget);
237
- console.log(`Gerado: ${path.relative(workspaceRoot, readmeTarget)}`);
238
- } else {
239
- console.warn(`README.md do VSRepository nao encontrado em: ${path.relative(workspaceRoot, readmeSource)}. Ignorando a copia.`);
240
- }
236
+ // const readmeSource = path.join(packageRoot, 'README.md');
237
+ // const readmeTarget = path.join(outputDir, 'README.md');
238
+
239
+ // if (fs.existsSync(readmeSource)) {
240
+ // fs.copyFileSync(readmeSource, readmeTarget);
241
+ // console.log(`Gerado: ${path.relative(workspaceRoot, readmeTarget)}`);
242
+ // } else {
243
+ // console.warn(`README.md do VSRepository nao encontrado em: ${path.relative(workspaceRoot, readmeSource)}. Ignorando a copia.`);
244
+ // }
241
245
 
242
246
  console.log('\nVSRepository gerado com tipagem do Prisma.');
243
247
  console.log(`Output: ${path.relative(workspaceRoot, outputDir)}`);