@vsrepo/prisma7-adapter 1.3.2 → 2.0.0-dev.1

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.
Files changed (79) hide show
  1. package/CHANGELOG.md +535 -0
  2. package/LICENSE +20 -20
  3. package/README.md +394 -299
  4. package/README.pt-BR.md +394 -299
  5. package/dist/constants/provider-capabilities.constant.d.ts +17 -0
  6. package/dist/constants/provider-capabilities.constant.js +27 -0
  7. package/dist/index.d.ts +9 -8
  8. package/dist/index.js +1 -7
  9. package/dist/parsers/data.parser.d.ts +3 -33
  10. package/dist/parsers/data.parser.js +70 -69
  11. package/dist/parsers/include.parser.d.ts +1 -1
  12. package/dist/parsers/include.parser.js +3 -7
  13. package/dist/parsers/order-by.parser.d.ts +1 -10
  14. package/dist/parsers/order-by.parser.js +3 -16
  15. package/dist/parsers/select.parser.d.ts +1 -1
  16. package/dist/parsers/select.parser.js +3 -7
  17. package/dist/parsers/where.parser.d.ts +4 -29
  18. package/dist/parsers/where.parser.js +49 -148
  19. package/dist/prisma7.adapter.d.ts +116 -81
  20. package/dist/prisma7.adapter.js +345 -362
  21. package/dist/resolvers/map-prisma-error.resolver.d.ts +0 -11
  22. package/dist/resolvers/map-prisma-error.resolver.js +48 -72
  23. package/dist/resolvers/merge-entities.resolver.d.ts +11 -15
  24. package/dist/resolvers/merge-entities.resolver.js +29 -38
  25. package/dist/resolvers/resolve-provider.resolver.d.ts +2 -22
  26. package/dist/resolvers/resolve-provider.resolver.js +10 -33
  27. package/dist/types/adapter-config.type.d.ts +21 -10
  28. package/dist/types/adapter-config.type.js +1 -3
  29. package/dist/types/adapter-relations.type.d.ts +14 -8
  30. package/dist/types/adapter-relations.type.js +1 -3
  31. package/dist/types/plain-object.type.js +1 -3
  32. package/dist/types/prisma-arg-like.type.js +1 -3
  33. package/dist/types/prisma-client-models.type.d.ts +4 -4
  34. package/dist/types/prisma-client-models.type.js +1 -3
  35. package/dist/types/prisma-provider.type.d.ts +1 -1
  36. package/dist/types/prisma-provider.type.js +1 -3
  37. package/dist/types/prisma-repository-like.type.d.ts +1 -1
  38. package/dist/types/prisma-repository-like.type.js +1 -3
  39. package/dist/types/prisma7-client-like.type.d.ts +1 -8
  40. package/dist/types/prisma7-client-like.type.js +1 -3
  41. package/dist/types/prisma7-global-config.type.d.ts +17 -0
  42. package/dist/types/prisma7-global-config.type.js +1 -0
  43. package/dist/types/prisma7-orm-types.type.d.ts +2 -2
  44. package/dist/types/prisma7-orm-types.type.js +1 -3
  45. package/dist/types/relation.type.d.ts +119 -25
  46. package/dist/types/relation.type.js +1 -3
  47. package/dist/validators/is-decimal.validator.d.ts +2 -5
  48. package/dist/validators/is-decimal.validator.js +3 -6
  49. package/dist/validators/is-plain-object.validator.d.ts +1 -1
  50. package/dist/validators/is-plain-object.validator.js +3 -7
  51. package/dist/validators/validate-prisma-client.validator.d.ts +1 -14
  52. package/dist/validators/validate-prisma-client.validator.js +7 -24
  53. package/package.json +108 -91
  54. package/dist/index.js.map +0 -1
  55. package/dist/parsers/data.parser.js.map +0 -1
  56. package/dist/parsers/include.parser.js.map +0 -1
  57. package/dist/parsers/order-by.parser.js.map +0 -1
  58. package/dist/parsers/select.parser.js.map +0 -1
  59. package/dist/parsers/where.parser.js.map +0 -1
  60. package/dist/prisma7.adapter.js.map +0 -1
  61. package/dist/resolvers/map-prisma-error.resolver.js.map +0 -1
  62. package/dist/resolvers/merge-entities.resolver.js.map +0 -1
  63. package/dist/resolvers/resolve-provider.resolver.js.map +0 -1
  64. package/dist/types/adapter-config.type.js.map +0 -1
  65. package/dist/types/adapter-relations.type.js.map +0 -1
  66. package/dist/types/plain-object.type.js.map +0 -1
  67. package/dist/types/prisma-arg-like.type.js.map +0 -1
  68. package/dist/types/prisma-client-models.type.js.map +0 -1
  69. package/dist/types/prisma-provider.type.js.map +0 -1
  70. package/dist/types/prisma-repository-like.type.js.map +0 -1
  71. package/dist/types/prisma7-client-like.type.js.map +0 -1
  72. package/dist/types/prisma7-orm-types.type.js.map +0 -1
  73. package/dist/types/relation.type.js.map +0 -1
  74. package/dist/validators/is-decimal.validator.js.map +0 -1
  75. package/dist/validators/is-plain-object.validator.js.map +0 -1
  76. package/dist/validators/validate-adapter-config.validator.d.ts +0 -8
  77. package/dist/validators/validate-adapter-config.validator.js +0 -78
  78. package/dist/validators/validate-adapter-config.validator.js.map +0 -1
  79. package/dist/validators/validate-prisma-client.validator.js.map +0 -1
