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 +54 -10
- package/dist/VSRepository.d.ts +23 -4
- package/dist/VSRepository.js +3 -0
- package/dist/internal/resolvers/base-methods.resolve.js +1 -0
- package/dist/internal/resolvers/dbAndPrismaArgs.resolve.js +10 -8
- package/dist/internal/validation/constructor-config.validate.js +1 -0
- package/package.json +1 -1
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
|
-
##
|
|
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>;
|
|
1009
|
-
pkName: keyof T;
|
|
1010
|
-
softRemovekName?: keyof T & string;
|
|
1011
|
-
selectModels?: SelectModels<M>;
|
|
1012
|
-
defaultSelectModel?: keyof SM;
|
|
1013
|
-
requiredWhere?: WhereModel<M>;
|
|
1014
|
-
|
|
1015
|
-
|
|
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
|
-
**`
|
|
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.
|
package/dist/VSRepository.d.ts
CHANGED
|
@@ -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
|
package/dist/VSRepository.js
CHANGED
|
@@ -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 (
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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]) {
|