@vsrepo/prisma7-adapter 1.3.1 → 2.0.0-dev

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 (77) hide show
  1. package/CHANGELOG.md +417 -0
  2. package/LICENSE +20 -20
  3. package/README.md +303 -299
  4. package/README.pt-BR.md +303 -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 +8 -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 +7 -45
  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 +2 -10
  14. package/dist/parsers/order-by.parser.js +6 -19
  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 -28
  18. package/dist/parsers/where.parser.js +49 -151
  19. package/dist/prisma7.adapter.d.ts +104 -81
  20. package/dist/prisma7.adapter.js +329 -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 +7 -12
  28. package/dist/types/adapter-config.type.js +1 -3
  29. package/dist/types/adapter-relations.type.d.ts +2 -2
  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-orm-types.type.d.ts +2 -2
  42. package/dist/types/prisma7-orm-types.type.js +1 -3
  43. package/dist/types/relation.type.d.ts +25 -19
  44. package/dist/types/relation.type.js +1 -3
  45. package/dist/validators/is-decimal.validator.d.ts +2 -5
  46. package/dist/validators/is-decimal.validator.js +3 -6
  47. package/dist/validators/is-plain-object.validator.d.ts +1 -1
  48. package/dist/validators/is-plain-object.validator.js +3 -7
  49. package/dist/validators/validate-prisma-client.validator.d.ts +1 -14
  50. package/dist/validators/validate-prisma-client.validator.js +7 -24
  51. package/package.json +108 -91
  52. package/dist/index.js.map +0 -1
  53. package/dist/parsers/data.parser.js.map +0 -1
  54. package/dist/parsers/include.parser.js.map +0 -1
  55. package/dist/parsers/order-by.parser.js.map +0 -1
  56. package/dist/parsers/select.parser.js.map +0 -1
  57. package/dist/parsers/where.parser.js.map +0 -1
  58. package/dist/prisma7.adapter.js.map +0 -1
  59. package/dist/resolvers/map-prisma-error.resolver.js.map +0 -1
  60. package/dist/resolvers/merge-entities.resolver.js.map +0 -1
  61. package/dist/resolvers/resolve-provider.resolver.js.map +0 -1
  62. package/dist/types/adapter-config.type.js.map +0 -1
  63. package/dist/types/adapter-relations.type.js.map +0 -1
  64. package/dist/types/plain-object.type.js.map +0 -1
  65. package/dist/types/prisma-arg-like.type.js.map +0 -1
  66. package/dist/types/prisma-client-models.type.js.map +0 -1
  67. package/dist/types/prisma-provider.type.js.map +0 -1
  68. package/dist/types/prisma-repository-like.type.js.map +0 -1
  69. package/dist/types/prisma7-client-like.type.js.map +0 -1
  70. package/dist/types/prisma7-orm-types.type.js.map +0 -1
  71. package/dist/types/relation.type.js.map +0 -1
  72. package/dist/validators/is-decimal.validator.js.map +0 -1
  73. package/dist/validators/is-plain-object.validator.js.map +0 -1
  74. package/dist/validators/validate-adapter-config.validator.d.ts +0 -8
  75. package/dist/validators/validate-adapter-config.validator.js +0 -78
  76. package/dist/validators/validate-adapter-config.validator.js.map +0 -1
  77. package/dist/validators/validate-prisma-client.validator.js.map +0 -1
