@vsrepo/prisma7-adapter 1.0.3 → 1.1.0
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 +27 -1
- package/README.pt-BR.md +27 -1
- package/dist/prisma7.adapter.d.ts +58 -1
- package/dist/prisma7.adapter.js +117 -0
- package/dist/types/prisma-repository-like.type.d.ts +7 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
- [How each write method resolves relations](#how-each-write-method-resolves-relations)
|
|
34
34
|
- [`relations` in method options (read)](#relations-in-method-options-read)
|
|
35
35
|
- [`merge`](#merge)
|
|
36
|
+
- [Atomic and aggregation methods](#atomic-and-aggregation-methods)
|
|
36
37
|
- [`createMany`/`createManyReturning`/`updateMany`/`updateManyReturning` don't support nested writes](#createmanycreatemanyreturningupdatemanyupdatemanyreturning-dont-support-nested-writes)
|
|
37
38
|
- [Provider-specific limitations](#provider-specific-limitations)
|
|
38
39
|
- [Transactions](#transactions)
|
|
@@ -197,6 +198,31 @@ const prismaInclude = prismaSelect
|
|
|
197
198
|
|
|
198
199
|
For to-many relations (`otm`/`mtm`), items in the stored record and items in `obj` are matched by the configured `pk`: a match merges the two items, a new `pk` (or no `pk`) is appended. Nothing is ever removed by `merge`.
|
|
199
200
|
|
|
201
|
+
## Atomic and aggregation methods
|
|
202
|
+
|
|
203
|
+
> Requires `vsrepo` **2.1.0+** — these methods were added to the `VSRepoAdapter` contract in that release (see the [VSRepository CHANGELOG](https://github.com/jaobrabo123/VSRepository/blob/main/CHANGELOG.md#210---2026-09-04)).
|
|
204
|
+
|
|
205
|
+
The adapter implements the 8 abstract methods `VSRepository`'s `increment`/`decrement`/`multiply`/`divide`/`sum`/`average`/`min`/`max` delegate to: `incrementOne`, `decrementOne`, `multiplyOne`, `divideOne`, `sum`, `average`, `min`, `max`.
|
|
206
|
+
|
|
207
|
+
- `incrementOne`/`decrementOne`/`multiplyOne`/`divideOne` translate directly into Prisma's native single-field atomic write — `data: { [field]: { increment: value } }` (and `decrement`/`multiply`/`divide`) — so the operation is evaluated **server-side** against the row's *current* value (`UPDATE ... SET field = field + value`), not as a fetch-then-save round trip on the client. Prisma's `update()` already returns the row reflecting the state *after* the write, so the adapter never issues a follow-up read.
|
|
208
|
+
- `sum`/`average`/`min`/`max` translate into Prisma's `aggregate()` with `_sum`/`_avg`/`_min`/`_max: { [field]: true }`. The raw result (`number`, `bigint`, a `Decimal` instance, or `null`) is normalized to `number | null` — `null` is returned as-is (mirroring SQL's `SUM()`/`AVG()`/`MIN()`/`MAX()`, which return `NULL`, not `0`, over an empty set), and a `Decimal`/`DecimalLike` value is converted via its `.toNumber()`.
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
// Atomic — evaluated server-side, no read-modify-write:
|
|
212
|
+
await productRepository.increment(productId, "stock", 10);
|
|
213
|
+
await accountRepository.decrement(accountId, "balance", 50);
|
|
214
|
+
await productRepository.multiply(productId, "price", 1.1); // e.g. a 10% price bump
|
|
215
|
+
await productRepository.divide(productId, "price", 2);
|
|
216
|
+
|
|
217
|
+
// Aggregation — across every record matching an optional `where` (all if omitted):
|
|
218
|
+
const total = await productRepository.sum("price"); // number | null
|
|
219
|
+
const avgPrice = await productRepository.average("price", { active: true });
|
|
220
|
+
const cheapest = await productRepository.min("price");
|
|
221
|
+
const mostExpensive = await productRepository.max("price");
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**Decimal fields** (`Prisma.Decimal`) are fully supported as the `field` for all 8 methods — `value` for the atomic methods is passed straight through to Prisma (which accepts a `number`, `string`, or `Decimal`/`DecimalJsLike`), and the aggregate methods always normalize the result to a `number`, never a `Decimal` instance.
|
|
225
|
+
|
|
200
226
|
## `createMany`/`createManyReturning`/`updateMany`/`updateManyReturning` don't support nested writes
|
|
201
227
|
|
|
202
228
|
`createMany`, `createManyReturning`, `updateMany` and `updateManyReturning` only accept scalar fields in their `data`. If your payload includes a field configured in `relations` (regardless of its value), the adapter throws a `VSRepoPrisma7AdapterError` naming the offending field. For a full nested write, use `create`/`update`/`save` one record at a time, or wrap several `save` calls in a `saveMany`/`transaction`.
|
|
@@ -272,5 +298,5 @@ The adapter uses `VSLogger` (from `vsrepo`) internally: every method logs a `DEB
|
|
|
272
298
|
|
|
273
299
|
## Requirements
|
|
274
300
|
|
|
275
|
-
- `vsrepo`
|
|
301
|
+
- `vsrepo` ^2.1.0
|
|
276
302
|
- `@prisma/client` ^7.10.0
|
package/README.pt-BR.md
CHANGED
|
@@ -33,6 +33,7 @@ Implementação de `VSRepoAdapter` para o [VSRepository v2](https://github.com/j
|
|
|
33
33
|
- [Como cada método de escrita resolve relations](#como-cada-método-de-escrita-resolve-relations)
|
|
34
34
|
- [`relations` nas options (leitura)](#relations-nas-options-leitura)
|
|
35
35
|
- [`merge`](#merge)
|
|
36
|
+
- [Métodos atômicos e de agregação](#métodos-atômicos-e-de-agregação)
|
|
36
37
|
- [`createMany`/`createManyReturning`/`updateMany`/`updateManyReturning` não suportam nested writes](#createmanycreatemanyreturningupdatemanyupdatemanyreturning-não-suportam-nested-writes)
|
|
37
38
|
- [Limitações por provider](#limitações-por-provider)
|
|
38
39
|
- [Transactions](#transactions)
|
|
@@ -197,6 +198,31 @@ const prismaInclude = prismaSelect
|
|
|
197
198
|
|
|
198
199
|
Pra relations to-many (`otm`/`mtm`), os itens do registro salvo e os itens de `obj` são casados pela `pk` configurada: um match faz merge dos dois itens, uma `pk` nova (ou sem `pk`) é apenas adicionada. `merge` nunca remove nada.
|
|
199
200
|
|
|
201
|
+
## Métodos atômicos e de agregação
|
|
202
|
+
|
|
203
|
+
> Requer `vsrepo` **2.1.0+** — esses métodos foram adicionados ao contrato do `VSRepoAdapter` nessa versão (veja o [CHANGELOG do VSRepository](https://github.com/jaobrabo123/VSRepository/blob/main/CHANGELOG.md#210---2026-09-04-português)).
|
|
204
|
+
|
|
205
|
+
O adapter implementa os 8 métodos abstratos pros quais `increment`/`decrement`/`multiply`/`divide`/`sum`/`average`/`min`/`max` do `VSRepository` delegam: `incrementOne`, `decrementOne`, `multiplyOne`, `divideOne`, `sum`, `average`, `min`, `max`.
|
|
206
|
+
|
|
207
|
+
- `incrementOne`/`decrementOne`/`multiplyOne`/`divideOne` traduzem direto pra escrita atômica nativa de campo único do Prisma — `data: { [field]: { increment: value } }` (e `decrement`/`multiply`/`divide`) — então a operação é avaliada **server-side** contra o valor *atual* do registro (`UPDATE ... SET field = field + value`), e não como um fetch-then-save no cliente. O `update()` do Prisma já retorna a linha refletindo o estado *após* a escrita, então o adapter nunca precisa fazer uma leitura extra.
|
|
208
|
+
- `sum`/`average`/`min`/`max` traduzem pro `aggregate()` do Prisma, com `_sum`/`_avg`/`_min`/`_max: { [field]: true }`. O resultado bruto (`number`, `bigint`, uma instância de `Decimal`, ou `null`) é normalizado pra `number | null` — `null` é repassado como está (espelhando o `SUM()`/`AVG()`/`MIN()`/`MAX()` do SQL, que retornam `NULL`, não `0`, sobre um conjunto vazio), e um valor `Decimal`/`DecimalLike` é convertido via seu `.toNumber()`.
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
// Atômico — avaliado server-side, sem read-modify-write:
|
|
212
|
+
await productRepository.increment(productId, "stock", 10);
|
|
213
|
+
await accountRepository.decrement(accountId, "balance", 50);
|
|
214
|
+
await productRepository.multiply(productId, "price", 1.1); // ex: um reajuste de 10% no preço
|
|
215
|
+
await productRepository.divide(productId, "price", 2);
|
|
216
|
+
|
|
217
|
+
// Agregação — entre todos os registros que casam com um `where` opcional (todos se omitido):
|
|
218
|
+
const total = await productRepository.sum("price"); // number | null
|
|
219
|
+
const avgPrice = await productRepository.average("price", { active: true });
|
|
220
|
+
const cheapest = await productRepository.min("price");
|
|
221
|
+
const mostExpensive = await productRepository.max("price");
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
**Campos Decimal** (`Prisma.Decimal`) são totalmente suportados como o `field` dos 8 métodos — o `value` dos métodos atômicos é repassado direto pro Prisma (que aceita `number`, `string`, ou `Decimal`/`DecimalJsLike`), e os métodos de agregação sempre normalizam o resultado pra `number`, nunca uma instância de `Decimal`.
|
|
225
|
+
|
|
200
226
|
## `createMany`/`createManyReturning`/`updateMany`/`updateManyReturning` não suportam nested writes
|
|
201
227
|
|
|
202
228
|
`createMany`, `createManyReturning`, `updateMany` e `updateManyReturning` só aceitam campos escalares no `data`. Se seu payload incluir um campo configurado em `relations` (independente do valor), o adapter lança um `VSRepoPrisma7AdapterError` apontando o campo problemático. Pra um nested write completo, use `create`/`update`/`save` registro por registro, ou envolva várias chamadas de `save` num `saveMany`/`transaction`.
|
|
@@ -272,5 +298,5 @@ O adapter usa o `VSLogger` (de `vsrepo`) internamente: todo método loga uma lin
|
|
|
272
298
|
|
|
273
299
|
## Requisitos
|
|
274
300
|
|
|
275
|
-
- `vsrepo`
|
|
301
|
+
- `vsrepo` ^2.1.0
|
|
276
302
|
- `@prisma/client` ^7.10.0
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AdapterMethodOptions, AdapterQueryOptions, CountResult, DeepPartial, VSRepoAdapter, VSRepoWhere } from "vsrepo";
|
|
1
|
+
import { AdapterMethodOptions, AdapterQueryOptions, CountResult, DeepPartial, NumericKeys, VSRepoAdapter, VSRepoWhere } from "vsrepo";
|
|
2
2
|
import { VSRepoPrisma7AdapterConfig } from "./types/adapter-config.type";
|
|
3
3
|
/**
|
|
4
4
|
* `VSRepoAdapter` implementation for Prisma 7. Translates every method of the
|
|
@@ -50,6 +50,35 @@ export declare class VSRepoPrisma7Adapter<T> extends VSRepoAdapter<T> {
|
|
|
50
50
|
* started on it (or on `this.prisma` when `db` isn't provided at all).
|
|
51
51
|
*/
|
|
52
52
|
private runTransactional;
|
|
53
|
+
/**
|
|
54
|
+
* Runs a single-field atomic update (`increment`/`decrement`/`multiply`/
|
|
55
|
+
* `divide`) via Prisma's native `{ field: { <op>: value } }` write —
|
|
56
|
+
* evaluated server-side against the row's current value, never as a
|
|
57
|
+
* client-side read-modify-write. `value` is passed through as-is:
|
|
58
|
+
* Prisma accepts a `number`, `bigint`, or any `Decimal`/`DecimalJsLike`
|
|
59
|
+
* value (which covers a {@link DecimalLike} like `Prisma.Decimal`)
|
|
60
|
+
* depending on the target column's type.
|
|
61
|
+
*
|
|
62
|
+
* Prisma's `update()` already returns the row reflecting the state
|
|
63
|
+
* *after* the write, so no follow-up read is needed here.
|
|
64
|
+
*/
|
|
65
|
+
private atomicUpdate;
|
|
66
|
+
/**
|
|
67
|
+
* Converts a raw value returned by Prisma's `aggregate()` (`number`,
|
|
68
|
+
* `bigint`, a `Decimal` instance, or `null` when no record matches)
|
|
69
|
+
* into the `number | null` shape required by the `VSRepoAdapter`
|
|
70
|
+
* aggregate contract.
|
|
71
|
+
*/
|
|
72
|
+
private toNullableNumber;
|
|
73
|
+
/**
|
|
74
|
+
* Runs a single-field aggregation (`sum`/`avg`/`min`/`max`) via Prisma's
|
|
75
|
+
* `aggregate()`, across every record matching `where` (all records if
|
|
76
|
+
* empty). Returns `null` when no record matches — mirroring SQL's
|
|
77
|
+
* `SUM()`/`AVG()`/`MIN()`/`MAX()`, which return `NULL` (not `0`) over an
|
|
78
|
+
* empty set — instead of Prisma's own `_sum`/`_avg`/`_min`/`_max: null`
|
|
79
|
+
* shape.
|
|
80
|
+
*/
|
|
81
|
+
private aggregate;
|
|
53
82
|
/** Returns the underlying ORM client instance used outside of transactions. */
|
|
54
83
|
getDbClient(): any;
|
|
55
84
|
/** Runs `fn` inside a native transaction of the underlying ORM/database. */
|
|
@@ -130,4 +159,32 @@ export declare class VSRepoPrisma7Adapter<T> extends VSRepoAdapter<T> {
|
|
|
130
159
|
merge<K>(where: VSRepoWhere<T>, obj: DeepPartial<T>, options?: AdapterMethodOptions<T>): Promise<K & T>;
|
|
131
160
|
/** Creates a record if none matches `where`, otherwise updates it. */
|
|
132
161
|
upsert(where: VSRepoWhere<T>, create: DeepPartial<T>, update: DeepPartial<T>, options?: AdapterMethodOptions<T>): Promise<T>;
|
|
162
|
+
/**
|
|
163
|
+
* Atomically adds `value` to `field` on the record matching `where`,
|
|
164
|
+
* via Prisma's native `{ field: { increment: value } }` write.
|
|
165
|
+
*/
|
|
166
|
+
incrementOne<K extends NumericKeys<T>>(field: K, value: NonNullable<T[K]>, where: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<T>;
|
|
167
|
+
/** Same as {@link VSRepoPrisma7Adapter.incrementOne}, subtracting `value` instead of adding it. */
|
|
168
|
+
decrementOne<K extends NumericKeys<T>>(field: K, value: NonNullable<T[K]>, where: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<T>;
|
|
169
|
+
/** Same as {@link VSRepoPrisma7Adapter.incrementOne}, multiplying the field's current value by `value`. */
|
|
170
|
+
multiplyOne<K extends NumericKeys<T>>(field: K, value: NonNullable<T[K]>, where: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<T>;
|
|
171
|
+
/**
|
|
172
|
+
* Same as {@link VSRepoPrisma7Adapter.incrementOne}, dividing the
|
|
173
|
+
* field's current value by `value`. Division-by-zero is not handled by
|
|
174
|
+
* the adapter — it's whatever Postgres does natively (raises a
|
|
175
|
+
* `division_by_zero` error for integer columns; `Infinity`/`NaN` are not
|
|
176
|
+
* representable in a numeric/decimal column, so those also error).
|
|
177
|
+
*/
|
|
178
|
+
divideOne<K extends NumericKeys<T>>(field: K, value: NonNullable<T[K]>, where: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<T>;
|
|
179
|
+
/**
|
|
180
|
+
* Returns the sum of `field` across every record matching `where` (all
|
|
181
|
+
* records if `where` is empty), or `null` if no record matches.
|
|
182
|
+
*/
|
|
183
|
+
sum(field: NumericKeys<T>, where: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<number | null>;
|
|
184
|
+
/** Same as {@link VSRepoPrisma7Adapter.sum}, but the arithmetic mean instead of the total. */
|
|
185
|
+
average(field: NumericKeys<T>, where: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<number | null>;
|
|
186
|
+
/** Same as {@link VSRepoPrisma7Adapter.sum}, but the minimum value instead of the total. */
|
|
187
|
+
min(field: NumericKeys<T>, where: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<number | null>;
|
|
188
|
+
/** Same as {@link VSRepoPrisma7Adapter.sum}, but the maximum value instead of the total. */
|
|
189
|
+
max(field: NumericKeys<T>, where: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<number | null>;
|
|
133
190
|
}
|
package/dist/prisma7.adapter.js
CHANGED
|
@@ -106,6 +106,79 @@ class VSRepoPrisma7Adapter extends vsrepo_1.VSRepoAdapter {
|
|
|
106
106
|
}
|
|
107
107
|
return (db ?? this.prisma).$transaction(fn);
|
|
108
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* Runs a single-field atomic update (`increment`/`decrement`/`multiply`/
|
|
111
|
+
* `divide`) via Prisma's native `{ field: { <op>: value } }` write —
|
|
112
|
+
* evaluated server-side against the row's current value, never as a
|
|
113
|
+
* client-side read-modify-write. `value` is passed through as-is:
|
|
114
|
+
* Prisma accepts a `number`, `bigint`, or any `Decimal`/`DecimalJsLike`
|
|
115
|
+
* value (which covers a {@link DecimalLike} like `Prisma.Decimal`)
|
|
116
|
+
* depending on the target column's type.
|
|
117
|
+
*
|
|
118
|
+
* Prisma's `update()` already returns the row reflecting the state
|
|
119
|
+
* *after* the write, so no follow-up read is needed here.
|
|
120
|
+
*/
|
|
121
|
+
async atomicUpdate(operation, field, value, where, options) {
|
|
122
|
+
const start = this.logger.startPerformLog(`run ${operation}One`);
|
|
123
|
+
try {
|
|
124
|
+
const arg = {
|
|
125
|
+
...this.resolveReadArg(options),
|
|
126
|
+
where: (0, where_parser_1.parsePrismaWhere)(where),
|
|
127
|
+
data: { [field]: { [operation]: value } },
|
|
128
|
+
};
|
|
129
|
+
this.logger.logDebug(`Resolved Prisma arg for '${operation}One'`, arg);
|
|
130
|
+
return await this.getPrismaRepository(options?.db).update(arg);
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, `${operation}One`);
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
this.logger.endPerformLog(start);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Converts a raw value returned by Prisma's `aggregate()` (`number`,
|
|
141
|
+
* `bigint`, a `Decimal` instance, or `null` when no record matches)
|
|
142
|
+
* into the `number | null` shape required by the `VSRepoAdapter`
|
|
143
|
+
* aggregate contract.
|
|
144
|
+
*/
|
|
145
|
+
toNullableNumber(value) {
|
|
146
|
+
if (value === null || value === undefined)
|
|
147
|
+
return null;
|
|
148
|
+
if (typeof value === "bigint")
|
|
149
|
+
return Number(value);
|
|
150
|
+
if (typeof value?.toNumber === "function") {
|
|
151
|
+
return value.toNumber();
|
|
152
|
+
}
|
|
153
|
+
return Number(value);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Runs a single-field aggregation (`sum`/`avg`/`min`/`max`) via Prisma's
|
|
157
|
+
* `aggregate()`, across every record matching `where` (all records if
|
|
158
|
+
* empty). Returns `null` when no record matches — mirroring SQL's
|
|
159
|
+
* `SUM()`/`AVG()`/`MIN()`/`MAX()`, which return `NULL` (not `0`) over an
|
|
160
|
+
* empty set — instead of Prisma's own `_sum`/`_avg`/`_min`/`_max: null`
|
|
161
|
+
* shape.
|
|
162
|
+
*/
|
|
163
|
+
async aggregate(operation, field, where, options) {
|
|
164
|
+
const start = this.logger.startPerformLog(`run ${operation}`);
|
|
165
|
+
const aggKey = `_${operation}`;
|
|
166
|
+
try {
|
|
167
|
+
const arg = {
|
|
168
|
+
where: (0, where_parser_1.parsePrismaWhere)(where),
|
|
169
|
+
[aggKey]: { [field]: true },
|
|
170
|
+
};
|
|
171
|
+
this.logger.logDebug(`Resolved Prisma arg for '${operation}'`, arg);
|
|
172
|
+
const result = await this.getPrismaRepository(options?.db).aggregate(arg);
|
|
173
|
+
return this.toNullableNumber(result?.[aggKey]?.[field]);
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
throw (0, map_prisma_error_resolver_1.mapPrismaError)(error, operation);
|
|
177
|
+
}
|
|
178
|
+
finally {
|
|
179
|
+
this.logger.endPerformLog(start);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
109
182
|
/** Returns the underlying ORM client instance used outside of transactions. */
|
|
110
183
|
getDbClient() {
|
|
111
184
|
return this.prisma;
|
|
@@ -509,5 +582,49 @@ class VSRepoPrisma7Adapter extends vsrepo_1.VSRepoAdapter {
|
|
|
509
582
|
this.logger.endPerformLog(start);
|
|
510
583
|
}
|
|
511
584
|
}
|
|
585
|
+
/**
|
|
586
|
+
* Atomically adds `value` to `field` on the record matching `where`,
|
|
587
|
+
* via Prisma's native `{ field: { increment: value } }` write.
|
|
588
|
+
*/
|
|
589
|
+
async incrementOne(field, value, where, options) {
|
|
590
|
+
return this.atomicUpdate("increment", field, value, where, options);
|
|
591
|
+
}
|
|
592
|
+
/** Same as {@link VSRepoPrisma7Adapter.incrementOne}, subtracting `value` instead of adding it. */
|
|
593
|
+
async decrementOne(field, value, where, options) {
|
|
594
|
+
return this.atomicUpdate("decrement", field, value, where, options);
|
|
595
|
+
}
|
|
596
|
+
/** Same as {@link VSRepoPrisma7Adapter.incrementOne}, multiplying the field's current value by `value`. */
|
|
597
|
+
async multiplyOne(field, value, where, options) {
|
|
598
|
+
return this.atomicUpdate("multiply", field, value, where, options);
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Same as {@link VSRepoPrisma7Adapter.incrementOne}, dividing the
|
|
602
|
+
* field's current value by `value`. Division-by-zero is not handled by
|
|
603
|
+
* the adapter — it's whatever Postgres does natively (raises a
|
|
604
|
+
* `division_by_zero` error for integer columns; `Infinity`/`NaN` are not
|
|
605
|
+
* representable in a numeric/decimal column, so those also error).
|
|
606
|
+
*/
|
|
607
|
+
async divideOne(field, value, where, options) {
|
|
608
|
+
return this.atomicUpdate("divide", field, value, where, options);
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Returns the sum of `field` across every record matching `where` (all
|
|
612
|
+
* records if `where` is empty), or `null` if no record matches.
|
|
613
|
+
*/
|
|
614
|
+
async sum(field, where, options) {
|
|
615
|
+
return this.aggregate("sum", field, where, options);
|
|
616
|
+
}
|
|
617
|
+
/** Same as {@link VSRepoPrisma7Adapter.sum}, but the arithmetic mean instead of the total. */
|
|
618
|
+
async average(field, where, options) {
|
|
619
|
+
return this.aggregate("avg", field, where, options);
|
|
620
|
+
}
|
|
621
|
+
/** Same as {@link VSRepoPrisma7Adapter.sum}, but the minimum value instead of the total. */
|
|
622
|
+
async min(field, where, options) {
|
|
623
|
+
return this.aggregate("min", field, where, options);
|
|
624
|
+
}
|
|
625
|
+
/** Same as {@link VSRepoPrisma7Adapter.sum}, but the maximum value instead of the total. */
|
|
626
|
+
async max(field, where, options) {
|
|
627
|
+
return this.aggregate("max", field, where, options);
|
|
628
|
+
}
|
|
512
629
|
}
|
|
513
630
|
exports.VSRepoPrisma7Adapter = VSRepoPrisma7Adapter;
|
|
@@ -2,6 +2,12 @@ import { PrismaArgLike } from "./prisma-arg-like.type";
|
|
|
2
2
|
type AnyFn = (arg: PrismaArgLike) => Promise<any>;
|
|
3
3
|
/** `count` do Prisma resolve pra um `number` (na forma simples, sem `select` de agregação). */
|
|
4
4
|
type CountFn = (arg: PrismaArgLike) => Promise<number>;
|
|
5
|
+
/**
|
|
6
|
+
* `aggregate` do Prisma resolve pra um objeto com uma chave por operação
|
|
7
|
+
* pedida (`_sum`/`_avg`/`_min`/`_max`/`_count`), cada uma mapeando campo ->
|
|
8
|
+
* valor agregado (`number | bigint | Decimal | null`).
|
|
9
|
+
*/
|
|
10
|
+
type AggregateFn = (arg: PrismaArgLike & Record<string, Record<string, boolean>>) => Promise<Record<string, Record<string, unknown> | undefined>>;
|
|
5
11
|
export type PrismaRepositoryLike = {
|
|
6
12
|
findFirst: AnyFn;
|
|
7
13
|
findFirstOrThrow: AnyFn;
|
|
@@ -16,5 +22,6 @@ export type PrismaRepositoryLike = {
|
|
|
16
22
|
delete: AnyFn;
|
|
17
23
|
deleteMany: AnyFn;
|
|
18
24
|
count: CountFn;
|
|
25
|
+
aggregate: AggregateFn;
|
|
19
26
|
};
|
|
20
27
|
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vsrepo/prisma7-adapter",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "VSRepository adapter implementation backed by Prisma 7, translating every VSRepository operation into Prisma Client calls.",
|
|
5
5
|
"homepage": "https://github.com/jaobrabo123/VSRepoPrisma7Adapter#readme",
|
|
6
6
|
"repository": {
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"license": "MIT",
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"@prisma/client": "^7.10.0",
|
|
52
|
-
"vsrepo": "^2.
|
|
52
|
+
"vsrepo": "^2.1.0"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"deepmerge": "^4.3.1",
|