@cerbos/orm-prisma 2.0.1 → 3.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 +59 -2
- package/lib/{types/index.d.ts → index.d.ts} +3 -9
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +629 -0
- package/lib/index.js.map +1 -0
- package/package.json +47 -32
- package/src/generated/prisma/browser.ts +59 -0
- package/src/generated/prisma/client.ts +79 -0
- package/src/generated/prisma/commonInputTypes.ts +248 -0
- package/src/generated/prisma/enums.ts +15 -0
- package/src/generated/prisma/internal/class.ts +260 -0
- package/src/generated/prisma/internal/prismaNamespace.ts +1333 -0
- package/src/generated/prisma/internal/prismaNamespaceBrowser.ts +168 -0
- package/src/generated/prisma/models/Category.ts +1407 -0
- package/src/generated/prisma/models/Label.ts +1271 -0
- package/src/generated/prisma/models/NestedResource.ts +1557 -0
- package/src/generated/prisma/models/NextLevelNestedResource.ts +1332 -0
- package/src/generated/prisma/models/Resource.ts +2131 -0
- package/src/generated/prisma/models/SubCategory.ts +1407 -0
- package/src/generated/prisma/models/Tag.ts +1271 -0
- package/src/generated/prisma/models/User.ts +1498 -0
- package/src/generated/prisma/models.ts +19 -0
- package/src/generated/prisma-v6/client.d.ts +1 -0
- package/src/generated/prisma-v6/default.d.ts +1 -0
- package/src/generated/prisma-v6/edge.d.ts +1 -0
- package/src/generated/prisma-v6/index.d.ts +13639 -0
- package/src/generated/prisma-v6/runtime/index-browser.d.ts +370 -0
- package/src/generated/prisma-v6/runtime/library.d.ts +3982 -0
- package/src/generated/prisma-v6/wasm.d.ts +1 -0
- package/src/index.test.ts +4869 -0
- package/src/index.ts +954 -0
- package/src/test-setup.v6.ts +5 -0
- package/src/test-setup.v7.ts +7 -0
- package/lib/cjs/index.js +0 -517
- package/lib/cjs/index.js.map +0 -1
- package/lib/esm/index.js +0 -513
- package/lib/esm/index.js.map +0 -1
- package/lib/types/index.d.ts.map +0 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { PrismaBetterSqlite3 } from "@prisma/adapter-better-sqlite3";
|
|
2
|
+
import { Prisma, PrismaClient } from "./generated/prisma/client";
|
|
3
|
+
|
|
4
|
+
const adapter = new PrismaBetterSqlite3({ url: "./prisma/dev.db" });
|
|
5
|
+
const prisma = new PrismaClient({ adapter });
|
|
6
|
+
|
|
7
|
+
export { prisma, Prisma };
|
package/lib/cjs/index.js
DELETED
|
@@ -1,517 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PlanKind = void 0;
|
|
4
|
-
exports.queryPlanToPrisma = queryPlanToPrisma;
|
|
5
|
-
const core_1 = require("@cerbos/core");
|
|
6
|
-
Object.defineProperty(exports, "PlanKind", { enumerable: true, get: function () { return core_1.PlanKind; } });
|
|
7
|
-
/**
|
|
8
|
-
* Converts a Cerbos query plan to a Prisma filter.
|
|
9
|
-
* @param {QueryPlanToPrismaArgs} args - The arguments containing the query plan and mapper.
|
|
10
|
-
* @returns {QueryPlanToPrismaResult} The result containing the kind and filters.
|
|
11
|
-
*/
|
|
12
|
-
function queryPlanToPrisma({ queryPlan, mapper = {}, }) {
|
|
13
|
-
switch (queryPlan.kind) {
|
|
14
|
-
case core_1.PlanKind.ALWAYS_ALLOWED:
|
|
15
|
-
return { kind: core_1.PlanKind.ALWAYS_ALLOWED };
|
|
16
|
-
case core_1.PlanKind.ALWAYS_DENIED:
|
|
17
|
-
return { kind: core_1.PlanKind.ALWAYS_DENIED };
|
|
18
|
-
case core_1.PlanKind.CONDITIONAL:
|
|
19
|
-
return {
|
|
20
|
-
kind: core_1.PlanKind.CONDITIONAL,
|
|
21
|
-
filters: buildPrismaFilterFromCerbosExpression(queryPlan.condition, mapper),
|
|
22
|
-
};
|
|
23
|
-
default:
|
|
24
|
-
throw Error(`Invalid query plan.`);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Resolves a field reference considering relations and nested fields.
|
|
29
|
-
* Handles both direct field mappings and relation mappings with support for nested structures.
|
|
30
|
-
*
|
|
31
|
-
* @param {string} reference - The field reference from Cerbos
|
|
32
|
-
* @param {Mapper} mapper - Configuration for field/relation mapping
|
|
33
|
-
* @returns {Object} Resolved reference with path and optional relations
|
|
34
|
-
*/
|
|
35
|
-
const resolveFieldReference = (reference, mapper) => {
|
|
36
|
-
const parts = reference.split(".");
|
|
37
|
-
const config = typeof mapper === "function" ? mapper(reference) : mapper[reference];
|
|
38
|
-
let matchedPrefix = "";
|
|
39
|
-
let matchedConfig;
|
|
40
|
-
if (!config) {
|
|
41
|
-
for (let i = parts.length - 1; i >= 0; i--) {
|
|
42
|
-
const prefix = parts.slice(0, i + 1).join(".");
|
|
43
|
-
const prefixConfig = typeof mapper === "function" ? mapper(prefix) : mapper[prefix];
|
|
44
|
-
if (prefixConfig) {
|
|
45
|
-
matchedPrefix = prefix;
|
|
46
|
-
matchedConfig = prefixConfig;
|
|
47
|
-
break;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
const activeConfig = config || matchedConfig;
|
|
52
|
-
if (activeConfig?.relation) {
|
|
53
|
-
const { name, type, fields } = activeConfig.relation;
|
|
54
|
-
const matchedParts = matchedPrefix ? matchedPrefix.split(".") : [];
|
|
55
|
-
const remainingParts = matchedPrefix
|
|
56
|
-
? parts.slice(matchedParts.length)
|
|
57
|
-
: parts.slice(1);
|
|
58
|
-
let field;
|
|
59
|
-
const relations = [
|
|
60
|
-
{ name, type, field: activeConfig.relation.field, nestedMapper: fields },
|
|
61
|
-
];
|
|
62
|
-
if (fields && remainingParts.length > 0) {
|
|
63
|
-
let currentMapper = fields;
|
|
64
|
-
let currentParts = remainingParts;
|
|
65
|
-
while (currentParts.length > 0) {
|
|
66
|
-
const nextConfig = currentMapper[currentParts[0]];
|
|
67
|
-
if (nextConfig?.relation) {
|
|
68
|
-
relations.push({
|
|
69
|
-
name: nextConfig.relation.name,
|
|
70
|
-
type: nextConfig.relation.type,
|
|
71
|
-
field: nextConfig.relation.field,
|
|
72
|
-
nestedMapper: nextConfig.relation.fields,
|
|
73
|
-
});
|
|
74
|
-
currentMapper = nextConfig.relation.fields || {};
|
|
75
|
-
currentParts = currentParts.slice(1);
|
|
76
|
-
}
|
|
77
|
-
else {
|
|
78
|
-
field = nextConfig?.field || currentParts[currentParts.length - 1];
|
|
79
|
-
break;
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return { path: field ? [field] : remainingParts, relations };
|
|
84
|
-
}
|
|
85
|
-
return { path: [activeConfig?.field || reference] };
|
|
86
|
-
};
|
|
87
|
-
/**
|
|
88
|
-
* Determines the appropriate Prisma operator based on relation type.
|
|
89
|
-
* Used for building relation filters in Prisma queries.
|
|
90
|
-
*
|
|
91
|
-
* @param {Object} relation - Relation configuration
|
|
92
|
-
* @param {string} relation.name - Name of the relation
|
|
93
|
-
* @param {('one'|'many')} relation.type - Type of relation
|
|
94
|
-
* @returns {string} Prisma relation operator ('is' for one-to-one, 'some' for one-to-many)
|
|
95
|
-
*/
|
|
96
|
-
const getPrismaRelationOperator = (relation) => (relation.type === "one" ? "is" : "some");
|
|
97
|
-
/**
|
|
98
|
-
* Builds a nested relation filter for Prisma queries.
|
|
99
|
-
* Handles multiple levels of relations and applies appropriate operators.
|
|
100
|
-
*
|
|
101
|
-
* @param {Array} relations - Array of relation configurations
|
|
102
|
-
* @param {Object} fieldFilter - Base filter to apply at the deepest level
|
|
103
|
-
* @returns {Object} Nested Prisma filter structure
|
|
104
|
-
*/
|
|
105
|
-
const buildNestedRelationFilter = (relations, fieldFilter) => {
|
|
106
|
-
if (relations.length === 0)
|
|
107
|
-
return fieldFilter;
|
|
108
|
-
let currentFilter = fieldFilter;
|
|
109
|
-
for (let i = relations.length - 1; i >= 0; i--) {
|
|
110
|
-
const relation = relations[i];
|
|
111
|
-
const relationOperator = getPrismaRelationOperator(relation);
|
|
112
|
-
if (relation.field && i === relations.length - 1) {
|
|
113
|
-
const [, filterValue] = Object.entries(currentFilter)[0];
|
|
114
|
-
currentFilter = { [relation.field]: filterValue };
|
|
115
|
-
}
|
|
116
|
-
currentFilter = { [relation.name]: { [relationOperator]: currentFilter } };
|
|
117
|
-
}
|
|
118
|
-
return currentFilter;
|
|
119
|
-
};
|
|
120
|
-
/**
|
|
121
|
-
* Type guard to check if an operand is a resolved field reference.
|
|
122
|
-
* @param {ResolvedOperand} operand - Operand to check
|
|
123
|
-
* @returns {boolean} True if operand is a field reference
|
|
124
|
-
*/
|
|
125
|
-
function isResolvedFieldReference(operand) {
|
|
126
|
-
return "path" in operand;
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Type guard to check if an operand is a resolved value.
|
|
130
|
-
* @param {ResolvedOperand} operand - Operand to check
|
|
131
|
-
* @returns {boolean} True if operand is a value
|
|
132
|
-
*/
|
|
133
|
-
function isResolvedValue(operand) {
|
|
134
|
-
return "value" in operand;
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Type guard for PlanExpressionOperand with name property.
|
|
138
|
-
* @param {PlanExpressionOperand} operand - Operand to check
|
|
139
|
-
* @returns {boolean} True if operand has name property
|
|
140
|
-
*/
|
|
141
|
-
function isPlanExpressionWithName(operand) {
|
|
142
|
-
return "name" in operand && typeof operand.name === "string";
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Type guard for PlanExpressionOperand with value property.
|
|
146
|
-
* @param {PlanExpressionOperand} operand - Operand to check
|
|
147
|
-
* @returns {boolean} True if operand has value property
|
|
148
|
-
*/
|
|
149
|
-
function isPlanExpressionWithValue(operand) {
|
|
150
|
-
return "value" in operand && operand.value !== undefined;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Type guard for PlanExpressionOperand with operator property.
|
|
154
|
-
* @param {PlanExpressionOperand} operand - Operand to check
|
|
155
|
-
* @returns {boolean} True if operand has operator and operands properties
|
|
156
|
-
*/
|
|
157
|
-
function isPlanExpressionWithOperator(operand) {
|
|
158
|
-
return ("operator" in operand &&
|
|
159
|
-
typeof operand.operator === "string" &&
|
|
160
|
-
"operands" in operand &&
|
|
161
|
-
Array.isArray(operand.operands));
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* Resolves a PlanExpressionOperand into a ResolvedOperand.
|
|
165
|
-
* Handles field references, values, and nested expressions.
|
|
166
|
-
*
|
|
167
|
-
* @param {PlanExpressionOperand} operand - Operand to resolve
|
|
168
|
-
* @param {Mapper} mapper - Field mapping configuration
|
|
169
|
-
* @returns {ResolvedOperand} Resolved operand
|
|
170
|
-
* @throws {Error} If operand is invalid
|
|
171
|
-
*/
|
|
172
|
-
const resolveOperand = (operand, mapper) => {
|
|
173
|
-
if (isPlanExpressionWithName(operand)) {
|
|
174
|
-
return resolveFieldReference(operand.name, mapper);
|
|
175
|
-
}
|
|
176
|
-
else if (isPlanExpressionWithValue(operand)) {
|
|
177
|
-
return { value: operand.value };
|
|
178
|
-
}
|
|
179
|
-
else if (isPlanExpressionWithOperator(operand)) {
|
|
180
|
-
const nestedResult = buildPrismaFilterFromCerbosExpression(operand, mapper);
|
|
181
|
-
return { value: nestedResult };
|
|
182
|
-
}
|
|
183
|
-
throw new Error("Operand must have name, value, or be an expression");
|
|
184
|
-
};
|
|
185
|
-
/**
|
|
186
|
-
* Builds a Prisma filter from a Cerbos expression.
|
|
187
|
-
* Main function for converting Cerbos query conditions to Prisma filters.
|
|
188
|
-
*
|
|
189
|
-
* @param {PlanExpressionOperand} expression - Cerbos expression to convert
|
|
190
|
-
* @param {Mapper} mapper - Field mapping configuration
|
|
191
|
-
* @returns {PrismaFilter} Prisma compatible filter
|
|
192
|
-
* @throws {Error} If expression is invalid or operator is unsupported
|
|
193
|
-
*/
|
|
194
|
-
const buildPrismaFilterFromCerbosExpression = (expression, mapper) => {
|
|
195
|
-
// Validate expression structure
|
|
196
|
-
if (!("operator" in expression) || !("operands" in expression)) {
|
|
197
|
-
throw new Error("Invalid Cerbos expression structure");
|
|
198
|
-
}
|
|
199
|
-
const { operator, operands } = expression;
|
|
200
|
-
/**
|
|
201
|
-
* Helper function to process relational operators (eq, ne, lt, etc.)
|
|
202
|
-
* @param {string} operator - Relational operator
|
|
203
|
-
* @param {ResolvedOperand} left - Left operand
|
|
204
|
-
* @param {ResolvedOperand} right - Right operand
|
|
205
|
-
* @returns {PrismaFilter} Prisma filter for the relation
|
|
206
|
-
*/
|
|
207
|
-
const processRelationalOperator = (operator, left, right) => {
|
|
208
|
-
const prismaOperator = {
|
|
209
|
-
eq: "equals",
|
|
210
|
-
ne: "not",
|
|
211
|
-
lt: "lt",
|
|
212
|
-
le: "lte",
|
|
213
|
-
gt: "gt",
|
|
214
|
-
ge: "gte",
|
|
215
|
-
}[operator];
|
|
216
|
-
if (isResolvedFieldReference(left)) {
|
|
217
|
-
const { path, relations } = left;
|
|
218
|
-
if (!isResolvedValue(right)) {
|
|
219
|
-
throw new Error("Right operand must be a value");
|
|
220
|
-
}
|
|
221
|
-
if (!prismaOperator) {
|
|
222
|
-
throw new Error(`Unsupported operator: ${operator}`);
|
|
223
|
-
}
|
|
224
|
-
const filterValue = { [prismaOperator]: right.value };
|
|
225
|
-
const fieldFilter = { [path[path.length - 1]]: filterValue };
|
|
226
|
-
if (relations && relations.length > 0) {
|
|
227
|
-
return buildNestedRelationFilter(relations, fieldFilter);
|
|
228
|
-
}
|
|
229
|
-
return fieldFilter;
|
|
230
|
-
}
|
|
231
|
-
if (!isResolvedValue(right)) {
|
|
232
|
-
throw new Error("Right operand must be a value");
|
|
233
|
-
}
|
|
234
|
-
if (!prismaOperator) {
|
|
235
|
-
throw new Error(`Unsupported operator: ${operator}`);
|
|
236
|
-
}
|
|
237
|
-
return { [prismaOperator]: right.value };
|
|
238
|
-
};
|
|
239
|
-
// Process different operator types
|
|
240
|
-
switch (operator) {
|
|
241
|
-
case "and":
|
|
242
|
-
return {
|
|
243
|
-
AND: operands.map((operand) => buildPrismaFilterFromCerbosExpression(operand, mapper)),
|
|
244
|
-
};
|
|
245
|
-
case "or":
|
|
246
|
-
return {
|
|
247
|
-
OR: operands.map((operand) => buildPrismaFilterFromCerbosExpression(operand, mapper)),
|
|
248
|
-
};
|
|
249
|
-
case "not":
|
|
250
|
-
return {
|
|
251
|
-
NOT: buildPrismaFilterFromCerbosExpression(operands[0], mapper),
|
|
252
|
-
};
|
|
253
|
-
case "eq":
|
|
254
|
-
case "ne":
|
|
255
|
-
case "lt":
|
|
256
|
-
case "le":
|
|
257
|
-
case "gt":
|
|
258
|
-
case "ge": {
|
|
259
|
-
const leftOperand = operands.find((o) => isPlanExpressionWithName(o) || isPlanExpressionWithOperator(o));
|
|
260
|
-
if (!leftOperand)
|
|
261
|
-
throw new Error("No valid left operand found");
|
|
262
|
-
const rightOperand = operands.find((o) => o !== leftOperand);
|
|
263
|
-
if (!rightOperand)
|
|
264
|
-
throw new Error("No valid right operand found");
|
|
265
|
-
const left = resolveOperand(leftOperand, mapper);
|
|
266
|
-
const right = resolveOperand(rightOperand, mapper);
|
|
267
|
-
return processRelationalOperator(operator, left, right);
|
|
268
|
-
}
|
|
269
|
-
case "in": {
|
|
270
|
-
const nameOperand = operands.find(isPlanExpressionWithName);
|
|
271
|
-
if (!nameOperand)
|
|
272
|
-
throw new Error("Name operand is undefined");
|
|
273
|
-
const valueOperand = operands.find(isPlanExpressionWithValue);
|
|
274
|
-
if (!valueOperand)
|
|
275
|
-
throw new Error("Value operand is undefined");
|
|
276
|
-
const resolved = resolveOperand(nameOperand, mapper);
|
|
277
|
-
if (!isResolvedFieldReference(resolved))
|
|
278
|
-
throw new Error("Name operand must resolve to a field reference");
|
|
279
|
-
const { path, relations } = resolved;
|
|
280
|
-
const resolvedValue = resolveOperand(valueOperand, mapper);
|
|
281
|
-
if (!isResolvedValue(resolvedValue))
|
|
282
|
-
throw new Error("Value operand must resolve to a value");
|
|
283
|
-
const { value } = resolvedValue;
|
|
284
|
-
if (relations && relations.length > 0) {
|
|
285
|
-
const fieldFilter = { [path[path.length - 1]]: value };
|
|
286
|
-
return buildNestedRelationFilter(relations, fieldFilter);
|
|
287
|
-
}
|
|
288
|
-
return { [path[path.length - 1]]: { in: value } };
|
|
289
|
-
}
|
|
290
|
-
case "contains":
|
|
291
|
-
case "startsWith":
|
|
292
|
-
case "endsWith": {
|
|
293
|
-
const nameOperand = operands.find(isPlanExpressionWithName);
|
|
294
|
-
if (!nameOperand)
|
|
295
|
-
throw new Error("Name operand is undefined");
|
|
296
|
-
const resolved = resolveOperand(nameOperand, mapper);
|
|
297
|
-
if (!isResolvedFieldReference(resolved))
|
|
298
|
-
throw new Error("Name operand must resolve to a field reference");
|
|
299
|
-
const { path, relations } = resolved;
|
|
300
|
-
const valueOperand = operands.find(isPlanExpressionWithValue);
|
|
301
|
-
if (!valueOperand)
|
|
302
|
-
throw new Error("Value operand is undefined");
|
|
303
|
-
const resolvedValue = resolveOperand(valueOperand, mapper);
|
|
304
|
-
if (!isResolvedValue(resolvedValue))
|
|
305
|
-
throw new Error("Value operand must resolve to a value");
|
|
306
|
-
const { value } = resolvedValue;
|
|
307
|
-
if (typeof value !== "string")
|
|
308
|
-
throw new Error(`${operator} operator requires string value`);
|
|
309
|
-
const fieldFilter = { [path[path.length - 1]]: { [operator]: value } };
|
|
310
|
-
if (relations && relations.length > 0) {
|
|
311
|
-
return buildNestedRelationFilter(relations, fieldFilter);
|
|
312
|
-
}
|
|
313
|
-
return fieldFilter;
|
|
314
|
-
}
|
|
315
|
-
case "isSet": {
|
|
316
|
-
const nameOperand = operands.find(isPlanExpressionWithName);
|
|
317
|
-
if (!nameOperand)
|
|
318
|
-
throw new Error("Name operand is undefined");
|
|
319
|
-
const resolved = resolveOperand(nameOperand, mapper);
|
|
320
|
-
if (!isResolvedFieldReference(resolved))
|
|
321
|
-
throw new Error("Name operand must resolve to a field reference");
|
|
322
|
-
const { path, relations } = resolved;
|
|
323
|
-
const valueOperand = operands.find(isPlanExpressionWithValue);
|
|
324
|
-
if (!valueOperand)
|
|
325
|
-
throw new Error("Value operand is undefined");
|
|
326
|
-
const resolvedValue = resolveOperand(valueOperand, mapper);
|
|
327
|
-
const fieldFilter = {
|
|
328
|
-
[path[path.length - 1]]: resolvedValue
|
|
329
|
-
? { not: null }
|
|
330
|
-
: { equals: null },
|
|
331
|
-
};
|
|
332
|
-
if (relations && relations.length > 0) {
|
|
333
|
-
return buildNestedRelationFilter(relations, fieldFilter);
|
|
334
|
-
}
|
|
335
|
-
return fieldFilter;
|
|
336
|
-
}
|
|
337
|
-
case "hasIntersection": {
|
|
338
|
-
if (operands.length !== 2)
|
|
339
|
-
throw new Error("hasIntersection requires exactly two operands");
|
|
340
|
-
const [leftOperand, rightOperand] = operands;
|
|
341
|
-
if ("operator" in leftOperand && leftOperand.operator === "map") {
|
|
342
|
-
if (!("value" in rightOperand))
|
|
343
|
-
throw new Error("Second operand of hasIntersection must be a value");
|
|
344
|
-
const [collection, lambda] = leftOperand.operands;
|
|
345
|
-
if (!("name" in collection))
|
|
346
|
-
throw new Error("First operand of map must be a collection reference");
|
|
347
|
-
// Get variable name from lambda
|
|
348
|
-
if (!isPlanExpressionWithOperator(lambda)) {
|
|
349
|
-
throw new Error("Lambda expression must have operands");
|
|
350
|
-
}
|
|
351
|
-
const [, variable] = lambda.operands;
|
|
352
|
-
if (!("name" in variable))
|
|
353
|
-
throw new Error("Lambda variable must have a name");
|
|
354
|
-
// Create scoped mapper for the collection
|
|
355
|
-
const scopedMapper = createScopedMapper(collection.name, variable.name, mapper);
|
|
356
|
-
const { relations } = resolveFieldReference(collection.name, mapper);
|
|
357
|
-
if (!relations || relations.length === 0)
|
|
358
|
-
throw new Error("Map operation requires relations");
|
|
359
|
-
if (!("operands" in lambda))
|
|
360
|
-
throw new Error("Invalid lambda expression structure");
|
|
361
|
-
const [projection] = lambda.operands;
|
|
362
|
-
if (!("name" in projection))
|
|
363
|
-
throw new Error("Invalid map lambda expression structure");
|
|
364
|
-
// Use scoped mapper for resolving the projection
|
|
365
|
-
const resolved = resolveFieldReference(projection.name, scopedMapper);
|
|
366
|
-
const fieldName = resolved.path[resolved.path.length - 1];
|
|
367
|
-
return buildNestedRelationFilter(relations, {
|
|
368
|
-
[fieldName]: { in: rightOperand.value },
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
|
-
if (!("name" in leftOperand))
|
|
372
|
-
throw new Error("First operand of hasIntersection must be a field reference or map expression");
|
|
373
|
-
if (!("value" in rightOperand))
|
|
374
|
-
throw new Error("Second operand of hasIntersection must be a value");
|
|
375
|
-
const { path, relations } = resolveFieldReference(leftOperand.name, mapper);
|
|
376
|
-
if (!Array.isArray(rightOperand.value))
|
|
377
|
-
throw new Error("hasIntersection requires an array value");
|
|
378
|
-
if (relations && relations.length > 0) {
|
|
379
|
-
const fieldFilter = {
|
|
380
|
-
[path[path.length - 1]]: { in: rightOperand.value },
|
|
381
|
-
};
|
|
382
|
-
return buildNestedRelationFilter(relations, fieldFilter);
|
|
383
|
-
}
|
|
384
|
-
return { [path[path.length - 1]]: { some: rightOperand.value } };
|
|
385
|
-
}
|
|
386
|
-
case "lambda": {
|
|
387
|
-
const [condition, variable] = operands;
|
|
388
|
-
if (!("name" in variable))
|
|
389
|
-
throw new Error("Lambda variable must have a name");
|
|
390
|
-
return buildPrismaFilterFromCerbosExpression(condition, (key) => ({ field: key.replace(`${variable.name}.`, "") }));
|
|
391
|
-
}
|
|
392
|
-
case "exists":
|
|
393
|
-
case "exists_one":
|
|
394
|
-
case "all":
|
|
395
|
-
case "except":
|
|
396
|
-
case "filter": {
|
|
397
|
-
if (operands.length !== 2)
|
|
398
|
-
throw new Error(`${operator} requires exactly two operands`);
|
|
399
|
-
const [collection, lambda] = operands;
|
|
400
|
-
if (!("name" in collection))
|
|
401
|
-
throw new Error("First operand of exists/all/except must be a collection reference");
|
|
402
|
-
if (!("operator" in lambda))
|
|
403
|
-
throw new Error("Second operand of exists/all/except must be a lambda expression");
|
|
404
|
-
// Get variable name from lambda
|
|
405
|
-
const [, variable] = lambda.operands;
|
|
406
|
-
if (!("name" in variable))
|
|
407
|
-
throw new Error("Lambda variable must have a name");
|
|
408
|
-
// Create scoped mapper for the collection
|
|
409
|
-
const scopedMapper = createScopedMapper(collection.name, variable.name, mapper);
|
|
410
|
-
const { relations } = resolveFieldReference(collection.name, mapper);
|
|
411
|
-
if (!relations)
|
|
412
|
-
throw new Error(`${operator} operator requires a relation mapping`);
|
|
413
|
-
const lambdaCondition = buildPrismaFilterFromCerbosExpression(lambda.operands[0], // Use the condition part of the lambda
|
|
414
|
-
scopedMapper);
|
|
415
|
-
const relation = relations[0];
|
|
416
|
-
let filterValue = lambdaCondition;
|
|
417
|
-
// If the lambda condition already has a relation structure, merge it
|
|
418
|
-
if (lambdaCondition.AND || lambdaCondition.OR) {
|
|
419
|
-
filterValue = lambdaCondition;
|
|
420
|
-
}
|
|
421
|
-
else {
|
|
422
|
-
const filterField = relation.field || Object.keys(lambdaCondition)[0];
|
|
423
|
-
filterValue = {
|
|
424
|
-
[filterField]: lambdaCondition[Object.keys(lambdaCondition)[0]],
|
|
425
|
-
};
|
|
426
|
-
}
|
|
427
|
-
switch (operator) {
|
|
428
|
-
case "exists":
|
|
429
|
-
case "filter":
|
|
430
|
-
return { [relation.name]: { some: filterValue } };
|
|
431
|
-
case "exists_one":
|
|
432
|
-
return {
|
|
433
|
-
[relation.name]: {
|
|
434
|
-
some: filterValue,
|
|
435
|
-
},
|
|
436
|
-
AND: [
|
|
437
|
-
{
|
|
438
|
-
[relation.name]: {
|
|
439
|
-
every: {
|
|
440
|
-
OR: [filterValue, { NOT: filterValue }],
|
|
441
|
-
},
|
|
442
|
-
},
|
|
443
|
-
},
|
|
444
|
-
],
|
|
445
|
-
};
|
|
446
|
-
case "all":
|
|
447
|
-
return { [relation.name]: { every: filterValue } };
|
|
448
|
-
default:
|
|
449
|
-
throw new Error(`Unexpected operator: ${operator}`);
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
case "map": {
|
|
453
|
-
if (operands.length !== 2)
|
|
454
|
-
throw new Error("map requires exactly two operands");
|
|
455
|
-
const [collection, lambda] = operands;
|
|
456
|
-
if (!("name" in collection))
|
|
457
|
-
throw new Error("First operand of map must be a collection reference");
|
|
458
|
-
if (!("operator" in lambda) || lambda.operator !== "lambda")
|
|
459
|
-
throw new Error("Second operand of map must be a lambda expression");
|
|
460
|
-
// Get variable name from lambda
|
|
461
|
-
const [projection, variable] = lambda.operands;
|
|
462
|
-
if (!("name" in projection) || !("name" in variable))
|
|
463
|
-
throw new Error("Invalid map lambda expression structure");
|
|
464
|
-
// Create scoped mapper for the collection
|
|
465
|
-
const scopedMapper = createScopedMapper(collection.name, variable.name, mapper);
|
|
466
|
-
const { relations } = resolveFieldReference(collection.name, mapper);
|
|
467
|
-
if (!relations)
|
|
468
|
-
throw new Error("map operator requires a relation mapping");
|
|
469
|
-
// Use scoped mapper for resolving the projection
|
|
470
|
-
const resolved = resolveFieldReference(projection.name, scopedMapper);
|
|
471
|
-
const fieldName = resolved.path[resolved.path.length - 1];
|
|
472
|
-
return buildNestedRelationFilter(relations, {
|
|
473
|
-
[getPrismaRelationOperator(relations[relations.length - 1])]: {
|
|
474
|
-
select: { [fieldName]: true },
|
|
475
|
-
},
|
|
476
|
-
});
|
|
477
|
-
}
|
|
478
|
-
default:
|
|
479
|
-
throw new Error(`Unsupported operator: ${operator}`);
|
|
480
|
-
}
|
|
481
|
-
};
|
|
482
|
-
/**
|
|
483
|
-
* Creates a scoped mapper for collection operations that preserves access to parent scope
|
|
484
|
-
* and handles nested collections
|
|
485
|
-
*/
|
|
486
|
-
const createScopedMapper = (collectionPath, variableName, fullMapper) => (key) => {
|
|
487
|
-
// If the key starts with the variable name, it's accessing the collection item
|
|
488
|
-
if (key.startsWith(variableName + ".")) {
|
|
489
|
-
const strippedKey = key.replace(variableName + ".", "");
|
|
490
|
-
const parts = strippedKey.split(".");
|
|
491
|
-
// Get the collection's relation config
|
|
492
|
-
const collectionConfig = typeof fullMapper === "function"
|
|
493
|
-
? fullMapper(collectionPath)
|
|
494
|
-
: fullMapper[collectionPath];
|
|
495
|
-
if (collectionConfig?.relation?.fields) {
|
|
496
|
-
// For nested paths, traverse the fields configuration
|
|
497
|
-
let currentConfig = collectionConfig.relation.fields;
|
|
498
|
-
let field = parts[0];
|
|
499
|
-
for (let i = 0; i < parts.length - 1; i++) {
|
|
500
|
-
const part = parts[i];
|
|
501
|
-
if (currentConfig[part]?.relation?.fields) {
|
|
502
|
-
currentConfig = currentConfig[part].relation.fields;
|
|
503
|
-
field = parts[i + 1];
|
|
504
|
-
}
|
|
505
|
-
else {
|
|
506
|
-
break;
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
// Return the field config if it exists, otherwise create a default one
|
|
510
|
-
return currentConfig[field] || { field };
|
|
511
|
-
}
|
|
512
|
-
return { field: strippedKey };
|
|
513
|
-
}
|
|
514
|
-
// For keys not referencing the collection item, use the full mapper
|
|
515
|
-
return typeof fullMapper === "function" ? fullMapper(key) : fullMapper[key];
|
|
516
|
-
};
|
|
517
|
-
//# sourceMappingURL=index.js.map
|
package/lib/cjs/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|