@@ -0,0 +1,17 @@
1
+ import { PrismaProvider } from "../types/prisma-provider.type.js";
2
+ /**
3
+ * Providers where Prisma accepts the `mode: "insensitive"` filter, which is
4
+ * what `ignoreCase` is translated to (see the README's provider support table).
5
+ */
6
+ export declare const INSENSITIVE_MODE_PROVIDERS: ReadonlySet<PrismaProvider>;
7
+ /**
8
+ * Providers that expose `createManyAndReturn` and `updateManyAndReturn`, which
9
+ * `createManyReturning` and `updateManyReturning` are built on.
10
+ */
11
+ export declare const RETURNING_MANY_PROVIDERS: ReadonlySet<PrismaProvider>;
12
+ /**
13
+ * Providers that support Prisma's `skipDuplicates` (`INSERT ... ON CONFLICT DO NOTHING`
14
+ * or equivalent), which is what `ignoreConflicts` is translated to on `createMany` and
15
+ * `createManyReturning`.
16
+ */
17
+ export declare const SKIP_DUPLICATES_PROVIDERS: ReadonlySet<PrismaProvider>;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Providers where Prisma accepts the `mode: "insensitive"` filter, which is
3
+ * what `ignoreCase` is translated to (see the README's provider support table).
4
+ */
5
+ export const INSENSITIVE_MODE_PROVIDERS = new Set([
6
+ "postgresql",
7
+ "cockroachdb",
8
+ ]);
9
+ /**
10
+ * Providers that expose `createManyAndReturn` and `updateManyAndReturn`, which
11
+ * `createManyReturning` and `updateManyReturning` are built on.
12
+ */
13
+ export const RETURNING_MANY_PROVIDERS = new Set([
14
+ "postgresql",
15
+ "cockroachdb",
16
+ "sqlite",
17
+ ]);
18
+ /**
19
+ * Providers that support Prisma's `skipDuplicates` (`INSERT ... ON CONFLICT DO NOTHING`
20
+ * or equivalent), which is what `ignoreConflicts` is translated to on `createMany` and
21
+ * `createManyReturning`.
22
+ */
23
+ export const SKIP_DUPLICATES_PROVIDERS = new Set([
24
+ "postgresql",
25
+ "mysql",
26
+ "cockroachdb",
27
+ ]);
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- export { VSRepoPrisma7Adapter, VSRepoPrisma7Adapter as Prisma7Adapter } from "./prisma7.adapter";
2
- export type { Relation } from "./types/relation.type";
3
- export type { Prisma7OrmTypes } from "./types/prisma7-orm-types.type";
4
- export type { Prisma7ClientLike } from "./types/prisma7-client-like.type";
5
- export type { AdapterRelations } from "./types/adapter-relations.type";
6
- export type { VSRepoPrisma7AdapterConfig } from "./types/adapter-config.type";
7
- export type { PrismaClientModels } from "./types/prisma-client-models.type";
8
- export type { PrismaProvider } from "./types/prisma-provider.type";
1
+ export { VSRepoPrisma7Adapter, VSRepoPrisma7Adapter as Prisma7Adapter } from "./prisma7.adapter.js";
2
+ export type { Relation } from "./types/relation.type.js";
3
+ export type { Prisma7OrmTypes } from "./types/prisma7-orm-types.type.js";
4
+ export type { Prisma7ClientLike } from "./types/prisma7-client-like.type.js";
5
+ export type { AdapterRelations } from "./types/adapter-relations.type.js";
6
+ export type { Prisma7AdapterConfig } from "./types/adapter-config.type.js";
7
+ export type { PrismaClientModels } from "./types/prisma-client-models.type.js";
8
+ export type { PrismaProvider } from "./types/prisma-provider.type.js";
package/dist/index.js CHANGED
@@ -1,7 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Prisma7Adapter = exports.VSRepoPrisma7Adapter = void 0;
4
- var prisma7_adapter_1 = require("./prisma7.adapter");
5
- Object.defineProperty(exports, "VSRepoPrisma7Adapter", { enumerable: true, get: function () { return prisma7_adapter_1.VSRepoPrisma7Adapter; } });
6
- Object.defineProperty(exports, "Prisma7Adapter", { enumerable: true, get: function () { return prisma7_adapter_1.VSRepoPrisma7Adapter; } });
7
- //# sourceMappingURL=index.js.map
1
+ export { VSRepoPrisma7Adapter, VSRepoPrisma7Adapter as Prisma7Adapter } from "./prisma7.adapter.js";
@@ -1,37 +1,7 @@
1
- /**
2
- * Parser que converte um `DeepPartial<T>` (formato "cru" vindo do vsrepo) nos
3
- * payloads `create`/`update` esperados pelo Prisma para escritas com relations,
4
- * replicando o comportamento da v1 (`resolveCreateUpdatePayloadsWithRelations`).
5
- *
6
- * Sem `relations` configurado no adapter, cada campo é repassado como está —
7
- * exceto `pkName`, que é omitido do `update` (não faz sentido reatribuir a PK
8
- * num update parcial).
9
- *
10
- * Com `relations`, cada campo de relação é resolvido de acordo com seu `mode`/
11
- * `restriction` (ver `Relation`):
12
- * - to-one (`oto`/`mto`) sem PK no valor enviado -> `create` (e `upsert` no
13
- * update, a não ser que `restriction: "add"`, que usa só `create`)
14
- * - to-one com PK no valor enviado -> `connectOrCreate` (e
15
- * `upsert` no update, a não ser que `restriction: "add"`)
16
- * - to-one enviado como `null` com `nullable` -> `delete` (`oto` +
17
- * `restriction: "set"`) ou `disconnect` (`oto` com `restriction: "add"` /
18
- * `mto`; um `oto` não "desconecta" no `update`, a linha possuída é apagada)
19
- * - to-one enviado como `null` sem `nullable` -> lança `VSRepoAdapterError`
20
- * (code `INVALID_DATA`)
21
- * - to-many (`otm`/`mtm`) — itens são separados entre "com PK" e "sem PK":
22
- * os sem PK viram `create`, os com PK viram `connectOrCreate` no create e
23
- * `upsert` no update; com `restriction: "set"`, itens de `otm` que não
24
- * vieram no array são removidos (`deleteMany`) e itens de `mtm` têm o
25
- * vínculo resetado (`set: []`) antes de reconectar
26
- *
27
- * Essa mesma saída `{ create, update }` é reaproveitada em todos os métodos de
28
- * escrita do adapter: `create()` usa só `.create`, `update()`/`updateMany()`
29
- * usam só `.update`, e `save()`/`upsert()` usam os dois.
30
- */
31
- import { AdapterRelations } from "../types/adapter-relations.type";
32
- import { PlainObject } from "../types/plain-object.type";
1
+ import { AdapterRelations } from "../types/adapter-relations.type.js";
2
+ import { PlainObject } from "../types/plain-object.type.js";
33
3
  export interface PrismaWriteData {
34
4
  create: PlainObject;
35
5
  update: PlainObject;
36
6
  }
37
- export declare function parsePrismaWriteData<T>(obj: PlainObject, pkName: string, relations?: AdapterRelations<T>): PrismaWriteData;
7
+ export declare function parsePrismaWriteData<T>(obj: PlainObject, pkName: string, relations?: AdapterRelations<T>, omitPkInUpdate?: boolean): PrismaWriteData;
@@ -1,37 +1,4 @@
1
- "use strict";
2
- /**
3
- * Parser que converte um `DeepPartial<T>` (formato "cru" vindo do vsrepo) nos
4
- * payloads `create`/`update` esperados pelo Prisma para escritas com relations,
5
- * replicando o comportamento da v1 (`resolveCreateUpdatePayloadsWithRelations`).
6
- *
7
- * Sem `relations` configurado no adapter, cada campo é repassado como está —
8
- * exceto `pkName`, que é omitido do `update` (não faz sentido reatribuir a PK
9
- * num update parcial).
10
- *
11
- * Com `relations`, cada campo de relação é resolvido de acordo com seu `mode`/
12
- * `restriction` (ver `Relation`):
13
- * - to-one (`oto`/`mto`) sem PK no valor enviado -> `create` (e `upsert` no
14
- * update, a não ser que `restriction: "add"`, que usa só `create`)
15
- * - to-one com PK no valor enviado -> `connectOrCreate` (e
16
- * `upsert` no update, a não ser que `restriction: "add"`)
17
- * - to-one enviado como `null` com `nullable` -> `delete` (`oto` +
18
- * `restriction: "set"`) ou `disconnect` (`oto` com `restriction: "add"` /
19
- * `mto`; um `oto` não "desconecta" no `update`, a linha possuída é apagada)
20
- * - to-one enviado como `null` sem `nullable` -> lança `VSRepoAdapterError`
21
- * (code `INVALID_DATA`)
22
- * - to-many (`otm`/`mtm`) — itens são separados entre "com PK" e "sem PK":
23
- * os sem PK viram `create`, os com PK viram `connectOrCreate` no create e
24
- * `upsert` no update; com `restriction: "set"`, itens de `otm` que não
25
- * vieram no array são removidos (`deleteMany`) e itens de `mtm` têm o
26
- * vínculo resetado (`set: []`) antes de reconectar
27
- *
28
- * Essa mesma saída `{ create, update }` é reaproveitada em todos os métodos de
29
- * escrita do adapter: `create()` usa só `.create`, `update()`/`updateMany()`
30
- * usam só `.update`, e `save()`/`upsert()` usam os dois.
31
- */
32
- Object.defineProperty(exports, "__esModule", { value: true });
33
- exports.parsePrismaWriteData = parsePrismaWriteData;
34
- const vsrepo_1 = require("vsrepo");
1
+ import { AdapterErrorCode, VSRepoAdapterError } from "vsrepo";
35
2
  function omitKey(item, key) {
36
3
  const clone = { ...item };
37
4
  delete clone[key];
@@ -48,7 +15,7 @@ function splitByPk(items, pk) {
48
15
  function parseToOneRelation(field, relation) {
49
16
  if (field === null) {
50
17
  if (!relation.nullable) {
51
- throw new vsrepo_1.VSRepoAdapterError(`You cannot provide null for a to-one relation when it is not nullable.`, vsrepo_1.AdapterErrorCode.INVALID_DATA, null);
18
+ throw new VSRepoAdapterError(`You cannot provide null for a to-one relation when it is not nullable.`, AdapterErrorCode.INVALID_DATA, null);
52
19
  }
53
20
  if (relation.mode === "oto") {
54
21
  if (relation.restriction === "set") {
@@ -60,12 +27,10 @@ function parseToOneRelation(field, relation) {
60
27
  return { update: { disconnect: true } };
61
28
  }
62
29
  const pkValue = field[relation.pk];
63
- if (pkValue == undefined) {
30
+ if (pkValue === undefined) {
64
31
  return {
65
32
  create: { create: field },
66
- update: relation.restriction === "add"
67
- ? { create: field }
68
- : { upsert: { create: field, update: field } },
33
+ update: relation.restriction === "add" ? { create: field } : { upsert: { create: field, update: field } },
69
34
  };
70
35
  }
71
36
  const connectOrCreate = { where: { [relation.pk]: pkValue }, create: field };
@@ -99,9 +64,7 @@ function parseToManyRelation(field, relation) {
99
64
  if (relation.restriction === "add") {
100
65
  return {
101
66
  create,
102
- update: relation.mode === "mtm"
103
- ? { create: withoutPk, connectOrCreate }
104
- : { create: withoutPk, upsert },
67
+ update: relation.mode === "mtm" ? { create: withoutPk, connectOrCreate } : { create: withoutPk, upsert },
105
68
  };
106
69
  }
107
70
  return {
@@ -117,7 +80,7 @@ function parseToManyRelation(field, relation) {
117
80
  },
118
81
  };
119
82
  }
120
- function parsePrismaWriteData(obj, pkName, relations) {
83
+ export function parsePrismaWriteData(obj, pkName, relations, omitPkInUpdate = false) {
121
84
  const create = {};
122
85
  const update = {};
123
86
  for (const [key, field] of Object.entries(obj)) {
@@ -126,7 +89,7 @@ function parsePrismaWriteData(obj, pkName, relations) {
126
89
  const relation = relations?.[key];
127
90
  if (!relation) {
128
91
  create[key] = field;
129
- if (key !== pkName)
92
+ if (!omitPkInUpdate || key !== pkName)
130
93
  update[key] = field;
131
94
  continue;
132
95
  }
@@ -144,4 +107,3 @@ function parsePrismaWriteData(obj, pkName, relations) {
144
107
  }
145
108
  return { create, update };
146
109
  }
147
- //# sourceMappingURL=data.parser.js.map
@@ -1,3 +1,3 @@
1
1
  import { VSRepoRelations } from "vsrepo";
2
- import { PlainObject } from "../types/plain-object.type";
2
+ import { PlainObject } from "../types/plain-object.type.js";
3
3
  export declare function parsePrismaInclude<T>(relations: VSRepoRelations<T>): PlainObject;
@@ -1,11 +1,8 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parsePrismaInclude = parsePrismaInclude;
4
- const is_plain_object_validator_1 = require("../validators/is-plain-object.validator");
5
- function parsePrismaInclude(relations) {
1
+ import { isPlainObject } from "../validators/is-plain-object.validator.js";
2
+ export function parsePrismaInclude(relations) {
6
3
  const include = {};
7
4
  for (const [key, value] of Object.entries(relations)) {
8
- if ((0, is_plain_object_validator_1.isPlainObject)(value)) {
5
+ if (isPlainObject(value)) {
9
6
  include[key] = { include: parsePrismaInclude(value) };
10
7
  }
11
8
  else {
@@ -14,4 +11,3 @@ function parsePrismaInclude(relations) {
14
11
  }
15
12
  return include;
16
13
  }
17
- //# sourceMappingURL=include.parser.js.map
@@ -1,15 +1,7 @@
1
- /**
2
- * Parser que converte um `Ordering<T>` (formato "amigável" do vsrepo) num
3
- * `orderBy` válido de qualquer modelo do Prisma.
4
- *
5
- * Suporta:
6
- * - Direção em qualquer caixa: { name: "ASC" } / { name: "asc" } -> { name: "asc" }
7
- * - Ordenação encadeada: [{ name: "asc" }, { createdAt: "desc" }]
8
- * - Ordenação aninhada em relations to-one: { address: { city: "asc" } }
9
- */
10
1
  import { Ordering } from "vsrepo";
2
+ import { PlainObject } from "../types/plain-object.type.js";
11
3
  /**
12
4
  * Use o segundo generic para tipar o retorno com o `OrderByInput`
13
5
  * do Prisma correspondente ao modelo.
14
6
  */
15
- export declare function parsePrismaOrderBy<T, O = any>(order: Ordering<T> | undefined | null): O | undefined;
7
+ export declare function parsePrismaOrderBy<T>(order: Ordering<T> | undefined): PlainObject | PlainObject[] | undefined;
@@ -1,16 +1,4 @@
1
- "use strict";
2
- /**
3
- * Parser que converte um `Ordering<T>` (formato "amigável" do vsrepo) num
4
- * `orderBy` válido de qualquer modelo do Prisma.
5
- *
6
- * Suporta:
7
- * - Direção em qualquer caixa: { name: "ASC" } / { name: "asc" } -> { name: "asc" }
8
- * - Ordenação encadeada: [{ name: "asc" }, { createdAt: "desc" }]
9
- * - Ordenação aninhada em relations to-one: { address: { city: "asc" } }
10
- */
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.parsePrismaOrderBy = parsePrismaOrderBy;
13
- const is_plain_object_validator_1 = require("../validators/is-plain-object.validator");
1
+ import { isPlainObject } from "../validators/is-plain-object.validator.js";
14
2
  function isSortDirection(value) {
15
3
  return value === "asc" || value === "desc" || value === "ASC" || value === "DESC";
16
4
  }
@@ -21,7 +9,7 @@ function parseOrderByField(order) {
21
9
  continue;
22
10
  result[key] = isSortDirection(value)
23
11
  ? value.toLowerCase()
24
- : (0, is_plain_object_validator_1.isPlainObject)(value)
12
+ : isPlainObject(value)
25
13
  ? parseOrderByField(value)
26
14
  : value;
27
15
  }
@@ -31,9 +19,8 @@ function parseOrderByField(order) {
31
19
  * Use o segundo generic para tipar o retorno com o `OrderByInput`
32
20
  * do Prisma correspondente ao modelo.
33
21
  */
34
- function parsePrismaOrderBy(order) {
35
- if (order === undefined || order === null)
36
- return undefined;
37
- return (Array.isArray(order) ? order.map(o => parseOrderByField(o)) : parseOrderByField(order));
22
+ export function parsePrismaOrderBy(order) {
23
+ if (!order)
24
+ return;
25
+ return Array.isArray(order) ? order.map(o => parseOrderByField(o)) : parseOrderByField(order);
38
26
  }
39
- //# sourceMappingURL=order-by.parser.js.map
@@ -1,3 +1,3 @@
1
1
  import { VSRepoSelect } from "vsrepo";
2
- import { PlainObject } from "../types/plain-object.type";
2
+ import { PlainObject } from "../types/plain-object.type.js";
3
3
  export declare function parsePrismaSelect<T>(relations: VSRepoSelect<T>): PlainObject;
@@ -1,11 +1,8 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.parsePrismaSelect = parsePrismaSelect;
4
- const is_plain_object_validator_1 = require("../validators/is-plain-object.validator");
5
- function parsePrismaSelect(relations) {
1
+ import { isPlainObject } from "../validators/is-plain-object.validator.js";
2
+ export function parsePrismaSelect(relations) {
6
3
  const select = {};
7
4
  for (const [key, value] of Object.entries(relations)) {
8
- if ((0, is_plain_object_validator_1.isPlainObject)(value)) {
5
+ if (isPlainObject(value)) {
9
6
  select[key] = { select: parsePrismaSelect(value) };
10
7
  }
11
8
  else {
@@ -14,4 +11,3 @@ function parsePrismaSelect(relations) {
14
11
  }
15
12
  return select;
16
13
  }
17
- //# sourceMappingURL=select.parser.js.map
@@ -1,31 +1,7 @@
1
- /**
2
- * Parser que converte um `VSRepoWhere<T>` (formato "amigável" da aplicação)
3
- * em um `where` válido de qualquer modelo do Prisma.
4
- *
5
- * Suporta:
6
- * - Valor direto: { name: "Ana" }
7
- * - Operadores de campo: { age: { gte: 18, lte: 65 } }
8
- * - `between`: { age: { between: [18, 65] } } -> { gte: 18, lte: 65 }
9
- * - `not` (valor ou operador): { name: { not: "Ana" } }
10
- * { name: { not: { contains: "an" } } }
11
- * - Strings case-insensitive: { name: { contains: "ana", ignoreCase: true } }
12
- * -> { contains: "ana", mode: "insensitive" }
13
- * - Relação lista (array): { posts: { _some: { title: "x" } } } -> { posts: { some: {...} } }
14
- * - Relação objeto (to-one): { author: { _with: { id: 1 } } } -> { author: { is: {...} } }
15
- * { author: { _without: { id: 1 } } } -> { author: { isNot: {...} } }
16
- * - Lógicos no nível raiz: { AND: [...] , OR: [...], NOT: {...} }
17
- *
18
- * Reflete a tipagem atual: `AND`/`OR`/`NOT` só existem em `VSRepoWhere<T>`
19
- * (nível raiz). Dentro de relações (`_some`/`_every`/`_none`/`_with`/
20
- * `_without`), o tipo usado é `VSRepoWherePlain<U>`, que NÃO tem esses
21
- * operadores lógicos — por isso a recursão para relações usa
22
- * `parsePlainWhere`, e não `parseWhere`.
23
- */
24
1
  import { VSRepoWhere } from "vsrepo";
2
+ import { PlainObject } from "../types/plain-object.type.js";
3
+ import { PrismaProvider } from "../types/prisma-provider.type.js";
25
4
  /**
26
- * API pública. Use o segundo generic para tipar o retorno com o `WhereInput`
27
- * do Prisma correspondente ao modelo, ex:
28
- *
29
- * parseVSRepoWhere<User, Prisma.UserWhereInput>(where)
5
+ * Converts a `VSRepoWhere` into a Prisma `where`.
30
6
  */
31
- export declare function parsePrismaWhere<T, W = any>(where: VSRepoWhere<T> | undefined | null): W | undefined;
7
+ export declare function parsePrismaWhere<T>(where: VSRepoWhere<T> | undefined, provider?: PrismaProvider): PlainObject | undefined;
@@ -1,73 +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
- ]);
45
- /** Chaves de operadores de string que aceitam `mode: 'insensitive'` no Prisma */
46
- const CASE_SENSITIVE_STRING_KEYS = ["equals", "contains", "startsWith", "endsWith"];
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";
47
4
  const LOGICAL_KEYS = new Set(["AND", "OR", "NOT"]);
48
- /** Verifica se um objeto "parece" um VSRepoFieldOperators (e não um filtro de relação/nested where) */
49
- function isFieldOperatorObject(value) {
50
- return Object.keys(value).some(key => FIELD_OPERATOR_KEYS.has(key));
51
- }
52
- function isArrayRelationFilter(value) {
53
- return "_some" in value || "_every" in value || "_none" in value;
54
- }
55
- function isObjectRelationFilter(value) {
56
- return "_with" in value || "_without" in value;
57
- }
58
- /**
59
- * Converte um VSRepoFieldOperators<V> em um filtro de campo do Prisma.
60
- */
61
- function parseFieldOperators(value) {
5
+ function parseFieldValue(value, provider) {
6
+ if (!isPlainObject(value)) {
7
+ return value;
8
+ }
62
9
  const result = {};
63
- const ignoreCase = value.ignoreCase === true;
64
10
  for (const [key, val] of Object.entries(value)) {
65
11
  if (val === undefined)
66
12
  continue;
67
13
  switch (key) {
68
- case "ignoreCase":
69
- // 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";
70
23
  break;
24
+ }
71
25
  case "between": {
72
26
  const [min, max] = val;
73
27
  if (min !== undefined)
@@ -77,112 +31,56 @@ function parseFieldOperators(value) {
77
31
  break;
78
32
  }
79
33
  case "not": {
80
- result.not =
81
- (0, is_plain_object_validator_1.isPlainObject)(val) && isFieldOperatorObject(val)
82
- ? parseFieldOperators(val)
83
- : 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);
84
43
  break;
85
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
+ }
86
61
  default:
87
62
  result[key] = val;
88
63
  }
89
64
  }
90
- if (ignoreCase) {
91
- const hasCaseSensitiveKey = CASE_SENSITIVE_STRING_KEYS.some(k => k in result);
92
- if (hasCaseSensitiveKey) {
93
- result.mode = "insensitive";
94
- }
95
- }
96
65
  return result;
97
66
  }
98
- /** Converte { _some, _every, _none } em { some, every, none } (VSRepoWherePlain — sem AND/OR/NOT) */
99
- function parseArrayRelationFilter(value) {
100
- const result = {};
101
- if (value._some !== undefined) {
102
- result.some = parsePlainWhere(value._some);
103
- }
104
- if (value._every !== undefined) {
105
- result.every = parsePlainWhere(value._every);
106
- }
107
- if (value._none !== undefined) {
108
- result.none = parsePlainWhere(value._none);
109
- }
110
- return result;
111
- }
112
- /** Converte { _with, _without } em { is, isNot } (VSRepoWherePlain — sem AND/OR/NOT) */
113
- function parseObjectRelationFilter(value) {
114
- if (value._with !== undefined) {
115
- return { is: parsePlainWhere(value._with) };
116
- }
117
- if (value._without !== undefined) {
118
- return { isNot: parsePlainWhere(value._without) };
119
- }
120
- return {};
121
- }
122
- /** Decide como interpretar o valor de um campo do where */
123
- function parseFieldValue(value) {
124
- // valores primitivos (string, number, boolean, Date, null, bigint, Decimal) passam direto
125
- if (value === null || typeof value !== "object" || value instanceof Date || (0, is_decimal_validator_1.isDecimal)(value)) {
126
- return value;
127
- }
128
- // arrays (usados em `in`/`notIn` no nível mais alto, ex: { status: ["A","B"] })
129
- if (Array.isArray(value)) {
130
- return value;
131
- }
132
- const obj = value;
133
- if (isArrayRelationFilter(obj)) {
134
- return parseArrayRelationFilter(obj);
135
- }
136
- if (isObjectRelationFilter(obj)) {
137
- return parseObjectRelationFilter(obj);
138
- }
139
- if (isFieldOperatorObject(obj)) {
140
- return parseFieldOperators(obj);
141
- }
142
- // fallback: nested where (não deveria ocorrer para campos primitivos bem tipados)
143
- return parsePlainWhere(obj);
144
- }
145
67
  /**
146
- * Converte um `VSRepoWherePlain<T>` (sem AND/OR/NOT) — usado para o corpo de
147
- * relações (`_some`/`_every`/`_none`/`_with`/`_without`).
68
+ * Converts a `VSRepoWhere` into a Prisma `where`.
148
69
  */
149
- function parsePlainWhere(where) {
150
- if (where === undefined || where === null)
151
- return undefined;
152
- const result = {};
153
- for (const [key, value] of Object.entries(where)) {
154
- if (value === undefined)
155
- continue;
156
- result[key] = parseFieldValue(value);
157
- }
158
- return result;
159
- }
160
- /**
161
- * Converte um `VSRepoWhere<T>` completo (nível raiz, com AND/OR/NOT) em um
162
- * where do Prisma.
163
- */
164
- function parseWhere(where) {
165
- if (where === undefined || where === null)
70
+ export function parsePrismaWhere(where, provider) {
71
+ if (where === undefined)
166
72
  return undefined;
167
73
  const result = {};
168
74
  for (const [key, value] of Object.entries(where)) {
169
75
  if (value === undefined)
170
76
  continue;
171
77
  if (LOGICAL_KEYS.has(key)) {
172
- 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);
173
81
  continue;
174
82
  }
175
- result[key] = parseFieldValue(value);
83
+ result[key] = parseFieldValue(value, provider);
176
84
  }
177
85
  return result;
178
86
  }
179
- /**
180
- * API pública. Use o segundo generic para tipar o retorno com o `WhereInput`
181
- * do Prisma correspondente ao modelo, ex:
182
- *
183
- * parseVSRepoWhere<User, Prisma.UserWhereInput>(where)
184
- */
185
- function parsePrismaWhere(where) {
186
- return parseWhere(where);
187
- }
188
- //# sourceMappingURL=where.parser.js.map