@@ -1,71 +1,27 @@
1
- "use strict";
2
- /**
3
- * Parser que converte um `VSRepoWhere<T>` (formato "amigável" da aplicação)
4
- * em um `where` válido de qualquer modelo do Prisma.
5
- *
6
- * Suporta:
7
- * - Valor direto: { name: "Ana" }
8
- * - Operadores de campo: { age: { gte: 18, lte: 65 } }
9
- * - `between`: { age: { between: [18, 65] } } -> { gte: 18, lte: 65 }
10
- * - `not` (valor ou operador): { name: { not: "Ana" } }
11
- * { name: { not: { contains: "an" } } }
12
- * - Strings case-insensitive: { name: { contains: "ana", ignoreCase: true } }
13
- * -> { contains: "ana", mode: "insensitive" }
14
- * - Relação lista (array): { posts: { _some: { title: "x" } } } -> { posts: { some: {...} } }
15
- * - Relação objeto (to-one): { author: { _with: { id: 1 } } } -> { author: { is: {...} } }
16
- * { author: { _without: { id: 1 } } } -> { author: { isNot: {...} } }
17
- * - Lógicos no nível raiz: { AND: [...] , OR: [...], NOT: {...} }
18
- *
19
- * Reflete a tipagem atual: `AND`/`OR`/`NOT` só existem em `VSRepoWhere<T>`
20
- * (nível raiz). Dentro de relações (`_some`/`_every`/`_none`/`_with`/
21
- * `_without`), o tipo usado é `VSRepoWherePlain<U>`, que NÃO tem esses
22
- * operadores lógicos — por isso a recursão para relações usa
23
- * `parsePlainWhere`, e não `parseWhere`.
24
- */
25
- Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.parsePrismaWhere = parsePrismaWhere;
27
- const is_decimal_validator_1 = require("../validators/is-decimal.validator");
28
- const is_plain_object_validator_1 = require("../validators/is-plain-object.validator");
29
- /** Chaves reconhecidas como operadores de campo do VSRepoFieldOperators */
30
- const FIELD_OPERATOR_KEYS = new Set([
31
- "equals",
32
- "not",
33
- "in",
34
- "notIn",
35
- "gt",
36
- "gte",
37
- "lt",
38
- "lte",
39
- "between",
40
- "contains",
41
- "startsWith",
42
- "endsWith",
43
- "ignoreCase",
44
- ]);
1
+ import { AdapterErrorCode, VSRepoAdapterError } from "vsrepo";
2
+ import { INSENSITIVE_MODE_PROVIDERS } from "../constants/provider-capabilities.constant.js";
3
+ import { isPlainObject } from "../validators/is-plain-object.validator.js";
45
4
  const LOGICAL_KEYS = new Set(["AND", "OR", "NOT"]);
