vsrepo 1.2.8 → 1.2.9

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
@@ -31,6 +31,7 @@ O VSRepository permite criar repositories fortemente tipados com:
31
31
  - [Configurando os métodos base](#configurando-os-métodos-base)
32
32
  - [Select Models](#select-models)
33
33
  - [Required Where](#requiredwhere)
34
+ - [Default Ordenation](#default-ordenation)
34
35
  - [Opção `see`](#opção-see)
35
36
  - [Métodos dinâmicos](#métodos-dinâmicos)
36
37
  - [Prefixos disponíveis](#prefixos-disponíveis)
@@ -485,7 +486,47 @@ const usuario = await usuarioRepository.findByEmail("joao@email.com");
485
486
 
486
487
  ---
487
488
 
488
- ## Opção `see`
489
+ ## Default Ordenation
490
+
491
+ `defaultOrdenation` define uma ordenação padrão aplicada automaticamente em todas as queries que aceitam `orderBy`, sem precisar repetir o argumento `order` em cada chamada.
492
+
493
+ ```ts
494
+ const usuarioRepository = setupVSRepo<Usuario, "usuario">()(({
495
+ tableName: "usuario",
496
+ pkName: "id",
497
+ defaultOrdenation: { criadoEm: "desc" },
498
+ }).build(prisma);
499
+ ```
500
+
501
+ Com isso, toda query de listagem já virá ordenada por `criadoEm` decrescente:
502
+
503
+ ```ts
504
+ // Internamente: ORDER BY criadoEm DESC
505
+ const usuarios = await usuarioRepository.getAll();
506
+
507
+ // Também aplica ao getAll com pagination
508
+ const paginados = await usuarioRepository.getAll({ pagination: { take: 10 } });
509
+ ```
510
+
511
+ **A `defaultOrdenation` é ignorada quando:**
512
+
513
+ - O método usa o sufixo `Ordered`, `OrderedAndPaginated` ou `PaginatedAndOrdered` — nesses casos o argumento `order` passado na chamada tem prioridade.
514
+ - O método dinâmico tem `injectOrdenation` configurado — a ordenação fixa do método prevalece.
515
+
516
+ ```ts
517
+ methods: {
518
+ findManyPaginatedAndOrdered: { map: true }, // ordem vem do argumento → defaultOrdenation ignorada
519
+ findManyByAtivo: { map: true }, // sem Ordered → defaultOrdenation aplicada
520
+ findManyByStatus: {
521
+ map: true,
522
+ injectOrdenation: { nome: "asc" }, // injectOrdenation → defaultOrdenation ignorada
523
+ },
524
+ }
525
+ ```
526
+
527
+ > `defaultOrdenation` aceita o mesmo tipo que o `orderBy` nativo do Prisma para o modelo — incluindo arrays de ordenações encadeadas.
528
+
529
+ ---
489
530
 
490
531
  Quando `softRemovekName` está configurado, todos os métodos base aceitam a opção `see` para controlar a visibilidade de registros soft-deletados:
491
532
 
@@ -1005,14 +1046,15 @@ type UsuarioPatchPayload = PatchObject<Prisma.UsuarioUpdateInput, typeof usuario
1005
1046
 
1006
1047
  ```ts
1007
1048
  setupVSRepo<TPayload, TTableName>()({
1008
- tableName: Uncapitalize<M>; // Nome da tabela no Prisma
1009
- pkName: keyof T; // Nome da primary key
1010
- softRemovekName?: keyof T & string; // Campo DateTime para soft-delete (opcional)
1011
- selectModels?: SelectModels<M>; // Projeções de dados nomeadas
1012
- defaultSelectModel?: keyof SM; // Select aplicado por padrão
1013
- requiredWhere?: WhereModel<M>; // Filtros sempre aplicados
1014
- relations?: RepositoryRelations<T>; // Configuração de relações
1015
- methods?: Record<string, MethodConfig<M, SM>>; // Métodos dinâmicos
1049
+ tableName: Uncapitalize<M>; // Nome da tabela no Prisma
1050
+ pkName: keyof T; // Nome da primary key
1051
+ softRemovekName?: keyof T & string; // Campo DateTime para soft-delete (opcional)
1052
+ selectModels?: SelectModels<M>; // Projeções de dados nomeadas
1053
+ defaultSelectModel?: keyof SM; // Select aplicado por padrão
1054
+ requiredWhere?: WhereModel<M>; // Filtros sempre aplicados
1055
+ defaultOrdenation?: OrdenationModel<M>; // Ordenação padrão para queries sem Ordered/injectOrdenation
1056
+ relations?: RepositoryRelations<T>; // Configuração de relações
1057
+ methods?: Record<string, MethodConfig<M, SM>>; // Métodos dinâmicos
1016
1058
  });
1017
1059
  ```
1018
1060
 
@@ -1106,4 +1148,6 @@ Para reportar problemas ou sugerir novas funcionalidades, abra uma **Issue**.
1106
1148
 
1107
1149
  **`softRemovekName` lança erro no build** — O campo informado deve ser do tipo `DateTime` no schema do Prisma. Tipos como `Boolean` ou `String` não são aceitos.
1108
1150
 
1109
- **`saveList`/`patchList` com `db` inválido** — O campo `db` nestes métodos aceita apenas `DbTransaction` (retorno de `prisma.$transaction`), não o cliente principal. Passar o `PrismaClient` diretamente causará comportamento inesperado.
1151
+ **`defaultOrdenation` não está sendo aplicada** — Verifique se o método não usa o sufixo `Ordered`, `OrderedAndPaginated` ou `PaginatedAndOrdered`, e se não possui `injectOrdenation` configurado. Ambos têm prioridade sobre a ordenação padrão.
1152
+
1153
+ **`saveList`/`patchList` com `db` inválido** — O campo `db` nestes métodos aceita apenas `DbTransaction` (retorno de `prisma.$transaction`), não o cliente principal. Passar o `PrismaClient` diretamente causará comportamento inesperado.
@@ -195,7 +195,7 @@ type GetCreateManyInput<I> = I extends { createManyInput: infer CM } ? CM : unkn
195
195
  type GetUpdateManyInput<I> = I extends { updateManyInput: infer UM } ? UM : unknown;
196
196
  type GetWhereInput<I> = I extends { whereInput: infer W } ? NonNullable<W> : unknown;
197
197
  type GetCursorInput<I> = I extends { cursorInput: infer C } ? C : unknown;
198
- type GetOrderByInput<I> = I extends { orderByInput: infer OB } ? OB : OrderOptions;
198
+ type GetOrderByInput<I> = I extends { orderByInput: infer OB } ? NonNullable<OB> : OrderOptions;
199
199
 
200
200
  type ExtraArgs<M extends string, R extends string, I> = [
201
201
  ...(M extends 'upsertBy' ? [update: GetUpdateInput<I>, create: GetCreateInput<I>]
@@ -349,6 +349,7 @@ type ExtractSelectModels<Config> = Config extends { selectModels: infer SM } ? S
349
349
  type ExtractDefaultSelect<Config> = Config extends { defaultSelectModel: infer D } ? D : never;
350
350
  type ExtractRelations<Config> = Config extends { relations: infer R } ? (R extends object ? R : {}) : {};
351
351
  type ExtractSoftRemovekName<Config> = Config extends { softRemovekName: infer S } ? S : never;
352
+ type ExtractDefaultOrdenation<Config> = Config extends { defaultOrdenation: infer O } ? O : never;
352
353
 
353
354
  type AggregateMethod<M extends Prisma.ModelName> = <A extends Prisma.TypeMap['model'][M]['operations']['aggregate']['args']>(
354
355
  prismaArgs: A,
@@ -644,6 +645,7 @@ type _Sel<Config> = ExtractSelectModels<Config>;
644
645
  type _Def<Config> = ExtractDefaultSelect<Config>;
645
646
  type _Rel<Config> = ExtractRelations<Config>;
646
647
  type _Soft<Config> = ExtractSoftRemovekName<Config>;
648
+ type _DOrd<Config> = ExtractDefaultOrdenation<Config>;
647
649
 
648
650
  // ─── refactored mapped type — optimized for the TS compiler ──────────────────
649
651
 
@@ -657,7 +659,8 @@ type AllBaseMethods<
657
659
  TPk = ExtractPkName<T, Config>,
658
660
  TRelations = _Rel<Config>,
659
661
  TSoftKey = _Soft<Config>,
660
- I = PrismaModelInputs<M>
662
+ I = PrismaModelInputs<M>,
663
+ TDefaultOrdenation = _DOrd<Config>
661
664
  > = {
662
665
  /** Fetches a record by its primary key (PK). */
663
666
  get: <S extends keyof TSelects | false = _DS<Config, C, 'get', TSelects>>(
@@ -711,6 +714,11 @@ type AllBaseMethods<
711
714
  getAll: <S extends keyof TSelects | false = _DS<Config, C, 'getAll', TSelects>>(
712
715
  options?: MethodOptions<S> & {
713
716
  pagination?: PaginationOptions<I extends { cursorInput: infer Curs } ? Curs : unknown>;
717
+ /**
718
+ * Ordering to apply to the query.
719
+ * When omitted and `defaultOrdenation` is configured on the repository,
720
+ * the default ordering is applied automatically.
721
+ */
714
722
  order?: I extends { orderByInput: infer OB } ? OB : OrderOptions;
715
723
  }
716
724
  ) => Promise<_Ret<M, TSelects, S, TDefault>[]>;
@@ -748,9 +756,10 @@ type InjectedBaseMethods<
748
756
  TPk = ExtractPkName<T, Config>,
749
757
  TRelations = _Rel<Config>,
750
758
  TSoftKey = _Soft<Config>,
751
- I = PrismaModelInputs<M>
759
+ I = PrismaModelInputs<M>,
760
+ TDefaultOrdenation = _DOrd<Config>
752
761
  > = Pick<
753
- AllBaseMethods<T, M, Config, C, TSelects, TDefault, TPk, TRelations, TSoftKey, I>,
762
+ AllBaseMethods<T, M, Config, C, TSelects, TDefault, TPk, TRelations, TSoftKey, I, TDefaultOrdenation>,
754
763
  | (C extends { baseMethods: { get: { active: false } } } ? never : 'get')
755
764
  | (C extends { baseMethods: { getOrThrow: { active: false } } } ? never : 'getOrThrow')
756
765
  | (C extends { baseMethods: { getList: { active: false } } } ? never : 'getList')
@@ -853,6 +862,7 @@ export type RepoConfig<T, M extends Prisma.ModelName, SM extends Record<string,
853
862
  selectModels?: SM;
854
863
  defaultSelectModel?: Extract<keyof SM, string>;
855
864
  requiredWhere?: WhereModel<M>;
865
+ defaultOrdenation?: OrdenationModel<M>;
856
866
  relations?: RepositoryRelations<T>;
857
867
  methods?: Record<string, MethodConfig<M, SM>>;
858
868
  };
@@ -942,6 +952,15 @@ export type ValidateRepoConfig<T extends object, M extends Prisma.ModelName, Con
942
952
  */
943
953
  requiredWhere?: WhereModel<M>;
944
954
 
955
+ /**
956
+ * Default ordering automatically injected into all queries that accept `orderBy`,
957
+ * unless the method already has `injectOrdenation` configured or uses the `Ordered` suffix.
958
+ *
959
+ * Useful for ensuring a consistent sort order across the repository without repeating
960
+ * the `order` argument on every call.
961
+ */
962
+ defaultOrdenation?: OrdenationModel<M>;
963
+
945
964
  /**
946
965
  * Configures automatic relation management.
947
966
  * When configured, allows the `save`, `saveList`, `patch`, and `patchList` methods
@@ -39,6 +39,7 @@ class VSRepository {
39
39
  requiredWhere;
40
40
  relations;
41
41
  methods;
42
+ defaultOrdenation;
42
43
  constructor(config) {
43
44
  const validatedConfig = (0, constructor_config_validate_1.validateConstructorConfig)(config);
44
45
  this.vsrepocache = new Map();
@@ -50,6 +51,7 @@ class VSRepository {
50
51
  this.relations = validatedConfig.relations;
51
52
  this.requiredWhere = validatedConfig.requiredWhere;
52
53
  this.methods = validatedConfig.methods;
54
+ this.defaultOrdenation = validatedConfig.defaultOrdenation;
53
55
  }
54
56
  extend(extensionFunc) {
55
57
  const extension = (0, extension_validate_1.validateExtension)(extensionFunc, this);
@@ -139,6 +141,7 @@ class VSRepository {
139
141
  updatePayload: dinamicMethodInfo.updateIndex !== undefined
140
142
  ? args.at(dinamicMethodInfo.updateIndex)
141
143
  : undefined,
144
+ withOrdenationAndPagination: !dinamicMethodInfo.ignoreOrderByAndPagination,
142
145
  };
143
146
  if (!dinamicMethodInfo.ignoreWhere) {
144
147
  resolveDbAndPrismaArgsData.specificWhere = (0, specific_where_resolve_1.resolveSpecificWhere)(args, dinamicMethodWhereOps.prettyWheres);
@@ -92,6 +92,7 @@ function resolveBaseMethods(instance, config) {
92
92
  options: restOptions,
93
93
  pagination,
94
94
  ordenation: order,
95
+ withOrdenationAndPagination: true,
95
96
  });
96
97
  const start = showWorking
97
98
  ? (0, logger_util_1.performanceLoggerStart)(tableName, "getAll", prismaArgs)
@@ -5,7 +5,7 @@ const method_options_validate_1 = require("../validation/method-options.validate
5
5
  const merge_wheres_resolve_1 = require("./merge-wheres.resolve");
6
6
  const select_resolve_1 = require("./select.resolve");
7
7
  function resolveDbAndPrismaArgs(data) {
8
- const { baseConfig, instance, options, wherePkValue, withoutSelect, withoutWhere, specificSelect, dataPayload, createPayload, updatePayload, alreadyValidatedOptions, specificWhere, pushWhere, ordenation, pagination, skipDuplicates, forceSeeMode, } = data;
8
+ const { baseConfig, instance, options, wherePkValue, withoutSelect, withoutWhere, specificSelect, dataPayload, createPayload, updatePayload, alreadyValidatedOptions, specificWhere, pushWhere, ordenation, pagination, skipDuplicates, forceSeeMode, withOrdenationAndPagination, } = data;
9
9
  const validatedOptions = (alreadyValidatedOptions && options)
10
10
  ? options
11
11
  : (0, method_options_validate_1.validateMethodOptions)(options, instance);
@@ -31,13 +31,15 @@ function resolveDbAndPrismaArgs(data) {
31
31
  if (updatePayload) {
32
32
  prismaArgs.update = updatePayload;
33
33
  }
34
- if (ordenation) {
35
- prismaArgs.orderBy = ordenation;
36
- }
37
- if (pagination) {
38
- prismaArgs.skip = pagination.skip;
39
- prismaArgs.take = pagination.take;
40
- prismaArgs.cursor = pagination.cursor;
34
+ if (withOrdenationAndPagination) {
35
+ if (instance.defaultOrdenation || ordenation) {
36
+ prismaArgs.orderBy = ordenation ?? instance.defaultOrdenation;
37
+ }
38
+ if (pagination) {
39
+ prismaArgs.skip = pagination.skip;
40
+ prismaArgs.take = pagination.take;
41
+ prismaArgs.cursor = pagination.cursor;
42
+ }
41
43
  }
42
44
  if (skipDuplicates !== undefined) {
43
45
  prismaArgs.skipDuplicates = skipDuplicates;
@@ -37,6 +37,7 @@ function validateConstructorConfig(config) {
37
37
  injectPagination: schemas_util_1.objectSchema.optional(),
38
38
  }))
39
39
  .optional(),
40
+ defaultOrdenation: schemas_util_1.objectSchema.or(zod_1.default.array(schemas_util_1.objectSchema)).optional(),
40
41
  })
41
42
  .superRefine((config, ctx) => {
42
43
  if (config.defaultSelectModel && !config.selectModels?.[config.defaultSelectModel]) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vsrepo",
3
- "version": "1.2.8",
3
+ "version": "1.2.9",
4
4
  "description": "Uma biblioteca de repository pattern para Prisma",
5
5
  "homepage": "https://github.com/jaobrabo123/VSRepository#readme",
6
6
  "repository": {