46
- /** Verifica se um objeto "parece" um VSRepoFieldOperators (e não um filtro de relação/nested where) */
47
- function isFieldOperatorObject(value) {
48
- return Object.keys(value).some(key => FIELD_OPERATOR_KEYS.has(key));
49
- }
50
- function isArrayRelationFilter(value) {
51
- return "_some" in value || "_every" in value || "_none" in value;
52
- }
53
- function isObjectRelationFilter(value) {
54
- return "_with" in value || "_without" in value;
55
- }
56
- /**
57
- * Converte um VSRepoFieldOperators<V> em um filtro de campo do Prisma.
58
- */
59
- function parseFieldOperators(value) {
5
+ function parseFieldValue(value, provider) {
6
+ if (!isPlainObject(value)) {
7
+ return value;
8
+ }
60
9
  const result = {};
61
- const ignoreCase = value.ignoreCase === true;
62
10
  for (const [key, val] of Object.entries(value)) {
63
11
  if (val === undefined)
64
12
  continue;
65
13
  switch (key) {
66
- case "ignoreCase":
67
- // tratado à parte, no final (vira `mode`)
14
+ case "ignoreCase": {
15
+ if (val !== true)
16
+ break;
17
+ if (provider && !INSENSITIVE_MODE_PROVIDERS.has(provider)) {
18
+ throw new VSRepoAdapterError(`The 'ignoreCase' option is not supported by the '${provider}' provider, since Prisma only ` +
19
+ `supports case-insensitive filtering on PostgreSQL and CockroachDB. ` +
20
+ `Remove 'ignoreCase' to filter using the database's own collation rules.`, AdapterErrorCode.NOT_SUPPORTED, null);
21
+ }
22
+ result.mode = "insensitive";
68
23
  break;
24
+ }
69
25
  case "between": {
70
26
  const [min, max] = val;
71
27
  if (min !== undefined)
@@ -75,111 +31,56 @@ function parseFieldOperators(value) {
75
31
  break;
76
32
  }
77
33
  case "not": {
78
- result.not =
79
- (0, is_plain_object_validator_1.isPlainObject)(val) && isFieldOperatorObject(val)
80
- ? parseFieldOperators(val)
81
- : val;
34
+ result.not = isPlainObject(val) ? parseFieldValue(val, provider) : val;
35
+ break;
36
+ }
37
+ case "_some": {
38
+ result.some = parsePrismaWhere(value._some, provider);
39
+ break;
40
+ }
41
+ case "_every": {
42
+ result.every = parsePrismaWhere(value._every, provider);
82
43
  break;
83
44
  }
45
+ case "_none": {
46
+ result.none = parsePrismaWhere(value._none, provider);
47
+ break;
48
+ }
49
+ case "_with": {
50
+ result.is = parsePrismaWhere(value._with, provider);
51
+ break;
52
+ }
53
+ case "_without": {
54
+ result.isNot = parsePrismaWhere(value._without, provider);
55
+ break;
56
+ }
57
+ case "like": {
58
+ throw new VSRepoAdapterError(`The 'like' operator is not supported by the Prisma adapter, since Prisma has no equivalent. ` +
59
+ `Use 'contains', 'startsWith' or 'endsWith' instead.`, AdapterErrorCode.NOT_SUPPORTED, null);
60
+ }
84
61
  default:
85
62
  result[key] = val;
86
63
  }
87
64
  }
88
- if (ignoreCase) {
89
- // * Simplismente aplica o "insensitive" se o ignoreCase for true, se for em um campo inválido o proprio Prisma lança erro
90
- result.mode = "insensitive";
91
- }
92
- return result;
93
- }
94
- /** Converte { _some, _every, _none } em { some, every, none } (VSRepoWherePlain — sem AND/OR/NOT) */
95
- function parseArrayRelationFilter(value) {
96
- const result = {};
97
- if (value._some !== undefined) {
98
- result.some = parsePlainWhere(value._some);
99
- }
100
- if (value._every !== undefined) {
101
- result.every = parsePlainWhere(value._every);
102
- }
103
- if (value._none !== undefined) {
104
- result.none = parsePlainWhere(value._none);
105
- }
106
65
  return result;
107
66
  }
108
- /** Converte { _with, _without } em { is, isNot } (VSRepoWherePlain — sem AND/OR/NOT) */
109
- function parseObjectRelationFilter(value) {
110
- const result = {};
111
- if (value._with !== undefined) {
112
- result.is = parsePlainWhere(value._with);
113
- }
114
- if (value._without !== undefined) {
115
- result.isNot = parsePlainWhere(value._without);
116
- }
117
- return result;
118
- }
119
- /** Decide como interpretar o valor de um campo do where */
120
- function parseFieldValue(value) {
121
- // valores primitivos (string, number, boolean, Date, null, bigint, Decimal) passam direto
122
- if (value === null || typeof value !== "object" || value instanceof Date || (0, is_decimal_validator_1.isDecimal)(value)) {
123
- return value;
124
- }
125
- // arrays (usados em `in`/`notIn` no nível mais alto, ex: { status: ["A","B"] })
126
- if (Array.isArray(value)) {
127
- return value;
128
- }
129
- const obj = value;
130
- if (isArrayRelationFilter(obj)) {
131
- return parseArrayRelationFilter(obj);
132
- }
133
- if (isObjectRelationFilter(obj)) {
134
- return parseObjectRelationFilter(obj);
135
- }
136
- if (isFieldOperatorObject(obj)) {
137
- return parseFieldOperators(obj);
138
- }
139
- // fallback: nested where (não deveria ocorrer para campos primitivos bem tipados)
140
- return parsePlainWhere(obj);
141
- }
142
67
  /**
143
- * Converte um `VSRepoWherePlain<T>` (sem AND/OR/NOT) — usado para o corpo de
144
- * relações (`_some`/`_every`/`_none`/`_with`/`_without`).
68
+ * Converts a `VSRepoWhere` into a Prisma `where`.
145
69
  */
146
- function parsePlainWhere(where) {
147
- if (where === undefined || where === null)
148
- return undefined;
149
- const result = {};
150
- for (const [key, value] of Object.entries(where)) {
151
- if (value === undefined)
152
- continue;
153
- result[key] = parseFieldValue(value);
154
- }
155
- return result;
156
- }
157
- /**
158
- * Converte um `VSRepoWhere<T>` completo (nível raiz, com AND/OR/NOT) em um
159
- * where do Prisma.
160
- */
161
- function parseWhere(where) {
162
- if (where === undefined || where === null)
70
+ export function parsePrismaWhere(where, provider) {
71
+ if (where === undefined)
163
72
  return undefined;
164
73
  const result = {};
165
74
  for (const [key, value] of Object.entries(where)) {
166
75
  if (value === undefined)
167
76
  continue;
168
77
  if (LOGICAL_KEYS.has(key)) {
169
- result[key] = Array.isArray(value) ? value.map(v => parseWhere(v)) : parseWhere(value);
78
+ result[key] = Array.isArray(value)
79
+ ? value.map(v => parsePrismaWhere(v, provider))
80
+ : parsePrismaWhere(value, provider);
170
81
  continue;
171
82
  }
172
- result[key] = parseFieldValue(value);
83
+ result[key] = parseFieldValue(value, provider);
173
84
  }
174
85
  return result;
175
86
  }
176
- /**
177
- * Use o segundo generic para tipar o retorno com o `WhereInput`
178
- * do Prisma correspondente ao modelo, ex:
179
- *
180
- * parseVSRepoWhere<User, Prisma.UserWhereInput>(where)
181
- */
182
- function parsePrismaWhere(where) {
183
- return parseWhere(where);
184
- }
185
- //# sourceMappingURL=where.parser.js.map
@@ -1,18 +1,9 @@
1
- import { AdapterMethodOptions, AdapterQueryOptions, CountResult, DeepPartial, NumericKeys, VSRepoAdapter, VSRepoTransactionOptions, VSRepoWhere } from "vsrepo";
2
- import { VSRepoPrisma7AdapterConfig } from "./types/adapter-config.type";
3
- import { Prisma7ClientLike } from "./types/prisma7-client-like.type";
1
+ import { AdapterMethodOptions, AdapterQueryOptions, CountResult, DeepPartial, NumericKeys, RestrictAdapterMethodOptions, SimpleAdapterMethodOptions, VSRepoAdapter, VSRepoTransactionOptions, VSRepoWhere, WithIgnoreConflicts } from "vsrepo";
2
+ import { Prisma7AdapterConfig } from "./types/adapter-config.type.js";
3
+ import { Prisma7ClientLike } from "./types/prisma7-client-like.type.js";
4
+ import { Prisma7GlobalConfig } from "./types/prisma7-global-config.type.js";
4
5
  /**
5
- * `VSRepoAdapter` implementation for Prisma 7. Translates every method of the
6
- * adapter contract into Prisma Client calls, resolving `VSRepoWhere`/`Ordering`/
7
- * `select`/`include` through the parsers, and — when a
8
- * `relations` config is provided — resolving relation fields on `create`/
9
- * `update`/`upsert`/`merge` the same way the v1 of VSRepository did (see
10
- * `Relation`).
11
- *
12
- * Every method always rejects with a `VSRepoAdapterError` — any error raised
13
- * by Prisma (or by the adapter itself) is translated through `mapPrismaError`
14
- * before leaving the adapter, so callers never have to deal with a raw
15
- * Prisma/driver error shape.
6
+ * `VSRepoAdapter` implementation for Prisma 7.
16
7
  *
17
8
  * @template T Entity type this adapter operates on.
18
9
  *
@@ -20,15 +11,36 @@ import { Prisma7ClientLike } from "./types/prisma7-client-like.type";
20
11
  */
21
12
  export declare class VSRepoPrisma7Adapter<T, K extends Prisma7ClientLike = Prisma7ClientLike> extends VSRepoAdapter<T> {
22
13
  private readonly prisma;
23
- private readonly tableName;
14
+ private readonly modelName;
24
15
  private readonly pkName;
25
16
  private readonly relations?;
26
17
  private readonly logger;
27
18
  private readonly provider;
28
- constructor(prisma: K, config: VSRepoPrisma7AdapterConfig<T, K>);
19
+ /** Whether the primary key may be dropped from a write payload when Prisma can't take it. */
20
+ private readonly allowOmitPk?;
21
+ private static globalConfig;
22
+ constructor(prisma: K, config: Prisma7AdapterConfig<T, K>);
23
+ /**
24
+ * Sets defaults (`provider`, `logLevel`, `allowOmitPk`) for every adapter
25
+ * created **after** this call. It replaces the previous global config, and
26
+ * the config passed to each adapter's constructor takes precedence.
27
+ */
28
+ static setGlobalConfig(globalConfig: Prisma7GlobalConfig): void;
29
29
  private getPrismaRepository;
30
30
  /** Resolves the "read" part of a Prisma arg: select/include/orderBy/pagination. */
31
31
  private resolveReadArg;
32
+ /** Parses a `where` for this adapter's provider (rejecting what the provider cannot run). */
33
+ private parseWhere;
34
+ /**
35
+ * `createManyReturning` and `updateManyReturning` rely on Prisma's `createManyAndReturn` /
36
+ * `updateManyAndReturn`, which only exist on PostgreSQL, CockroachDB and SQLite.
37
+ */
38
+ private assertReturningManySupported;
39
+ /**
40
+ * `ignoreConflicts` is translated to Prisma's `skipDuplicates`, which isn't available on
41
+ * SQL Server and SQLite. Rejects with `NOT_SUPPORTED` instead of leaving it to Prisma.
42
+ */
43
+ private assertIgnoreConflictsSupported;
32
44
  /**
33
45
  * Strips relation fields from a payload — used by `createMany`/`updateMany`/
34
46
  * `updateManyReturning`, since those Prisma operations don't support nested
@@ -58,13 +70,14 @@ export declare class VSRepoPrisma7Adapter<T, K extends Prisma7ClientLike = Prism
58
70
  * evaluated server-side against the row's current value, never as a
59
71
  * client-side read-modify-write. `value` is passed through as-is:
60
72
  * Prisma accepts a `number`, `bigint`, or any `Decimal`/`DecimalJsLike`
61
- * value (which covers a {@link DecimalLike} like `Prisma.Decimal`)
73
+ * value (which covers a `DecimalLike` like `Prisma.Decimal`)
62
74
  * depending on the target column's type.
63
75
  *
64
76
  * Prisma's `update()` already returns the row reflecting the state
65
77
  * *after* the write, so no follow-up read is needed here.
66
78
  */
67
79
  private atomicUpdate;
80
+ private atomicUpdateMany;
68
81
  /**
69
82
  * Converts a raw value returned by Prisma's `aggregate()` (`number`,
70
83
  * `bigint`, a `Decimal` instance, or `null` when no record matches)
@@ -85,108 +98,130 @@ export declare class VSRepoPrisma7Adapter<T, K extends Prisma7ClientLike = Prism
85
98
  getDbClient(): any;
86
99
  /** Runs `fn` inside a native transaction of the underlying ORM/database. */
87
100
  runInTransaction<R>(fn: (tx: any) => Promise<R>, options?: VSRepoTransactionOptions): Promise<R>;
101
+ private execMethod;
102
+ /** Runs `parsePrismaWriteData` with this adapter's `pkName`, `relations` and `allowOmitPk`. */
103
+ private parseData;
88
104
  /** Fetches a single record matching `where`. */
89
- findOne(where: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<T | null>;
105
+ findOne(where?: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<T | null>;
90
106
  /** Fetches a single record matching `where`, throwing if none is found. */
91
- findOneOrThrow(where: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<T>;
107
+ findOneOrThrow(where?: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<T>;
92
108
  /** Fetches all records matching `where`. */
93
- findMany(where: VSRepoWhere<T>, options?: AdapterMethodOptions<T> & {
94
- distinct?: (keyof T)[];
95
- }): Promise<T[]>;
109
+ findMany(where?: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<T[]>;
96
110
  /** Creates or updates (upsert) a single record. */
97
- save(obj: DeepPartial<T>, options?: AdapterMethodOptions<T>): Promise<T>;
111
+ save(obj: DeepPartial<T>, options?: SimpleAdapterMethodOptions<T>): Promise<T>;
98
112
  /**
99
113
  * Creates or updates (upsert) multiple records. Prisma has no native bulk
100
114
  * upsert, so each record is saved individually inside a transaction —
101
- * reusing `options.db` when it's already a transaction client (see
102
- * `runTransactional`).
115
+ * reusing `options.db` when it's already a transaction client.
103
116
  */
104
- saveMany(objs: DeepPartial<T>[], options?: AdapterMethodOptions<T>): Promise<T[]>;
117
+ saveMany(objs: DeepPartial<T>[], options?: SimpleAdapterMethodOptions<T>): Promise<T[]>;
105
118
  /** Deletes a single record matching `where`. */
106
- delete(where: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<T>;
119
+ delete(where: VSRepoWhere<T>, options?: SimpleAdapterMethodOptions<T>): Promise<T>;
107
120
  /** Deletes every record matching `where`, returning the count of affected rows. */
108
- deleteMany(where: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<CountResult>;
121
+ deleteMany(where: VSRepoWhere<T>, options?: RestrictAdapterMethodOptions<T>): Promise<CountResult>;
109
122
  /**
110
- * Deletes every record matching `where`, returning the deleted records.
123
+ * Deletes every record matching `where` and returns the deleted records.
111
124
  *
112
- * Prisma has no `deleteManyAndReturn`, so this does a `findMany` on
113
- * `where` first and then re-applies the same `where` to a `deleteMany`,
114
- * both inside a transaction (`runTransactional`).
125
+ * In the absence of a native `deleteManyAndReturn`, this fetches matching records
126
+ * via `findMany` first, extracts their primary keys, and then deletes them by ID
127
+ * using `{ [pkName]: { in: pks } }` inside a transaction.
115
128
  *
116
- * Because the delete is driven by the same `where` (not by the fetched
117
- * records), a concurrent change between the two operations can make them
118
- * diverge — e.g. a row inserted after the `findMany` matching the `where`
119
- * would still be deleted, while a row changed to stop matching wouldn't.
120
- * If you need to guarantee no concurrency issues, run this method inside a
121
- * `repository.transaction()` with a higher isolation level, e.g.
122
- * `TransactionIsolationLevel.SERIALIZABLE`.
123
- */
124
- deleteManyReturning(where: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<T[]>;
129
+ * Key behaviors:
130
+ * - **Primary Key Handling:** If `options.select` omits the primary key, it is
131
+ * temporarily added to the query so the subsequent batch delete can target
132
+ * those exact IDs, and stripped from the returned objects afterward.
133
+ * - **Concurrency & Isolation:** Deleting strictly by the fetched IDs ensures only
134
+ * the exact returned rows are removed (avoiding deleting newly inserted rows that
135
+ * match `where`). However, if a row is modified or deleted concurrently between
136
+ * the read and the delete step, race conditions can still occur unless wrapped
137
+ * in a transaction with an appropriate isolation level (e.g., `SERIALIZABLE`).
138
+ */
139
+ deleteManyReturning(where: VSRepoWhere<T>, options?: SimpleAdapterMethodOptions<T>): Promise<T[]>;
125
140
  /** Updates a single record matching `where`. */
126
- update(where: VSRepoWhere<T>, obj: DeepPartial<T>, options?: AdapterMethodOptions<T>): Promise<T>;
141
+ update(where: VSRepoWhere<T>, obj: DeepPartial<T>, options?: SimpleAdapterMethodOptions<T>): Promise<T>;
127
142
  /** Updates every record matching `where`, returning the count of affected rows. */
128
- updateMany(where: VSRepoWhere<T>, obj: DeepPartial<T>, options?: AdapterMethodOptions<T>): Promise<CountResult>;
129
- /** Updates every record matching `where`, returning the updated records. */
130
- updateManyReturning(where: VSRepoWhere<T>, obj: DeepPartial<T>, options?: AdapterMethodOptions<T>): Promise<T[]>;
143
+ updateMany(where: VSRepoWhere<T>, obj: DeepPartial<T>, options?: RestrictAdapterMethodOptions<T>): Promise<CountResult>;
144
+ /**
145
+ * Updates every record matching `where`, returning the updated records.
146
+ *
147
+ * Rejects with `NOT_SUPPORTED` on providers without `updateManyAndReturn` (MySQL and SQL Server).
148
+ */
149
+ updateManyReturning(where: VSRepoWhere<T>, obj: DeepPartial<T>, options?: SimpleAdapterMethodOptions<T>): Promise<T[]>;
131
150
  /** Returns the number of records matching `where`. */
132
- count(where: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<number>;
151
+ count(where?: VSRepoWhere<T>, options?: RestrictAdapterMethodOptions<T>): Promise<number>;
133
152
  /** Checks whether at least one record matching `where` exists. */
134
- exists(where: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<boolean>;
135
- /** Executes a raw query/statement against the underlying database, used by `@QueryMethod`. */
153
+ exists(where?: VSRepoWhere<T>, options?: RestrictAdapterMethodOptions<T>): Promise<boolean>;
154
+ /** Executes a raw query/statement against the underlying database. */
136
155
  query<R = any>(query: string, options?: AdapterQueryOptions): Promise<R>;
137
156
  /** Creates a single record. */
138
- create(obj: DeepPartial<T>, options?: AdapterMethodOptions<T>): Promise<T>;
157
+ create(obj: DeepPartial<T>, options?: SimpleAdapterMethodOptions<T>): Promise<T>;
139
158
  /**
140
- * Creates multiple records in a single operation. Relation fields are
141
- * stripped (see `stripRelationFields`), since Prisma's `createMany` doesn't
142
- * support nested writes.
159
+ * Creates multiple records in a single operation.
160
+ *
161
+ * Rejects with `NOT_SUPPORTED` when `ignoreConflicts` is used on a provider without
162
+ * `skipDuplicates` (SQL Server and SQLite).
143
163
  */
144
- createMany(objs: DeepPartial<T>[], options?: AdapterMethodOptions<T> & {
145
- ignoreConflicts?: boolean;
146
- }): Promise<CountResult>;
164
+ createMany(objs: DeepPartial<T>[], options?: WithIgnoreConflicts<RestrictAdapterMethodOptions<T>>): Promise<CountResult>;
147
165
  /**
148
166
  * Creates multiple records in a single operation, returning the created records.
167
+ *
168
+ * Rejects with `NOT_SUPPORTED` on providers without `createManyAndReturn` (MySQL and SQL Server),
169
+ * and when `ignoreConflicts` is used on a provider without `skipDuplicates` (SQL Server and SQLite).
149
170
  */
150
- createManyReturning(objs: DeepPartial<T>[], options?: AdapterMethodOptions<T> & {
151
- ignoreConflicts?: boolean;
152
- }): Promise<T[]>;
153
- /**
154
- * Fetches the record matching `where` and returns it deep-merged with
155
- * `obj`, WITHOUT persisting anything — same behavior the v1 of
156
- * VSRepository had (see `mergeEntities`). It's on the caller to decide
157
- * what to do with the result (e.g. call `save` next).
158
- */
159
- merge<K extends DeepPartial<T>>(where: VSRepoWhere<T>, obj: K, options?: AdapterMethodOptions<T>): Promise<(K & T) | null>;
171
+ createManyReturning(objs: DeepPartial<T>[], options?: WithIgnoreConflicts<SimpleAdapterMethodOptions<T>>): Promise<T[]>;
160
172
  /** Creates a record if none matches `where`, otherwise updates it. */
161
- upsert(where: VSRepoWhere<T>, create: DeepPartial<T>, update: DeepPartial<T>, options?: AdapterMethodOptions<T>): Promise<T>;
173
+ upsert(where: VSRepoWhere<T>, create: DeepPartial<T>, update: DeepPartial<T>, options?: SimpleAdapterMethodOptions<T>): Promise<T>;
162
174
  /**
163
175
  * Atomically adds `value` to `field` on the record matching `where`,
164
176
  * via Prisma's native `{ field: { increment: value } }` write.
165
177
  */
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>;
178
+ incrementOne<K extends NumericKeys<T>>(field: K, value: NonNullable<T[K]>, where: VSRepoWhere<T>, options?: SimpleAdapterMethodOptions<T>): Promise<T>;
179
+ /**
180
+ * Atomically subtracts `value` to `field` on the record matching `where`,
181
+ * via Prisma's native `{ field: { decrement: value } }` write.
182
+ */
183
+ decrementOne<K extends NumericKeys<T>>(field: K, value: NonNullable<T[K]>, where: VSRepoWhere<T>, options?: SimpleAdapterMethodOptions<T>): Promise<T>;
184
+ /**
185
+ * Atomically multiplies `value` to `field` on the record matching `where`,
186
+ * via Prisma's native `{ field: { multiply: value } }` write.
187
+ */
188
+ multiplyOne<K extends NumericKeys<T>>(field: K, value: NonNullable<T[K]>, where: VSRepoWhere<T>, options?: SimpleAdapterMethodOptions<T>): Promise<T>;
189
+ /**
190
+ * Atomically divides `value` to `field` on the record matching `where`,
191
+ * via Prisma's native `{ field: { divide: value } }` write.
192
+ */
193
+ divideOne<K extends NumericKeys<T>>(field: K, value: NonNullable<T[K]>, where: VSRepoWhere<T>, options?: SimpleAdapterMethodOptions<T>): Promise<T>;
194
+ /**
195
+ * Atomically adds `value` to `field` on every record matching `where`,
196
+ * via Prisma's native `{ field: { increment: value } }` write.
197
+ */
198
+ incrementMany<K extends NumericKeys<T>>(field: K, value: NonNullable<T[K]>, where: VSRepoWhere<T>, options?: RestrictAdapterMethodOptions<T>): Promise<CountResult>;
199
+ /**
200
+ * Atomically subtracts `value` from `field` on every record matching `where`,
201
+ * via Prisma's native `{ field: { decrement: value } }` write.
202
+ */
203
+ decrementMany<K extends NumericKeys<T>>(field: K, value: NonNullable<T[K]>, where: VSRepoWhere<T>, options?: RestrictAdapterMethodOptions<T>): Promise<CountResult>;
204
+ /**
205
+ * Atomically multiplies `field` by `value` on every record matching `where`,
206
+ * via Prisma's native `{ field: { multiply: value } }` write.
207
+ */
208
+ multiplyMany<K extends NumericKeys<T>>(field: K, value: NonNullable<T[K]>, where: VSRepoWhere<T>, options?: RestrictAdapterMethodOptions<T>): Promise<CountResult>;
171
209
  /**
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).
210
+ * Atomically divides `field` by `value` on every record matching `where`,
211
+ * via Prisma's native `{ field: { divide: value } }` write.
177
212
  */
178
- divideOne<K extends NumericKeys<T>>(field: K, value: NonNullable<T[K]>, where: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<T>;
213
+ divideMany<K extends NumericKeys<T>>(field: K, value: NonNullable<T[K]>, where: VSRepoWhere<T>, options?: RestrictAdapterMethodOptions<T>): Promise<CountResult>;
179
214
  /**
180
215
  * Returns the sum of `field` across every record matching `where` (all
181
216
  * records if `where` is empty), or `null` if no record matches.
182
217
  */
183
- sum(field: NumericKeys<T>, where: VSRepoWhere<T>, options?: AdapterMethodOptions<T>): Promise<number | null>;
218
+ sum(field: NumericKeys<T>, where?: VSRepoWhere<T>, options?: RestrictAdapterMethodOptions<T>): Promise<number | null>;
184
219
  /** 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>;
220
+ average(field: NumericKeys<T>, where?: VSRepoWhere<T>, options?: RestrictAdapterMethodOptions<T>): Promise<number | null>;
186
221
  /** 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>;
222
+ min(field: NumericKeys<T>, where?: VSRepoWhere<T>, options?: RestrictAdapterMethodOptions<T>): Promise<number | null>;
188
223
  /** 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>;
224
+ max(field: NumericKeys<T>, where?: VSRepoWhere<T>, options?: RestrictAdapterMethodOptions<T>): Promise<number | null>;
190
225
  /**
191
226
  * Returns the model's primary key
192
227
  *