@zenstackhq/runtime 3.0.0-alpha.8 → 3.0.0-beta.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.
- package/dist/{contract-BnvK1nW0.d.cts → contract-CusA0mQO.d.cts} +447 -314
- package/dist/{contract-BnvK1nW0.d.ts → contract-CusA0mQO.d.ts} +447 -314
- package/dist/helpers.cjs +31 -0
- package/dist/helpers.cjs.map +1 -0
- package/dist/helpers.d.cts +1 -0
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.js +6 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.cjs +2523 -1385
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -5
- package/dist/index.d.ts +29 -5
- package/dist/index.js +2382 -1250
- package/dist/index.js.map +1 -1
- package/dist/plugins/{policy.cjs → policy/index.cjs} +628 -310
- package/dist/plugins/policy/index.cjs.map +1 -0
- package/dist/plugins/{policy.d.ts → policy/index.d.cts} +2 -2
- package/dist/plugins/{policy.d.cts → policy/index.d.ts} +2 -2
- package/dist/plugins/{policy.js → policy/index.js} +631 -313
- package/dist/plugins/policy/index.js.map +1 -0
- package/dist/plugins/policy/plugin.zmodel +33 -0
- package/dist/schema.cjs +4 -1
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +1 -0
- package/dist/schema.d.ts +1 -0
- package/dist/schema.js +4 -1
- package/dist/schema.js.map +1 -1
- package/package.json +28 -24
- package/dist/client.cjs +0 -6150
- package/dist/client.cjs.map +0 -1
- package/dist/client.d.cts +0 -17
- package/dist/client.d.ts +0 -17
- package/dist/client.js +0 -6115
- package/dist/client.js.map +0 -1
- package/dist/plugins/policy.cjs.map +0 -1
- package/dist/plugins/policy.js.map +0 -1
|
@@ -41,32 +41,131 @@ var RejectedByPolicyError = class extends Error {
|
|
|
41
41
|
// src/plugins/policy/policy-handler.ts
|
|
42
42
|
var import_common_helpers6 = require("@zenstackhq/common-helpers");
|
|
43
43
|
var import_kysely7 = require("kysely");
|
|
44
|
-
var
|
|
44
|
+
var import_ts_pattern8 = require("ts-pattern");
|
|
45
45
|
|
|
46
46
|
// src/client/crud/dialects/index.ts
|
|
47
|
-
var
|
|
47
|
+
var import_ts_pattern5 = require("ts-pattern");
|
|
48
48
|
|
|
49
49
|
// src/client/crud/dialects/postgresql.ts
|
|
50
50
|
var import_common_helpers2 = require("@zenstackhq/common-helpers");
|
|
51
51
|
var import_kysely2 = require("kysely");
|
|
52
|
-
var
|
|
52
|
+
var import_ts_pattern3 = require("ts-pattern");
|
|
53
|
+
|
|
54
|
+
// src/client/constants.ts
|
|
55
|
+
var DELEGATE_JOINED_FIELD_PREFIX = "$delegate$";
|
|
56
|
+
var LOGICAL_COMBINATORS = [
|
|
57
|
+
"AND",
|
|
58
|
+
"OR",
|
|
59
|
+
"NOT"
|
|
60
|
+
];
|
|
61
|
+
var AGGREGATE_OPERATORS = [
|
|
62
|
+
"_count",
|
|
63
|
+
"_sum",
|
|
64
|
+
"_avg",
|
|
65
|
+
"_min",
|
|
66
|
+
"_max"
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
// src/client/query-utils.ts
|
|
70
|
+
var import_ts_pattern = require("ts-pattern");
|
|
71
|
+
|
|
72
|
+
// src/schema/expression.ts
|
|
73
|
+
var ExpressionUtils = {
|
|
74
|
+
literal: /* @__PURE__ */ __name((value) => {
|
|
75
|
+
return {
|
|
76
|
+
kind: "literal",
|
|
77
|
+
value
|
|
78
|
+
};
|
|
79
|
+
}, "literal"),
|
|
80
|
+
array: /* @__PURE__ */ __name((items) => {
|
|
81
|
+
return {
|
|
82
|
+
kind: "array",
|
|
83
|
+
items
|
|
84
|
+
};
|
|
85
|
+
}, "array"),
|
|
86
|
+
call: /* @__PURE__ */ __name((functionName, args) => {
|
|
87
|
+
return {
|
|
88
|
+
kind: "call",
|
|
89
|
+
function: functionName,
|
|
90
|
+
args
|
|
91
|
+
};
|
|
92
|
+
}, "call"),
|
|
93
|
+
binary: /* @__PURE__ */ __name((left, op, right) => {
|
|
94
|
+
return {
|
|
95
|
+
kind: "binary",
|
|
96
|
+
op,
|
|
97
|
+
left,
|
|
98
|
+
right
|
|
99
|
+
};
|
|
100
|
+
}, "binary"),
|
|
101
|
+
unary: /* @__PURE__ */ __name((op, operand) => {
|
|
102
|
+
return {
|
|
103
|
+
kind: "unary",
|
|
104
|
+
op,
|
|
105
|
+
operand
|
|
106
|
+
};
|
|
107
|
+
}, "unary"),
|
|
108
|
+
field: /* @__PURE__ */ __name((field) => {
|
|
109
|
+
return {
|
|
110
|
+
kind: "field",
|
|
111
|
+
field
|
|
112
|
+
};
|
|
113
|
+
}, "field"),
|
|
114
|
+
member: /* @__PURE__ */ __name((receiver, members) => {
|
|
115
|
+
return {
|
|
116
|
+
kind: "member",
|
|
117
|
+
receiver,
|
|
118
|
+
members
|
|
119
|
+
};
|
|
120
|
+
}, "member"),
|
|
121
|
+
_this: /* @__PURE__ */ __name(() => {
|
|
122
|
+
return {
|
|
123
|
+
kind: "this"
|
|
124
|
+
};
|
|
125
|
+
}, "_this"),
|
|
126
|
+
_null: /* @__PURE__ */ __name(() => {
|
|
127
|
+
return {
|
|
128
|
+
kind: "null"
|
|
129
|
+
};
|
|
130
|
+
}, "_null"),
|
|
131
|
+
and: /* @__PURE__ */ __name((expr2, ...expressions) => {
|
|
132
|
+
return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "&&", exp), expr2);
|
|
133
|
+
}, "and"),
|
|
134
|
+
or: /* @__PURE__ */ __name((expr2, ...expressions) => {
|
|
135
|
+
return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "||", exp), expr2);
|
|
136
|
+
}, "or"),
|
|
137
|
+
is: /* @__PURE__ */ __name((value, kind) => {
|
|
138
|
+
return !!value && typeof value === "object" && "kind" in value && value.kind === kind;
|
|
139
|
+
}, "is"),
|
|
140
|
+
isLiteral: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "literal"), "isLiteral"),
|
|
141
|
+
isArray: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "array"), "isArray"),
|
|
142
|
+
isCall: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "call"), "isCall"),
|
|
143
|
+
isNull: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "null"), "isNull"),
|
|
144
|
+
isThis: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "this"), "isThis"),
|
|
145
|
+
isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
|
|
146
|
+
isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
|
|
147
|
+
isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
|
|
148
|
+
isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember"),
|
|
149
|
+
getLiteralValue: /* @__PURE__ */ __name((expr2) => {
|
|
150
|
+
return ExpressionUtils.isLiteral(expr2) ? expr2.value : void 0;
|
|
151
|
+
}, "getLiteralValue")
|
|
152
|
+
};
|
|
53
153
|
|
|
54
154
|
// src/client/errors.ts
|
|
55
155
|
var QueryError = class extends Error {
|
|
56
156
|
static {
|
|
57
157
|
__name(this, "QueryError");
|
|
58
158
|
}
|
|
59
|
-
constructor(message) {
|
|
60
|
-
super(message
|
|
159
|
+
constructor(message, cause) {
|
|
160
|
+
super(message, {
|
|
161
|
+
cause
|
|
162
|
+
});
|
|
61
163
|
}
|
|
62
164
|
};
|
|
63
165
|
var InternalError = class extends Error {
|
|
64
166
|
static {
|
|
65
167
|
__name(this, "InternalError");
|
|
66
168
|
}
|
|
67
|
-
constructor(message) {
|
|
68
|
-
super(message);
|
|
69
|
-
}
|
|
70
169
|
};
|
|
71
170
|
|
|
72
171
|
// src/client/query-utils.ts
|
|
@@ -77,7 +176,7 @@ __name(getModel, "getModel");
|
|
|
77
176
|
function requireModel(schema, model) {
|
|
78
177
|
const matchedName = Object.keys(schema.models).find((k) => k.toLowerCase() === model.toLowerCase());
|
|
79
178
|
if (!matchedName) {
|
|
80
|
-
throw new QueryError(`Model "${model}" not found`);
|
|
179
|
+
throw new QueryError(`Model "${model}" not found in schema`);
|
|
81
180
|
}
|
|
82
181
|
return schema.models[matchedName];
|
|
83
182
|
}
|
|
@@ -140,6 +239,16 @@ function getRelationForeignKeyFieldPairs(schema, model, relationField) {
|
|
|
140
239
|
}
|
|
141
240
|
}
|
|
142
241
|
__name(getRelationForeignKeyFieldPairs, "getRelationForeignKeyFieldPairs");
|
|
242
|
+
function isRelationField(schema, model, field) {
|
|
243
|
+
const fieldDef = getField(schema, model, field);
|
|
244
|
+
return !!fieldDef?.relation;
|
|
245
|
+
}
|
|
246
|
+
__name(isRelationField, "isRelationField");
|
|
247
|
+
function isInheritedField(schema, model, field) {
|
|
248
|
+
const fieldDef = getField(schema, model, field);
|
|
249
|
+
return !!fieldDef?.originModel;
|
|
250
|
+
}
|
|
251
|
+
__name(isInheritedField, "isInheritedField");
|
|
143
252
|
function getUniqueFields(schema, model) {
|
|
144
253
|
const modelDef = requireModel(schema, model);
|
|
145
254
|
const result = [];
|
|
@@ -165,20 +274,25 @@ function getUniqueFields(schema, model) {
|
|
|
165
274
|
return result;
|
|
166
275
|
}
|
|
167
276
|
__name(getUniqueFields, "getUniqueFields");
|
|
168
|
-
function buildFieldRef(schema, model, field, options, eb, modelAlias) {
|
|
277
|
+
function buildFieldRef(schema, model, field, options, eb, modelAlias, inlineComputedField = true) {
|
|
169
278
|
const fieldDef = requireField(schema, model, field);
|
|
170
279
|
if (!fieldDef.computed) {
|
|
171
280
|
return eb.ref(modelAlias ? `${modelAlias}.${field}` : field);
|
|
172
281
|
} else {
|
|
282
|
+
if (!inlineComputedField) {
|
|
283
|
+
return eb.ref(modelAlias ? `${modelAlias}.${field}` : field);
|
|
284
|
+
}
|
|
173
285
|
let computer;
|
|
174
286
|
if ("computedFields" in options) {
|
|
175
287
|
const computedFields = options.computedFields;
|
|
176
288
|
computer = computedFields?.[model]?.[field];
|
|
177
289
|
}
|
|
178
290
|
if (!computer) {
|
|
179
|
-
throw new QueryError(`Computed field "${field}" implementation not provided`);
|
|
291
|
+
throw new QueryError(`Computed field "${field}" implementation not provided for model "${model}"`);
|
|
180
292
|
}
|
|
181
|
-
return computer(eb
|
|
293
|
+
return computer(eb, {
|
|
294
|
+
currentModel: modelAlias
|
|
295
|
+
});
|
|
182
296
|
}
|
|
183
297
|
}
|
|
184
298
|
__name(buildFieldRef, "buildFieldRef");
|
|
@@ -221,11 +335,33 @@ function getManyToManyRelation(schema, model, field) {
|
|
|
221
335
|
model,
|
|
222
336
|
fieldDef.type
|
|
223
337
|
].sort();
|
|
338
|
+
let orderedFK;
|
|
339
|
+
if (model !== fieldDef.type) {
|
|
340
|
+
orderedFK = sortedModelNames[0] === model ? [
|
|
341
|
+
"A",
|
|
342
|
+
"B"
|
|
343
|
+
] : [
|
|
344
|
+
"B",
|
|
345
|
+
"A"
|
|
346
|
+
];
|
|
347
|
+
} else {
|
|
348
|
+
const sortedFieldNames = [
|
|
349
|
+
field,
|
|
350
|
+
oppositeFieldDef.name
|
|
351
|
+
].sort();
|
|
352
|
+
orderedFK = sortedFieldNames[0] === field ? [
|
|
353
|
+
"A",
|
|
354
|
+
"B"
|
|
355
|
+
] : [
|
|
356
|
+
"B",
|
|
357
|
+
"A"
|
|
358
|
+
];
|
|
359
|
+
}
|
|
224
360
|
return {
|
|
225
|
-
parentFkName:
|
|
361
|
+
parentFkName: orderedFK[0],
|
|
226
362
|
otherModel: fieldDef.type,
|
|
227
363
|
otherField: fieldDef.relation.opposite,
|
|
228
|
-
otherFkName:
|
|
364
|
+
otherFkName: orderedFK[1],
|
|
229
365
|
joinTable: fieldDef.relation.name ? `_${fieldDef.relation.name}` : `_${sortedModelNames[0]}To${sortedModelNames[1]}`
|
|
230
366
|
};
|
|
231
367
|
} else {
|
|
@@ -253,11 +389,38 @@ function flattenCompoundUniqueFilters(schema, model, filter) {
|
|
|
253
389
|
return result;
|
|
254
390
|
}
|
|
255
391
|
__name(flattenCompoundUniqueFilters, "flattenCompoundUniqueFilters");
|
|
392
|
+
function ensureArray(value) {
|
|
393
|
+
if (Array.isArray(value)) {
|
|
394
|
+
return value;
|
|
395
|
+
} else {
|
|
396
|
+
return [
|
|
397
|
+
value
|
|
398
|
+
];
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
__name(ensureArray, "ensureArray");
|
|
402
|
+
function getDelegateDescendantModels(schema, model, collected = /* @__PURE__ */ new Set()) {
|
|
403
|
+
const subModels = Object.values(schema.models).filter((m) => m.baseModel === model);
|
|
404
|
+
subModels.forEach((def) => {
|
|
405
|
+
if (!collected.has(def)) {
|
|
406
|
+
collected.add(def);
|
|
407
|
+
getDelegateDescendantModels(schema, def.name, collected);
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
return [
|
|
411
|
+
...collected
|
|
412
|
+
];
|
|
413
|
+
}
|
|
414
|
+
__name(getDelegateDescendantModels, "getDelegateDescendantModels");
|
|
415
|
+
function aggregate(eb, expr2, op) {
|
|
416
|
+
return (0, import_ts_pattern.match)(op).with("_count", () => eb.fn.count(expr2)).with("_sum", () => eb.fn.sum(expr2)).with("_avg", () => eb.fn.avg(expr2)).with("_min", () => eb.fn.min(expr2)).with("_max", () => eb.fn.max(expr2)).exhaustive();
|
|
417
|
+
}
|
|
418
|
+
__name(aggregate, "aggregate");
|
|
256
419
|
|
|
257
420
|
// src/client/crud/dialects/base.ts
|
|
258
421
|
var import_common_helpers = require("@zenstackhq/common-helpers");
|
|
259
422
|
var import_kysely = require("kysely");
|
|
260
|
-
var
|
|
423
|
+
var import_ts_pattern2 = require("ts-pattern");
|
|
261
424
|
|
|
262
425
|
// src/utils/enumerate.ts
|
|
263
426
|
function enumerate(x) {
|
|
@@ -284,9 +447,47 @@ var BaseCrudDialect = class {
|
|
|
284
447
|
this.schema = schema;
|
|
285
448
|
this.options = options;
|
|
286
449
|
}
|
|
287
|
-
transformPrimitive(value, _type) {
|
|
450
|
+
transformPrimitive(value, _type, _forArrayField) {
|
|
288
451
|
return value;
|
|
289
452
|
}
|
|
453
|
+
// #region common query builders
|
|
454
|
+
buildSelectModel(eb, model, modelAlias) {
|
|
455
|
+
const modelDef = requireModel(this.schema, model);
|
|
456
|
+
let result = eb.selectFrom(model === modelAlias ? model : `${model} as ${modelAlias}`);
|
|
457
|
+
let joinBase = modelDef.baseModel;
|
|
458
|
+
while (joinBase) {
|
|
459
|
+
result = this.buildDelegateJoin(model, modelAlias, joinBase, result);
|
|
460
|
+
joinBase = requireModel(this.schema, joinBase).baseModel;
|
|
461
|
+
}
|
|
462
|
+
return result;
|
|
463
|
+
}
|
|
464
|
+
buildFilterSortTake(model, args, query, modelAlias) {
|
|
465
|
+
let result = query;
|
|
466
|
+
if (args.where) {
|
|
467
|
+
result = result.where((eb) => this.buildFilter(eb, model, modelAlias, args?.where));
|
|
468
|
+
}
|
|
469
|
+
let negateOrderBy = false;
|
|
470
|
+
const skip = args.skip;
|
|
471
|
+
let take = args.take;
|
|
472
|
+
if (take !== void 0 && take < 0) {
|
|
473
|
+
negateOrderBy = true;
|
|
474
|
+
take = -take;
|
|
475
|
+
}
|
|
476
|
+
result = this.buildSkipTake(result, skip, take);
|
|
477
|
+
result = this.buildOrderBy(result, model, modelAlias, args.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
|
|
478
|
+
if ("distinct" in args && args.distinct) {
|
|
479
|
+
const distinct = ensureArray(args.distinct);
|
|
480
|
+
if (this.supportsDistinctOn) {
|
|
481
|
+
result = result.distinctOn(distinct.map((f) => import_kysely.sql.ref(`${modelAlias}.${f}`)));
|
|
482
|
+
} else {
|
|
483
|
+
throw new QueryError(`"distinct" is not supported by "${this.schema.provider.type}" provider`);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
if (args.cursor) {
|
|
487
|
+
result = this.buildCursorFilter(model, result, args.cursor, args.orderBy, negateOrderBy, modelAlias);
|
|
488
|
+
}
|
|
489
|
+
return result;
|
|
490
|
+
}
|
|
290
491
|
buildFilter(eb, model, modelAlias, where) {
|
|
291
492
|
if (where === true || where === void 0) {
|
|
292
493
|
return this.true(eb);
|
|
@@ -303,17 +504,20 @@ var BaseCrudDialect = class {
|
|
|
303
504
|
if (key.startsWith("$")) {
|
|
304
505
|
continue;
|
|
305
506
|
}
|
|
306
|
-
if (key
|
|
507
|
+
if (this.isLogicalCombinator(key)) {
|
|
307
508
|
result = this.and(eb, result, this.buildCompositeFilter(eb, model, modelAlias, key, payload));
|
|
308
509
|
continue;
|
|
309
510
|
}
|
|
310
511
|
const fieldDef = requireField(this.schema, model, key);
|
|
311
512
|
if (fieldDef.relation) {
|
|
312
513
|
result = this.and(eb, result, this.buildRelationFilter(eb, model, modelAlias, key, fieldDef, payload));
|
|
313
|
-
} else if (fieldDef.array) {
|
|
314
|
-
result = this.and(eb, result, this.buildArrayFilter(eb, model, modelAlias, key, fieldDef, payload));
|
|
315
514
|
} else {
|
|
316
|
-
|
|
515
|
+
const fieldRef = this.fieldRef(fieldDef.originModel ?? model, key, eb, fieldDef.originModel ?? modelAlias);
|
|
516
|
+
if (fieldDef.array) {
|
|
517
|
+
result = this.and(eb, result, this.buildArrayFilter(eb, fieldRef, fieldDef, payload));
|
|
518
|
+
} else {
|
|
519
|
+
result = this.and(eb, result, this.buildPrimitiveFilter(eb, fieldRef, fieldDef, payload));
|
|
520
|
+
}
|
|
317
521
|
}
|
|
318
522
|
}
|
|
319
523
|
if ("$expr" in _where && typeof _where["$expr"] === "function") {
|
|
@@ -321,8 +525,32 @@ var BaseCrudDialect = class {
|
|
|
321
525
|
}
|
|
322
526
|
return result;
|
|
323
527
|
}
|
|
528
|
+
buildCursorFilter(model, query, cursor, orderBy, negateOrderBy, modelAlias) {
|
|
529
|
+
const _orderBy = orderBy ?? makeDefaultOrderBy(this.schema, model);
|
|
530
|
+
const orderByItems = ensureArray(_orderBy).flatMap((obj) => Object.entries(obj));
|
|
531
|
+
const eb = (0, import_kysely.expressionBuilder)();
|
|
532
|
+
const subQueryAlias = `${model}$cursor$sub`;
|
|
533
|
+
const cursorFilter = this.buildFilter(eb, model, subQueryAlias, cursor);
|
|
534
|
+
let result = query;
|
|
535
|
+
const filters = [];
|
|
536
|
+
for (let i = orderByItems.length - 1; i >= 0; i--) {
|
|
537
|
+
const andFilters = [];
|
|
538
|
+
for (let j = 0; j <= i; j++) {
|
|
539
|
+
const [field, order] = orderByItems[j];
|
|
540
|
+
const _order = negateOrderBy ? order === "asc" ? "desc" : "asc" : order;
|
|
541
|
+
const op = j === i ? _order === "asc" ? ">=" : "<=" : "=";
|
|
542
|
+
andFilters.push(eb(eb.ref(`${modelAlias}.${field}`), op, this.buildSelectModel(eb, model, subQueryAlias).select(`${subQueryAlias}.${field}`).where(cursorFilter)));
|
|
543
|
+
}
|
|
544
|
+
filters.push(eb.and(andFilters));
|
|
545
|
+
}
|
|
546
|
+
result = result.where((eb2) => eb2.or(filters));
|
|
547
|
+
return result;
|
|
548
|
+
}
|
|
549
|
+
isLogicalCombinator(key) {
|
|
550
|
+
return LOGICAL_COMBINATORS.includes(key);
|
|
551
|
+
}
|
|
324
552
|
buildCompositeFilter(eb, model, modelAlias, key, payload) {
|
|
325
|
-
return (0,
|
|
553
|
+
return (0, import_ts_pattern2.match)(key).with("AND", () => this.and(eb, ...enumerate(payload).map((subPayload) => this.buildFilter(eb, model, modelAlias, subPayload)))).with("OR", () => this.or(eb, ...enumerate(payload).map((subPayload) => this.buildFilter(eb, model, modelAlias, subPayload)))).with("NOT", () => eb.not(this.buildCompositeFilter(eb, model, modelAlias, "AND", payload))).exhaustive();
|
|
326
554
|
}
|
|
327
555
|
buildRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
|
|
328
556
|
if (!fieldDef.array) {
|
|
@@ -331,19 +559,26 @@ var BaseCrudDialect = class {
|
|
|
331
559
|
return this.buildToManyRelationFilter(eb, model, modelAlias, field, fieldDef, payload);
|
|
332
560
|
}
|
|
333
561
|
}
|
|
334
|
-
buildToOneRelationFilter(eb, model,
|
|
562
|
+
buildToOneRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
|
|
335
563
|
if (payload === null) {
|
|
336
564
|
const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, model, field);
|
|
337
|
-
if (ownedByModel) {
|
|
338
|
-
return this.and(eb, ...keyPairs.map(({ fk }) => eb(import_kysely.sql.ref(`${
|
|
565
|
+
if (ownedByModel && !fieldDef.originModel) {
|
|
566
|
+
return this.and(eb, ...keyPairs.map(({ fk }) => eb(import_kysely.sql.ref(`${modelAlias}.${fk}`), "is", null)));
|
|
339
567
|
} else {
|
|
340
|
-
return this.buildToOneRelationFilter(eb, model,
|
|
568
|
+
return this.buildToOneRelationFilter(eb, model, modelAlias, field, fieldDef, {
|
|
341
569
|
is: null
|
|
342
570
|
});
|
|
343
571
|
}
|
|
344
572
|
}
|
|
345
|
-
const joinAlias = `${
|
|
346
|
-
const joinPairs = buildJoinPairs(
|
|
573
|
+
const joinAlias = `${modelAlias}$${field}`;
|
|
574
|
+
const joinPairs = buildJoinPairs(
|
|
575
|
+
this.schema,
|
|
576
|
+
model,
|
|
577
|
+
// if field is from a base, use the base model to join
|
|
578
|
+
fieldDef.originModel ?? modelAlias,
|
|
579
|
+
field,
|
|
580
|
+
joinAlias
|
|
581
|
+
);
|
|
347
582
|
const filterResultField = `${field}$filter`;
|
|
348
583
|
const joinSelect = eb.selectFrom(`${fieldDef.type} as ${joinAlias}`).where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely.sql.ref(left), "=", import_kysely.sql.ref(right))))).select(() => eb.fn.count(eb.lit(1)).as(filterResultField));
|
|
349
584
|
const conditions = [];
|
|
@@ -373,25 +608,26 @@ var BaseCrudDialect = class {
|
|
|
373
608
|
}
|
|
374
609
|
return this.and(eb, ...conditions);
|
|
375
610
|
}
|
|
376
|
-
buildToManyRelationFilter(eb, model,
|
|
611
|
+
buildToManyRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
|
|
377
612
|
if (payload === null) {
|
|
378
|
-
return eb(import_kysely.sql.ref(`${
|
|
613
|
+
return eb(import_kysely.sql.ref(`${modelAlias}.${field}`), "is", null);
|
|
379
614
|
}
|
|
380
615
|
const relationModel = fieldDef.type;
|
|
616
|
+
const relationFilterSelectAlias = `${modelAlias}$${field}$filter`;
|
|
381
617
|
const buildPkFkWhereRefs = /* @__PURE__ */ __name((eb2) => {
|
|
382
618
|
const m2m = getManyToManyRelation(this.schema, model, field);
|
|
383
619
|
if (m2m) {
|
|
384
620
|
const modelIdField = getIdFields(this.schema, model)[0];
|
|
385
621
|
const relationIdField = getIdFields(this.schema, relationModel)[0];
|
|
386
|
-
return eb2(import_kysely.sql.ref(`${
|
|
622
|
+
return eb2(import_kysely.sql.ref(`${relationFilterSelectAlias}.${relationIdField}`), "in", eb2.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(import_kysely.sql.ref(`${m2m.joinTable}.${m2m.parentFkName}`), "=", import_kysely.sql.ref(`${modelAlias}.${modelIdField}`)));
|
|
387
623
|
} else {
|
|
388
624
|
const relationKeyPairs = getRelationForeignKeyFieldPairs(this.schema, model, field);
|
|
389
625
|
let result2 = this.true(eb2);
|
|
390
626
|
for (const { fk, pk } of relationKeyPairs.keyPairs) {
|
|
391
627
|
if (relationKeyPairs.ownedByModel) {
|
|
392
|
-
result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${
|
|
628
|
+
result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${modelAlias}.${fk}`), "=", import_kysely.sql.ref(`${relationFilterSelectAlias}.${pk}`)));
|
|
393
629
|
} else {
|
|
394
|
-
result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${
|
|
630
|
+
result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${modelAlias}.${pk}`), "=", import_kysely.sql.ref(`${relationFilterSelectAlias}.${fk}`)));
|
|
395
631
|
}
|
|
396
632
|
}
|
|
397
633
|
return result2;
|
|
@@ -404,30 +640,29 @@ var BaseCrudDialect = class {
|
|
|
404
640
|
}
|
|
405
641
|
switch (key) {
|
|
406
642
|
case "some": {
|
|
407
|
-
result = this.and(eb, result, eb(
|
|
643
|
+
result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel, relationFilterSelectAlias).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationFilterSelectAlias, subPayload)), ">", 0));
|
|
408
644
|
break;
|
|
409
645
|
}
|
|
410
646
|
case "every": {
|
|
411
|
-
result = this.and(eb, result, eb(
|
|
647
|
+
result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel, relationFilterSelectAlias).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => eb1.not(this.buildFilter(eb1, relationModel, relationFilterSelectAlias, subPayload))), "=", 0));
|
|
412
648
|
break;
|
|
413
649
|
}
|
|
414
650
|
case "none": {
|
|
415
|
-
result = this.and(eb, result, eb(
|
|
651
|
+
result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel, relationFilterSelectAlias).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationFilterSelectAlias, subPayload)), "=", 0));
|
|
416
652
|
break;
|
|
417
653
|
}
|
|
418
654
|
}
|
|
419
655
|
}
|
|
420
656
|
return result;
|
|
421
657
|
}
|
|
422
|
-
buildArrayFilter(eb,
|
|
658
|
+
buildArrayFilter(eb, fieldRef, fieldDef, payload) {
|
|
423
659
|
const clauses = [];
|
|
424
660
|
const fieldType = fieldDef.type;
|
|
425
|
-
const fieldRef = buildFieldRef(this.schema, model, field, this.options, eb, modelAlias);
|
|
426
661
|
for (const [key, _value] of Object.entries(payload)) {
|
|
427
662
|
if (_value === void 0) {
|
|
428
663
|
continue;
|
|
429
664
|
}
|
|
430
|
-
const value = this.transformPrimitive(_value, fieldType);
|
|
665
|
+
const value = this.transformPrimitive(_value, fieldType, !!fieldDef.array);
|
|
431
666
|
switch (key) {
|
|
432
667
|
case "equals": {
|
|
433
668
|
clauses.push(this.buildLiteralFilter(eb, fieldRef, fieldType, eb.val(value)));
|
|
@@ -458,19 +693,23 @@ var BaseCrudDialect = class {
|
|
|
458
693
|
}
|
|
459
694
|
return this.and(eb, ...clauses);
|
|
460
695
|
}
|
|
461
|
-
buildPrimitiveFilter(eb,
|
|
696
|
+
buildPrimitiveFilter(eb, fieldRef, fieldDef, payload) {
|
|
462
697
|
if (payload === null) {
|
|
463
|
-
return eb(
|
|
698
|
+
return eb(fieldRef, "is", null);
|
|
464
699
|
}
|
|
465
700
|
if (isEnum(this.schema, fieldDef.type)) {
|
|
466
|
-
return this.buildEnumFilter(eb,
|
|
701
|
+
return this.buildEnumFilter(eb, fieldRef, fieldDef, payload);
|
|
467
702
|
}
|
|
468
|
-
return (0,
|
|
703
|
+
return (0, import_ts_pattern2.match)(fieldDef.type).with("String", () => this.buildStringFilter(eb, fieldRef, payload)).with(import_ts_pattern2.P.union("Int", "Float", "Decimal", "BigInt"), (type) => this.buildNumberFilter(eb, fieldRef, type, payload)).with("Boolean", () => this.buildBooleanFilter(eb, fieldRef, payload)).with("DateTime", () => this.buildDateTimeFilter(eb, fieldRef, payload)).with("Bytes", () => this.buildBytesFilter(eb, fieldRef, payload)).with("Json", () => {
|
|
704
|
+
throw new InternalError("JSON filters are not supported yet");
|
|
705
|
+
}).with("Unsupported", () => {
|
|
706
|
+
throw new QueryError(`Unsupported field cannot be used in filters`);
|
|
707
|
+
}).exhaustive();
|
|
469
708
|
}
|
|
470
709
|
buildLiteralFilter(eb, lhs, type, rhs) {
|
|
471
|
-
return eb(lhs, "=", rhs !== null && rhs !== void 0 ? this.transformPrimitive(rhs, type) : rhs);
|
|
710
|
+
return eb(lhs, "=", rhs !== null && rhs !== void 0 ? this.transformPrimitive(rhs, type, false) : rhs);
|
|
472
711
|
}
|
|
473
|
-
buildStandardFilter(eb, type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0) {
|
|
712
|
+
buildStandardFilter(eb, type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0, excludeKeys = []) {
|
|
474
713
|
if (payload === null || !(0, import_common_helpers.isPlainObject)(payload)) {
|
|
475
714
|
return {
|
|
476
715
|
conditions: [
|
|
@@ -485,8 +724,11 @@ var BaseCrudDialect = class {
|
|
|
485
724
|
if (onlyForKeys && !onlyForKeys.includes(op)) {
|
|
486
725
|
continue;
|
|
487
726
|
}
|
|
727
|
+
if (excludeKeys.includes(op)) {
|
|
728
|
+
continue;
|
|
729
|
+
}
|
|
488
730
|
const rhs = Array.isArray(value) ? value.map(getRhs) : getRhs(value);
|
|
489
|
-
const condition = (0,
|
|
731
|
+
const condition = (0, import_ts_pattern2.match)(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
|
|
490
732
|
(0, import_common_helpers.invariant)(Array.isArray(rhs), "right hand side must be an array");
|
|
491
733
|
if (rhs.length === 0) {
|
|
492
734
|
return this.false(eb);
|
|
@@ -500,7 +742,11 @@ var BaseCrudDialect = class {
|
|
|
500
742
|
} else {
|
|
501
743
|
return eb.not(eb(lhs, "in", rhs));
|
|
502
744
|
}
|
|
503
|
-
}).with("lt", () => eb(lhs, "<", rhs)).with("lte", () => eb(lhs, "<=", rhs)).with("gt", () => eb(lhs, ">", rhs)).with("gte", () => eb(lhs, ">=", rhs)).with("not", () => eb.not(recurse(value))).
|
|
745
|
+
}).with("lt", () => eb(lhs, "<", rhs)).with("lte", () => eb(lhs, "<=", rhs)).with("gt", () => eb(lhs, ">", rhs)).with("gte", () => eb(lhs, ">=", rhs)).with("not", () => eb.not(recurse(value))).with(import_ts_pattern2.P.union(...AGGREGATE_OPERATORS), (op2) => {
|
|
746
|
+
const innerResult = this.buildStandardFilter(eb, type, value, aggregate(eb, lhs, op2), getRhs, recurse, throwIfInvalid);
|
|
747
|
+
consumedKeys.push(...innerResult.consumedKeys);
|
|
748
|
+
return this.and(eb, ...innerResult.conditions);
|
|
749
|
+
}).otherwise(() => {
|
|
504
750
|
if (throwIfInvalid) {
|
|
505
751
|
throw new QueryError(`Invalid filter key: ${op}`);
|
|
506
752
|
} else {
|
|
@@ -517,24 +763,21 @@ var BaseCrudDialect = class {
|
|
|
517
763
|
consumedKeys
|
|
518
764
|
};
|
|
519
765
|
}
|
|
520
|
-
buildStringFilter(eb,
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
if (payload && typeof payload === "object" && "mode" in payload && payload.mode === "insensitive") {
|
|
525
|
-
insensitive = true;
|
|
526
|
-
fieldRef = eb.fn("lower", [
|
|
527
|
-
fieldRef
|
|
528
|
-
]);
|
|
766
|
+
buildStringFilter(eb, fieldRef, payload) {
|
|
767
|
+
let mode;
|
|
768
|
+
if (payload && typeof payload === "object" && "mode" in payload) {
|
|
769
|
+
mode = payload.mode;
|
|
529
770
|
}
|
|
530
|
-
const { conditions, consumedKeys } = this.buildStandardFilter(eb, "String", payload,
|
|
771
|
+
const { conditions, consumedKeys } = this.buildStandardFilter(eb, "String", payload, mode === "insensitive" ? eb.fn("lower", [
|
|
772
|
+
fieldRef
|
|
773
|
+
]) : fieldRef, (value) => this.prepStringCasing(eb, value, mode), (value) => this.buildStringFilter(eb, fieldRef, value));
|
|
531
774
|
if (payload && typeof payload === "object") {
|
|
532
775
|
for (const [key, value] of Object.entries(payload)) {
|
|
533
776
|
if (key === "mode" || consumedKeys.includes(key)) {
|
|
534
777
|
continue;
|
|
535
778
|
}
|
|
536
|
-
const condition = (0,
|
|
537
|
-
throw new
|
|
779
|
+
const condition = (0, import_ts_pattern2.match)(key).with("contains", () => mode === "insensitive" ? eb(fieldRef, "ilike", import_kysely.sql.val(`%${value}%`)) : eb(fieldRef, "like", import_kysely.sql.val(`%${value}%`))).with("startsWith", () => mode === "insensitive" ? eb(fieldRef, "ilike", import_kysely.sql.val(`${value}%`)) : eb(fieldRef, "like", import_kysely.sql.val(`${value}%`))).with("endsWith", () => mode === "insensitive" ? eb(fieldRef, "ilike", import_kysely.sql.val(`%${value}`)) : eb(fieldRef, "like", import_kysely.sql.val(`%${value}`))).otherwise(() => {
|
|
780
|
+
throw new QueryError(`Invalid string filter key: ${key}`);
|
|
538
781
|
});
|
|
539
782
|
if (condition) {
|
|
540
783
|
conditions.push(condition);
|
|
@@ -543,34 +786,37 @@ var BaseCrudDialect = class {
|
|
|
543
786
|
}
|
|
544
787
|
return this.and(eb, ...conditions);
|
|
545
788
|
}
|
|
546
|
-
prepStringCasing(eb, value,
|
|
789
|
+
prepStringCasing(eb, value, mode) {
|
|
790
|
+
if (!mode || mode === "default") {
|
|
791
|
+
return value === null ? value : import_kysely.sql.val(value);
|
|
792
|
+
}
|
|
547
793
|
if (typeof value === "string") {
|
|
548
|
-
return
|
|
549
|
-
import_kysely.sql.
|
|
550
|
-
])
|
|
794
|
+
return eb.fn("lower", [
|
|
795
|
+
import_kysely.sql.val(value)
|
|
796
|
+
]);
|
|
551
797
|
} else if (Array.isArray(value)) {
|
|
552
|
-
return value.map((v) => this.prepStringCasing(eb, v,
|
|
798
|
+
return value.map((v) => this.prepStringCasing(eb, v, mode));
|
|
553
799
|
} else {
|
|
554
|
-
return value === null ? null : import_kysely.sql.
|
|
800
|
+
return value === null ? null : import_kysely.sql.val(value);
|
|
555
801
|
}
|
|
556
802
|
}
|
|
557
|
-
buildNumberFilter(eb,
|
|
558
|
-
const { conditions } = this.buildStandardFilter(eb, type, payload,
|
|
803
|
+
buildNumberFilter(eb, fieldRef, type, payload) {
|
|
804
|
+
const { conditions } = this.buildStandardFilter(eb, type, payload, fieldRef, (value) => this.transformPrimitive(value, type, false), (value) => this.buildNumberFilter(eb, fieldRef, type, value));
|
|
559
805
|
return this.and(eb, ...conditions);
|
|
560
806
|
}
|
|
561
|
-
buildBooleanFilter(eb,
|
|
562
|
-
const { conditions } = this.buildStandardFilter(eb, "Boolean", payload,
|
|
807
|
+
buildBooleanFilter(eb, fieldRef, payload) {
|
|
808
|
+
const { conditions } = this.buildStandardFilter(eb, "Boolean", payload, fieldRef, (value) => this.transformPrimitive(value, "Boolean", false), (value) => this.buildBooleanFilter(eb, fieldRef, value), true, [
|
|
563
809
|
"equals",
|
|
564
810
|
"not"
|
|
565
811
|
]);
|
|
566
812
|
return this.and(eb, ...conditions);
|
|
567
813
|
}
|
|
568
|
-
buildDateTimeFilter(eb,
|
|
569
|
-
const { conditions } = this.buildStandardFilter(eb, "DateTime", payload,
|
|
814
|
+
buildDateTimeFilter(eb, fieldRef, payload) {
|
|
815
|
+
const { conditions } = this.buildStandardFilter(eb, "DateTime", payload, fieldRef, (value) => this.transformPrimitive(value, "DateTime", false), (value) => this.buildDateTimeFilter(eb, fieldRef, value), true);
|
|
570
816
|
return this.and(eb, ...conditions);
|
|
571
817
|
}
|
|
572
|
-
buildBytesFilter(eb,
|
|
573
|
-
const conditions = this.buildStandardFilter(eb, "Bytes", payload,
|
|
818
|
+
buildBytesFilter(eb, fieldRef, payload) {
|
|
819
|
+
const conditions = this.buildStandardFilter(eb, "Bytes", payload, fieldRef, (value) => this.transformPrimitive(value, "Bytes", false), (value) => this.buildBytesFilter(eb, fieldRef, value), true, [
|
|
574
820
|
"equals",
|
|
575
821
|
"in",
|
|
576
822
|
"notIn",
|
|
@@ -578,8 +824,8 @@ var BaseCrudDialect = class {
|
|
|
578
824
|
]);
|
|
579
825
|
return this.and(eb, ...conditions.conditions);
|
|
580
826
|
}
|
|
581
|
-
buildEnumFilter(eb,
|
|
582
|
-
const conditions = this.buildStandardFilter(eb, "String", payload,
|
|
827
|
+
buildEnumFilter(eb, fieldRef, fieldDef, payload) {
|
|
828
|
+
const conditions = this.buildStandardFilter(eb, "String", payload, fieldRef, (value) => value, (value) => this.buildEnumFilter(eb, fieldRef, fieldDef, value), true, [
|
|
583
829
|
"equals",
|
|
584
830
|
"in",
|
|
585
831
|
"notIn",
|
|
@@ -611,9 +857,7 @@ var BaseCrudDialect = class {
|
|
|
611
857
|
(0, import_common_helpers.invariant)(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
|
|
612
858
|
for (const [k, v] of Object.entries(value)) {
|
|
613
859
|
(0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
|
|
614
|
-
result = result.orderBy((eb) => eb.
|
|
615
|
-
import_kysely.sql.ref(k)
|
|
616
|
-
]), import_kysely.sql.raw(this.negateSort(v, negated)));
|
|
860
|
+
result = result.orderBy((eb) => aggregate(eb, this.fieldRef(model, k, eb, modelAlias), field), import_kysely.sql.raw(this.negateSort(v, negated)));
|
|
617
861
|
}
|
|
618
862
|
continue;
|
|
619
863
|
}
|
|
@@ -622,7 +866,7 @@ var BaseCrudDialect = class {
|
|
|
622
866
|
(0, import_common_helpers.invariant)(value && typeof value === "object", 'invalid orderBy value for field "_count"');
|
|
623
867
|
for (const [k, v] of Object.entries(value)) {
|
|
624
868
|
(0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
|
|
625
|
-
result = result.orderBy((eb) => eb.fn.count(
|
|
869
|
+
result = result.orderBy((eb) => eb.fn.count(this.fieldRef(model, k, eb, modelAlias)), import_kysely.sql.raw(this.negateSort(v, negated)));
|
|
626
870
|
}
|
|
627
871
|
continue;
|
|
628
872
|
}
|
|
@@ -631,10 +875,11 @@ var BaseCrudDialect = class {
|
|
|
631
875
|
}
|
|
632
876
|
const fieldDef = requireField(this.schema, model, field);
|
|
633
877
|
if (!fieldDef.relation) {
|
|
878
|
+
const fieldRef = this.fieldRef(model, field, (0, import_kysely.expressionBuilder)(), modelAlias);
|
|
634
879
|
if (value === "asc" || value === "desc") {
|
|
635
|
-
result = result.orderBy(
|
|
880
|
+
result = result.orderBy(fieldRef, this.negateSort(value, negated));
|
|
636
881
|
} else if (value && typeof value === "object" && "nulls" in value && "sort" in value && (value.sort === "asc" || value.sort === "desc") && (value.nulls === "first" || value.nulls === "last")) {
|
|
637
|
-
result = result.orderBy(
|
|
882
|
+
result = result.orderBy(fieldRef, import_kysely.sql.raw(`${this.negateSort(value.sort, negated)} nulls ${value.nulls}`));
|
|
638
883
|
}
|
|
639
884
|
} else {
|
|
640
885
|
const relationModel = fieldDef.type;
|
|
@@ -646,8 +891,9 @@ var BaseCrudDialect = class {
|
|
|
646
891
|
(0, import_common_helpers.invariant)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
|
|
647
892
|
const sort = this.negateSort(value._count, negated);
|
|
648
893
|
result = result.orderBy((eb) => {
|
|
649
|
-
|
|
650
|
-
|
|
894
|
+
const subQueryAlias = `${modelAlias}$orderBy$${field}$count`;
|
|
895
|
+
let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
|
|
896
|
+
const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, subQueryAlias);
|
|
651
897
|
subQuery = subQuery.where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely.sql.ref(left), "=", import_kysely.sql.ref(right)))));
|
|
652
898
|
subQuery = subQuery.select(() => eb.fn.count(eb.lit(1)).as("_count"));
|
|
653
899
|
return subQuery;
|
|
@@ -665,14 +911,100 @@ var BaseCrudDialect = class {
|
|
|
665
911
|
});
|
|
666
912
|
return result;
|
|
667
913
|
}
|
|
914
|
+
buildSelectAllFields(model, query, omit, modelAlias) {
|
|
915
|
+
const modelDef = requireModel(this.schema, model);
|
|
916
|
+
let result = query;
|
|
917
|
+
for (const field of Object.keys(modelDef.fields)) {
|
|
918
|
+
if (isRelationField(this.schema, model, field)) {
|
|
919
|
+
continue;
|
|
920
|
+
}
|
|
921
|
+
if (omit?.[field] === true) {
|
|
922
|
+
continue;
|
|
923
|
+
}
|
|
924
|
+
result = this.buildSelectField(result, model, modelAlias, field);
|
|
925
|
+
}
|
|
926
|
+
const descendants = getDelegateDescendantModels(this.schema, model);
|
|
927
|
+
for (const subModel of descendants) {
|
|
928
|
+
result = this.buildDelegateJoin(model, modelAlias, subModel.name, result);
|
|
929
|
+
result = result.select((eb) => {
|
|
930
|
+
const jsonObject = {};
|
|
931
|
+
for (const field of Object.keys(subModel.fields)) {
|
|
932
|
+
if (isRelationField(this.schema, subModel.name, field) || isInheritedField(this.schema, subModel.name, field)) {
|
|
933
|
+
continue;
|
|
934
|
+
}
|
|
935
|
+
jsonObject[field] = eb.ref(`${subModel.name}.${field}`);
|
|
936
|
+
}
|
|
937
|
+
return this.buildJsonObject(eb, jsonObject).as(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`);
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
return result;
|
|
941
|
+
}
|
|
942
|
+
buildModelSelect(eb, model, subQueryAlias, payload, selectAllFields) {
|
|
943
|
+
let subQuery = this.buildSelectModel(eb, model, subQueryAlias);
|
|
944
|
+
if (selectAllFields) {
|
|
945
|
+
subQuery = this.buildSelectAllFields(model, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
|
|
946
|
+
}
|
|
947
|
+
if (payload && typeof payload === "object") {
|
|
948
|
+
subQuery = this.buildFilterSortTake(model, payload, subQuery, subQueryAlias);
|
|
949
|
+
}
|
|
950
|
+
return subQuery;
|
|
951
|
+
}
|
|
952
|
+
buildSelectField(query, model, modelAlias, field) {
|
|
953
|
+
const fieldDef = requireField(this.schema, model, field);
|
|
954
|
+
if (fieldDef.computed) {
|
|
955
|
+
return query.select((eb) => this.fieldRef(model, field, eb, modelAlias).as(field));
|
|
956
|
+
} else if (!fieldDef.originModel) {
|
|
957
|
+
return query.select(import_kysely.sql.ref(`${modelAlias}.${field}`).as(field));
|
|
958
|
+
} else {
|
|
959
|
+
return this.buildSelectField(query, fieldDef.originModel, fieldDef.originModel, field);
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
buildDelegateJoin(thisModel, thisModelAlias, otherModelAlias, query) {
|
|
963
|
+
const idFields = getIdFields(this.schema, thisModel);
|
|
964
|
+
query = query.leftJoin(otherModelAlias, (qb) => {
|
|
965
|
+
for (const idField of idFields) {
|
|
966
|
+
qb = qb.onRef(`${thisModelAlias}.${idField}`, "=", `${otherModelAlias}.${idField}`);
|
|
967
|
+
}
|
|
968
|
+
return qb;
|
|
969
|
+
});
|
|
970
|
+
return query;
|
|
971
|
+
}
|
|
972
|
+
buildCountJson(model, eb, parentAlias, payload) {
|
|
973
|
+
const modelDef = requireModel(this.schema, model);
|
|
974
|
+
const toManyRelations = Object.entries(modelDef.fields).filter(([, field]) => field.relation && field.array);
|
|
975
|
+
const selections = payload === true ? {
|
|
976
|
+
select: toManyRelations.reduce((acc, [field]) => {
|
|
977
|
+
acc[field] = true;
|
|
978
|
+
return acc;
|
|
979
|
+
}, {})
|
|
980
|
+
} : payload;
|
|
981
|
+
const jsonObject = {};
|
|
982
|
+
for (const [field, value] of Object.entries(selections.select)) {
|
|
983
|
+
const fieldDef = requireField(this.schema, model, field);
|
|
984
|
+
const fieldModel = fieldDef.type;
|
|
985
|
+
const joinPairs = buildJoinPairs(this.schema, model, parentAlias, field, fieldModel);
|
|
986
|
+
let fieldCountQuery = eb.selectFrom(fieldModel).select(eb.fn.countAll().as(`_count$${field}`));
|
|
987
|
+
for (const [left, right] of joinPairs) {
|
|
988
|
+
fieldCountQuery = fieldCountQuery.whereRef(left, "=", right);
|
|
989
|
+
}
|
|
990
|
+
if (value && typeof value === "object" && "where" in value && value.where && typeof value.where === "object") {
|
|
991
|
+
const filter = this.buildFilter(eb, fieldModel, fieldModel, value.where);
|
|
992
|
+
fieldCountQuery = fieldCountQuery.where(filter);
|
|
993
|
+
}
|
|
994
|
+
jsonObject[field] = fieldCountQuery;
|
|
995
|
+
}
|
|
996
|
+
return this.buildJsonObject(eb, jsonObject);
|
|
997
|
+
}
|
|
998
|
+
// #endregion
|
|
999
|
+
// #region utils
|
|
668
1000
|
negateSort(sort, negated) {
|
|
669
1001
|
return negated ? sort === "asc" ? "desc" : "asc" : sort;
|
|
670
1002
|
}
|
|
671
1003
|
true(eb) {
|
|
672
|
-
return eb.lit(this.transformPrimitive(true, "Boolean"));
|
|
1004
|
+
return eb.lit(this.transformPrimitive(true, "Boolean", false));
|
|
673
1005
|
}
|
|
674
1006
|
false(eb) {
|
|
675
|
-
return eb.lit(this.transformPrimitive(false, "Boolean"));
|
|
1007
|
+
return eb.lit(this.transformPrimitive(false, "Boolean", false));
|
|
676
1008
|
}
|
|
677
1009
|
isTrue(expression) {
|
|
678
1010
|
const node = expression.toOperationNode();
|
|
@@ -711,6 +1043,21 @@ var BaseCrudDialect = class {
|
|
|
711
1043
|
not(eb, ...args) {
|
|
712
1044
|
return eb.not(this.and(eb, ...args));
|
|
713
1045
|
}
|
|
1046
|
+
fieldRef(model, field, eb, modelAlias, inlineComputedField = true) {
|
|
1047
|
+
return buildFieldRef(this.schema, model, field, this.options, eb, modelAlias, inlineComputedField);
|
|
1048
|
+
}
|
|
1049
|
+
canJoinWithoutNestedSelect(modelDef, payload) {
|
|
1050
|
+
if (modelDef.computedFields) {
|
|
1051
|
+
return false;
|
|
1052
|
+
}
|
|
1053
|
+
if (modelDef.baseModel || modelDef.isDelegate) {
|
|
1054
|
+
return false;
|
|
1055
|
+
}
|
|
1056
|
+
if (typeof payload === "object" && (payload.orderBy || payload.skip !== void 0 || payload.take !== void 0 || payload.cursor || payload.distinct)) {
|
|
1057
|
+
return false;
|
|
1058
|
+
}
|
|
1059
|
+
return true;
|
|
1060
|
+
}
|
|
714
1061
|
};
|
|
715
1062
|
|
|
716
1063
|
// src/client/crud/dialects/postgresql.ts
|
|
@@ -721,99 +1068,123 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
721
1068
|
get provider() {
|
|
722
1069
|
return "postgresql";
|
|
723
1070
|
}
|
|
724
|
-
transformPrimitive(value, type) {
|
|
1071
|
+
transformPrimitive(value, type, forArrayField) {
|
|
725
1072
|
if (value === void 0) {
|
|
726
1073
|
return value;
|
|
727
1074
|
}
|
|
728
1075
|
if (Array.isArray(value)) {
|
|
729
|
-
|
|
1076
|
+
if (type === "Json" && !forArrayField) {
|
|
1077
|
+
return JSON.stringify(value);
|
|
1078
|
+
} else {
|
|
1079
|
+
return value.map((v) => this.transformPrimitive(v, type, false));
|
|
1080
|
+
}
|
|
730
1081
|
} else {
|
|
731
|
-
return (0,
|
|
1082
|
+
return (0, import_ts_pattern3.match)(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).with("Decimal", () => value !== null ? value.toString() : value).otherwise(() => value);
|
|
732
1083
|
}
|
|
733
1084
|
}
|
|
734
1085
|
buildRelationSelection(query, model, relationField, parentAlias, payload) {
|
|
735
|
-
const
|
|
736
|
-
|
|
1086
|
+
const relationResultName = `${parentAlias}$${relationField}`;
|
|
1087
|
+
const joinedQuery = this.buildRelationJSON(model, query, relationField, parentAlias, payload, relationResultName);
|
|
1088
|
+
return joinedQuery.select(`${relationResultName}.$data as ${relationField}`);
|
|
737
1089
|
}
|
|
738
|
-
buildRelationJSON(model, qb, relationField,
|
|
1090
|
+
buildRelationJSON(model, qb, relationField, parentAlias, payload, resultName) {
|
|
739
1091
|
const relationFieldDef = requireField(this.schema, model, relationField);
|
|
740
1092
|
const relationModel = relationFieldDef.type;
|
|
741
1093
|
return qb.leftJoinLateral((eb) => {
|
|
742
|
-
const
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
subQuery = this.buildOrderBy(subQuery, relationModel, relationModel, payload.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
|
|
759
|
-
}
|
|
760
|
-
const m2m = getManyToManyRelation(this.schema, model, relationField);
|
|
761
|
-
if (m2m) {
|
|
762
|
-
const parentIds = getIdFields(this.schema, model);
|
|
763
|
-
const relationIds = getIdFields(this.schema, relationModel);
|
|
764
|
-
(0, import_common_helpers2.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
765
|
-
(0, import_common_helpers2.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
766
|
-
subQuery = subQuery.where(eb(eb.ref(`${relationModel}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentName}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
|
|
767
|
-
} else {
|
|
768
|
-
const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, relationModel);
|
|
769
|
-
subQuery = subQuery.where((eb2) => this.and(eb2, ...joinPairs.map(([left, right]) => eb2(import_kysely2.sql.ref(left), "=", import_kysely2.sql.ref(right)))));
|
|
770
|
-
}
|
|
771
|
-
return subQuery.as(joinTableName);
|
|
772
|
-
});
|
|
773
|
-
result = this.buildRelationObjectSelect(relationModel, relationField, relationFieldDef, result, payload, parentName);
|
|
774
|
-
result = this.buildRelationJoins(relationModel, relationField, result, payload, parentName);
|
|
775
|
-
return result.as(joinTableName);
|
|
1094
|
+
const relationSelectName = `${resultName}$sub`;
|
|
1095
|
+
const relationModelDef = requireModel(this.schema, relationModel);
|
|
1096
|
+
let tbl;
|
|
1097
|
+
if (this.canJoinWithoutNestedSelect(relationModelDef, payload)) {
|
|
1098
|
+
tbl = this.buildModelSelect(eb, relationModel, relationSelectName, payload, false);
|
|
1099
|
+
tbl = this.buildRelationJoinFilter(tbl, model, relationField, relationModel, relationSelectName, parentAlias);
|
|
1100
|
+
} else {
|
|
1101
|
+
tbl = eb.selectFrom(() => {
|
|
1102
|
+
let subQuery = this.buildModelSelect(eb, relationModel, `${relationSelectName}$t`, payload, true);
|
|
1103
|
+
subQuery = this.buildRelationJoinFilter(subQuery, model, relationField, relationModel, `${relationSelectName}$t`, parentAlias);
|
|
1104
|
+
return subQuery.as(relationSelectName);
|
|
1105
|
+
});
|
|
1106
|
+
}
|
|
1107
|
+
tbl = this.buildRelationObjectSelect(relationModel, relationSelectName, relationFieldDef, tbl, payload, resultName);
|
|
1108
|
+
tbl = this.buildRelationJoins(tbl, relationModel, relationSelectName, payload, resultName);
|
|
1109
|
+
return tbl.as(resultName);
|
|
776
1110
|
}, (join) => join.onTrue());
|
|
777
1111
|
}
|
|
778
|
-
|
|
1112
|
+
buildRelationJoinFilter(query, model, relationField, relationModel, relationModelAlias, parentAlias) {
|
|
1113
|
+
const m2m = getManyToManyRelation(this.schema, model, relationField);
|
|
1114
|
+
if (m2m) {
|
|
1115
|
+
const parentIds = getIdFields(this.schema, model);
|
|
1116
|
+
const relationIds = getIdFields(this.schema, relationModel);
|
|
1117
|
+
(0, import_common_helpers2.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1118
|
+
(0, import_common_helpers2.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1119
|
+
query = query.where((eb) => eb(eb.ref(`${relationModelAlias}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentAlias}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
|
|
1120
|
+
} else {
|
|
1121
|
+
const joinPairs = buildJoinPairs(this.schema, model, parentAlias, relationField, relationModelAlias);
|
|
1122
|
+
query = query.where((eb) => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely2.sql.ref(left), "=", import_kysely2.sql.ref(right)))));
|
|
1123
|
+
}
|
|
1124
|
+
return query;
|
|
1125
|
+
}
|
|
1126
|
+
buildRelationObjectSelect(relationModel, relationModelAlias, relationFieldDef, qb, payload, parentResultName) {
|
|
779
1127
|
qb = qb.select((eb) => {
|
|
780
|
-
const objArgs = this.buildRelationObjectArgs(relationModel,
|
|
1128
|
+
const objArgs = this.buildRelationObjectArgs(relationModel, relationModelAlias, eb, payload, parentResultName);
|
|
781
1129
|
if (relationFieldDef.array) {
|
|
782
|
-
return eb.fn.coalesce(import_kysely2.sql`jsonb_agg(jsonb_build_object(${import_kysely2.sql.join(objArgs)}))`, import_kysely2.sql`'[]'::jsonb`).as("$
|
|
1130
|
+
return eb.fn.coalesce(import_kysely2.sql`jsonb_agg(jsonb_build_object(${import_kysely2.sql.join(objArgs)}))`, import_kysely2.sql`'[]'::jsonb`).as("$data");
|
|
783
1131
|
} else {
|
|
784
|
-
return import_kysely2.sql`jsonb_build_object(${import_kysely2.sql.join(objArgs)})`.as("$
|
|
1132
|
+
return import_kysely2.sql`jsonb_build_object(${import_kysely2.sql.join(objArgs)})`.as("$data");
|
|
785
1133
|
}
|
|
786
1134
|
});
|
|
787
1135
|
return qb;
|
|
788
1136
|
}
|
|
789
|
-
buildRelationObjectArgs(relationModel,
|
|
1137
|
+
buildRelationObjectArgs(relationModel, relationModelAlias, eb, payload, parentResultName) {
|
|
790
1138
|
const relationModelDef = requireModel(this.schema, relationModel);
|
|
791
1139
|
const objArgs = [];
|
|
1140
|
+
const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
|
|
1141
|
+
if (descendantModels.length > 0) {
|
|
1142
|
+
objArgs.push(...descendantModels.map((subModel) => [
|
|
1143
|
+
import_kysely2.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
|
|
1144
|
+
eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
|
|
1145
|
+
]).flatMap((v) => v));
|
|
1146
|
+
}
|
|
792
1147
|
if (payload === true || !payload.select) {
|
|
793
1148
|
objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
|
|
794
1149
|
import_kysely2.sql.lit(field),
|
|
795
|
-
|
|
1150
|
+
this.fieldRef(relationModel, field, eb, relationModelAlias, false)
|
|
796
1151
|
]).flatMap((v) => v));
|
|
797
1152
|
} else if (payload.select) {
|
|
798
|
-
objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field]) =>
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
1153
|
+
objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
|
|
1154
|
+
if (field === "_count") {
|
|
1155
|
+
const subJson = this.buildCountJson(relationModel, eb, relationModelAlias, value);
|
|
1156
|
+
return [
|
|
1157
|
+
import_kysely2.sql.lit(field),
|
|
1158
|
+
subJson
|
|
1159
|
+
];
|
|
1160
|
+
} else {
|
|
1161
|
+
const fieldDef = requireField(this.schema, relationModel, field);
|
|
1162
|
+
const fieldValue = fieldDef.relation ? eb.ref(`${parentResultName}$${field}.$data`) : this.fieldRef(relationModel, field, eb, relationModelAlias, false);
|
|
1163
|
+
return [
|
|
1164
|
+
import_kysely2.sql.lit(field),
|
|
1165
|
+
fieldValue
|
|
1166
|
+
];
|
|
1167
|
+
}
|
|
1168
|
+
}).flatMap((v) => v));
|
|
802
1169
|
}
|
|
803
1170
|
if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
|
|
804
1171
|
objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field]) => [
|
|
805
1172
|
import_kysely2.sql.lit(field),
|
|
806
|
-
|
|
1173
|
+
// reference the synthesized JSON field
|
|
1174
|
+
eb.ref(`${parentResultName}$${field}.$data`)
|
|
807
1175
|
]).flatMap((v) => v));
|
|
808
1176
|
}
|
|
809
1177
|
return objArgs;
|
|
810
1178
|
}
|
|
811
|
-
buildRelationJoins(
|
|
812
|
-
let result =
|
|
813
|
-
if (typeof payload === "object"
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
1179
|
+
buildRelationJoins(query, relationModel, relationModelAlias, payload, parentResultName) {
|
|
1180
|
+
let result = query;
|
|
1181
|
+
if (typeof payload === "object") {
|
|
1182
|
+
const selectInclude = payload.include ?? payload.select;
|
|
1183
|
+
if (selectInclude && typeof selectInclude === "object") {
|
|
1184
|
+
Object.entries(selectInclude).filter(([, value]) => value).filter(([field]) => isRelationField(this.schema, relationModel, field)).forEach(([field, value]) => {
|
|
1185
|
+
result = this.buildRelationJSON(relationModel, result, field, relationModelAlias, value, `${parentResultName}$${field}`);
|
|
1186
|
+
});
|
|
1187
|
+
}
|
|
817
1188
|
}
|
|
818
1189
|
return result;
|
|
819
1190
|
}
|
|
@@ -853,12 +1224,15 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
853
1224
|
return `ARRAY[${values.map((v) => typeof v === "string" ? `'${v}'` : v)}]`;
|
|
854
1225
|
}
|
|
855
1226
|
}
|
|
1227
|
+
get supportInsertWithDefault() {
|
|
1228
|
+
return true;
|
|
1229
|
+
}
|
|
856
1230
|
};
|
|
857
1231
|
|
|
858
1232
|
// src/client/crud/dialects/sqlite.ts
|
|
859
1233
|
var import_common_helpers3 = require("@zenstackhq/common-helpers");
|
|
860
1234
|
var import_kysely3 = require("kysely");
|
|
861
|
-
var
|
|
1235
|
+
var import_ts_pattern4 = require("ts-pattern");
|
|
862
1236
|
var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
863
1237
|
static {
|
|
864
1238
|
__name(this, "SqliteCrudDialect");
|
|
@@ -866,86 +1240,82 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
866
1240
|
get provider() {
|
|
867
1241
|
return "sqlite";
|
|
868
1242
|
}
|
|
869
|
-
transformPrimitive(value, type) {
|
|
1243
|
+
transformPrimitive(value, type, _forArrayField) {
|
|
870
1244
|
if (value === void 0) {
|
|
871
1245
|
return value;
|
|
872
1246
|
}
|
|
873
1247
|
if (Array.isArray(value)) {
|
|
874
|
-
return value.map((v) => this.transformPrimitive(v, type));
|
|
1248
|
+
return value.map((v) => this.transformPrimitive(v, type, false));
|
|
875
1249
|
} else {
|
|
876
|
-
|
|
1250
|
+
if (this.schema.typeDefs && type in this.schema.typeDefs) {
|
|
1251
|
+
return JSON.stringify(value);
|
|
1252
|
+
} else {
|
|
1253
|
+
return (0, import_ts_pattern4.match)(type).with("Boolean", () => value ? 1 : 0).with("DateTime", () => value instanceof Date ? value.toISOString() : value).with("Decimal", () => value.toString()).with("Bytes", () => Buffer.from(value)).with("Json", () => JSON.stringify(value)).otherwise(() => value);
|
|
1254
|
+
}
|
|
877
1255
|
}
|
|
878
1256
|
}
|
|
879
1257
|
buildRelationSelection(query, model, relationField, parentAlias, payload) {
|
|
880
1258
|
return query.select((eb) => this.buildRelationJSON(model, eb, relationField, parentAlias, payload).as(relationField));
|
|
881
1259
|
}
|
|
882
|
-
buildRelationJSON(model, eb, relationField,
|
|
1260
|
+
buildRelationJSON(model, eb, relationField, parentAlias, payload) {
|
|
883
1261
|
const relationFieldDef = requireField(this.schema, model, relationField);
|
|
884
1262
|
const relationModel = relationFieldDef.type;
|
|
885
1263
|
const relationModelDef = requireModel(this.schema, relationModel);
|
|
886
|
-
const subQueryName = `${
|
|
887
|
-
let tbl
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
const
|
|
894
|
-
let
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
}
|
|
900
|
-
subQuery = this.buildSkipTake(subQuery, skip, take);
|
|
901
|
-
subQuery = this.buildOrderBy(subQuery, relationModel, relationModel, payload.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
|
|
902
|
-
}
|
|
903
|
-
const m2m = getManyToManyRelation(this.schema, model, relationField);
|
|
904
|
-
if (m2m) {
|
|
905
|
-
const parentIds = getIdFields(this.schema, model);
|
|
906
|
-
const relationIds = getIdFields(this.schema, relationModel);
|
|
907
|
-
(0, import_common_helpers3.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
908
|
-
(0, import_common_helpers3.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
909
|
-
subQuery = subQuery.where(eb(eb.ref(`${relationModel}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentName}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
|
|
910
|
-
} else {
|
|
911
|
-
const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
|
|
912
|
-
keyPairs.forEach(({ fk, pk }) => {
|
|
913
|
-
if (ownedByModel) {
|
|
914
|
-
subQuery = subQuery.whereRef(`${relationModel}.${pk}`, "=", `${parentName}.${fk}`);
|
|
915
|
-
} else {
|
|
916
|
-
subQuery = subQuery.whereRef(`${relationModel}.${fk}`, "=", `${parentName}.${pk}`);
|
|
917
|
-
}
|
|
918
|
-
});
|
|
919
|
-
}
|
|
920
|
-
return subQuery.as(subQueryName);
|
|
921
|
-
});
|
|
1264
|
+
const subQueryName = `${parentAlias}$${relationField}`;
|
|
1265
|
+
let tbl;
|
|
1266
|
+
if (this.canJoinWithoutNestedSelect(relationModelDef, payload)) {
|
|
1267
|
+
tbl = this.buildModelSelect(eb, relationModel, subQueryName, payload, false);
|
|
1268
|
+
tbl = this.buildRelationJoinFilter(tbl, model, relationField, subQueryName, parentAlias);
|
|
1269
|
+
} else {
|
|
1270
|
+
tbl = eb.selectFrom(() => {
|
|
1271
|
+
const selectModelAlias = `${parentAlias}$${relationField}$sub`;
|
|
1272
|
+
let selectModelQuery = this.buildModelSelect(eb, relationModel, selectModelAlias, payload, true);
|
|
1273
|
+
selectModelQuery = this.buildRelationJoinFilter(selectModelQuery, model, relationField, selectModelAlias, parentAlias);
|
|
1274
|
+
return selectModelQuery.as(subQueryName);
|
|
1275
|
+
});
|
|
1276
|
+
}
|
|
922
1277
|
tbl = tbl.select(() => {
|
|
923
1278
|
const objArgs = [];
|
|
1279
|
+
const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
|
|
1280
|
+
if (descendantModels.length > 0) {
|
|
1281
|
+
objArgs.push(...descendantModels.map((subModel) => [
|
|
1282
|
+
import_kysely3.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
|
|
1283
|
+
eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
|
|
1284
|
+
]).flatMap((v) => v));
|
|
1285
|
+
}
|
|
924
1286
|
if (payload === true || !payload.select) {
|
|
925
1287
|
objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
|
|
926
1288
|
import_kysely3.sql.lit(field),
|
|
927
|
-
|
|
1289
|
+
this.fieldRef(relationModel, field, eb, subQueryName, false)
|
|
928
1290
|
]).flatMap((v) => v));
|
|
929
1291
|
} else if (payload.select) {
|
|
930
1292
|
objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentName}$${relationField}`, value);
|
|
1293
|
+
if (field === "_count") {
|
|
1294
|
+
const subJson = this.buildCountJson(relationModel, eb, `${parentAlias}$${relationField}`, value);
|
|
934
1295
|
return [
|
|
935
1296
|
import_kysely3.sql.lit(field),
|
|
936
1297
|
subJson
|
|
937
1298
|
];
|
|
938
1299
|
} else {
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
1300
|
+
const fieldDef = requireField(this.schema, relationModel, field);
|
|
1301
|
+
if (fieldDef.relation) {
|
|
1302
|
+
const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentAlias}$${relationField}`, value);
|
|
1303
|
+
return [
|
|
1304
|
+
import_kysely3.sql.lit(field),
|
|
1305
|
+
subJson
|
|
1306
|
+
];
|
|
1307
|
+
} else {
|
|
1308
|
+
return [
|
|
1309
|
+
import_kysely3.sql.lit(field),
|
|
1310
|
+
this.fieldRef(relationModel, field, eb, subQueryName, false)
|
|
1311
|
+
];
|
|
1312
|
+
}
|
|
943
1313
|
}
|
|
944
1314
|
}).flatMap((v) => v));
|
|
945
1315
|
}
|
|
946
1316
|
if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
|
|
947
1317
|
objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field, value]) => {
|
|
948
|
-
const subJson = this.buildRelationJSON(relationModel, eb, field, `${
|
|
1318
|
+
const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentAlias}$${relationField}`, value);
|
|
949
1319
|
return [
|
|
950
1320
|
import_kysely3.sql.lit(field),
|
|
951
1321
|
subJson
|
|
@@ -953,13 +1323,35 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
953
1323
|
}).flatMap((v) => v));
|
|
954
1324
|
}
|
|
955
1325
|
if (relationFieldDef.array) {
|
|
956
|
-
return eb.fn.coalesce(import_kysely3.sql`json_group_array(json_object(${import_kysely3.sql.join(objArgs)}))`, import_kysely3.sql`json_array()`).as("$
|
|
1326
|
+
return eb.fn.coalesce(import_kysely3.sql`json_group_array(json_object(${import_kysely3.sql.join(objArgs)}))`, import_kysely3.sql`json_array()`).as("$data");
|
|
957
1327
|
} else {
|
|
958
|
-
return import_kysely3.sql`json_object(${import_kysely3.sql.join(objArgs)})`.as("data");
|
|
1328
|
+
return import_kysely3.sql`json_object(${import_kysely3.sql.join(objArgs)})`.as("$data");
|
|
959
1329
|
}
|
|
960
1330
|
});
|
|
961
1331
|
return tbl;
|
|
962
1332
|
}
|
|
1333
|
+
buildRelationJoinFilter(selectModelQuery, model, relationField, relationModelAlias, parentAlias) {
|
|
1334
|
+
const fieldDef = requireField(this.schema, model, relationField);
|
|
1335
|
+
const relationModel = fieldDef.type;
|
|
1336
|
+
const m2m = getManyToManyRelation(this.schema, model, relationField);
|
|
1337
|
+
if (m2m) {
|
|
1338
|
+
const parentIds = getIdFields(this.schema, model);
|
|
1339
|
+
const relationIds = getIdFields(this.schema, relationModel);
|
|
1340
|
+
(0, import_common_helpers3.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1341
|
+
(0, import_common_helpers3.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1342
|
+
selectModelQuery = selectModelQuery.where((eb) => eb(eb.ref(`${relationModelAlias}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentAlias}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
|
|
1343
|
+
} else {
|
|
1344
|
+
const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
|
|
1345
|
+
keyPairs.forEach(({ fk, pk }) => {
|
|
1346
|
+
if (ownedByModel) {
|
|
1347
|
+
selectModelQuery = selectModelQuery.whereRef(`${relationModelAlias}.${pk}`, "=", `${parentAlias}.${fk}`);
|
|
1348
|
+
} else {
|
|
1349
|
+
selectModelQuery = selectModelQuery.whereRef(`${relationModelAlias}.${fk}`, "=", `${parentAlias}.${pk}`);
|
|
1350
|
+
}
|
|
1351
|
+
});
|
|
1352
|
+
}
|
|
1353
|
+
return selectModelQuery;
|
|
1354
|
+
}
|
|
963
1355
|
buildSkipTake(query, skip, take) {
|
|
964
1356
|
if (take !== void 0) {
|
|
965
1357
|
query = query.limit(take);
|
|
@@ -995,93 +1387,17 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
995
1387
|
buildArrayLiteralSQL(_values) {
|
|
996
1388
|
throw new Error("SQLite does not support array literals");
|
|
997
1389
|
}
|
|
1390
|
+
get supportInsertWithDefault() {
|
|
1391
|
+
return false;
|
|
1392
|
+
}
|
|
998
1393
|
};
|
|
999
1394
|
|
|
1000
1395
|
// src/client/crud/dialects/index.ts
|
|
1001
1396
|
function getCrudDialect(schema, options) {
|
|
1002
|
-
return (0,
|
|
1397
|
+
return (0, import_ts_pattern5.match)(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
|
|
1003
1398
|
}
|
|
1004
1399
|
__name(getCrudDialect, "getCrudDialect");
|
|
1005
1400
|
|
|
1006
|
-
// src/schema/expression.ts
|
|
1007
|
-
var ExpressionUtils = {
|
|
1008
|
-
literal: /* @__PURE__ */ __name((value) => {
|
|
1009
|
-
return {
|
|
1010
|
-
kind: "literal",
|
|
1011
|
-
value
|
|
1012
|
-
};
|
|
1013
|
-
}, "literal"),
|
|
1014
|
-
array: /* @__PURE__ */ __name((items) => {
|
|
1015
|
-
return {
|
|
1016
|
-
kind: "array",
|
|
1017
|
-
items
|
|
1018
|
-
};
|
|
1019
|
-
}, "array"),
|
|
1020
|
-
call: /* @__PURE__ */ __name((functionName, args) => {
|
|
1021
|
-
return {
|
|
1022
|
-
kind: "call",
|
|
1023
|
-
function: functionName,
|
|
1024
|
-
args
|
|
1025
|
-
};
|
|
1026
|
-
}, "call"),
|
|
1027
|
-
binary: /* @__PURE__ */ __name((left, op, right) => {
|
|
1028
|
-
return {
|
|
1029
|
-
kind: "binary",
|
|
1030
|
-
op,
|
|
1031
|
-
left,
|
|
1032
|
-
right
|
|
1033
|
-
};
|
|
1034
|
-
}, "binary"),
|
|
1035
|
-
unary: /* @__PURE__ */ __name((op, operand) => {
|
|
1036
|
-
return {
|
|
1037
|
-
kind: "unary",
|
|
1038
|
-
op,
|
|
1039
|
-
operand
|
|
1040
|
-
};
|
|
1041
|
-
}, "unary"),
|
|
1042
|
-
field: /* @__PURE__ */ __name((field) => {
|
|
1043
|
-
return {
|
|
1044
|
-
kind: "field",
|
|
1045
|
-
field
|
|
1046
|
-
};
|
|
1047
|
-
}, "field"),
|
|
1048
|
-
member: /* @__PURE__ */ __name((receiver, members) => {
|
|
1049
|
-
return {
|
|
1050
|
-
kind: "member",
|
|
1051
|
-
receiver,
|
|
1052
|
-
members
|
|
1053
|
-
};
|
|
1054
|
-
}, "member"),
|
|
1055
|
-
_this: /* @__PURE__ */ __name(() => {
|
|
1056
|
-
return {
|
|
1057
|
-
kind: "this"
|
|
1058
|
-
};
|
|
1059
|
-
}, "_this"),
|
|
1060
|
-
_null: /* @__PURE__ */ __name(() => {
|
|
1061
|
-
return {
|
|
1062
|
-
kind: "null"
|
|
1063
|
-
};
|
|
1064
|
-
}, "_null"),
|
|
1065
|
-
and: /* @__PURE__ */ __name((expr2, ...expressions) => {
|
|
1066
|
-
return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "&&", exp), expr2);
|
|
1067
|
-
}, "and"),
|
|
1068
|
-
or: /* @__PURE__ */ __name((expr2, ...expressions) => {
|
|
1069
|
-
return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "||", exp), expr2);
|
|
1070
|
-
}, "or"),
|
|
1071
|
-
is: /* @__PURE__ */ __name((value, kind) => {
|
|
1072
|
-
return !!value && typeof value === "object" && "kind" in value && value.kind === kind;
|
|
1073
|
-
}, "is"),
|
|
1074
|
-
isLiteral: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "literal"), "isLiteral"),
|
|
1075
|
-
isArray: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "array"), "isArray"),
|
|
1076
|
-
isCall: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "call"), "isCall"),
|
|
1077
|
-
isNull: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "null"), "isNull"),
|
|
1078
|
-
isThis: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "this"), "isThis"),
|
|
1079
|
-
isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
|
|
1080
|
-
isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
|
|
1081
|
-
isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
|
|
1082
|
-
isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
|
|
1083
|
-
};
|
|
1084
|
-
|
|
1085
1401
|
// src/utils/default-operation-node-visitor.ts
|
|
1086
1402
|
var import_kysely4 = require("kysely");
|
|
1087
1403
|
var DefaultOperationNodeVisitor = class extends import_kysely4.OperationNodeVisitor {
|
|
@@ -1403,17 +1719,17 @@ var ColumnCollector = class extends DefaultOperationNodeVisitor {
|
|
|
1403
1719
|
// src/plugins/policy/expression-transformer.ts
|
|
1404
1720
|
var import_common_helpers5 = require("@zenstackhq/common-helpers");
|
|
1405
1721
|
var import_kysely6 = require("kysely");
|
|
1406
|
-
var
|
|
1722
|
+
var import_ts_pattern7 = require("ts-pattern");
|
|
1407
1723
|
|
|
1408
1724
|
// src/plugins/policy/expression-evaluator.ts
|
|
1409
1725
|
var import_common_helpers4 = require("@zenstackhq/common-helpers");
|
|
1410
|
-
var
|
|
1726
|
+
var import_ts_pattern6 = require("ts-pattern");
|
|
1411
1727
|
var ExpressionEvaluator = class {
|
|
1412
1728
|
static {
|
|
1413
1729
|
__name(this, "ExpressionEvaluator");
|
|
1414
1730
|
}
|
|
1415
1731
|
evaluate(expression, context) {
|
|
1416
|
-
const result = (0,
|
|
1732
|
+
const result = (0, import_ts_pattern6.match)(expression).when(ExpressionUtils.isArray, (expr2) => this.evaluateArray(expr2, context)).when(ExpressionUtils.isBinary, (expr2) => this.evaluateBinary(expr2, context)).when(ExpressionUtils.isField, (expr2) => this.evaluateField(expr2, context)).when(ExpressionUtils.isLiteral, (expr2) => this.evaluateLiteral(expr2)).when(ExpressionUtils.isMember, (expr2) => this.evaluateMember(expr2, context)).when(ExpressionUtils.isUnary, (expr2) => this.evaluateUnary(expr2, context)).when(ExpressionUtils.isCall, (expr2) => this.evaluateCall(expr2, context)).when(ExpressionUtils.isThis, () => context.thisValue).when(ExpressionUtils.isNull, () => null).exhaustive();
|
|
1417
1733
|
return result ?? null;
|
|
1418
1734
|
}
|
|
1419
1735
|
evaluateCall(expr2, context) {
|
|
@@ -1424,7 +1740,7 @@ var ExpressionEvaluator = class {
|
|
|
1424
1740
|
}
|
|
1425
1741
|
}
|
|
1426
1742
|
evaluateUnary(expr2, context) {
|
|
1427
|
-
return (0,
|
|
1743
|
+
return (0, import_ts_pattern6.match)(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
|
|
1428
1744
|
}
|
|
1429
1745
|
evaluateMember(expr2, context) {
|
|
1430
1746
|
let val = this.evaluate(expr2.receiver, context);
|
|
@@ -1448,7 +1764,7 @@ var ExpressionEvaluator = class {
|
|
|
1448
1764
|
}
|
|
1449
1765
|
const left = this.evaluate(expr2.left, context);
|
|
1450
1766
|
const right = this.evaluate(expr2.right, context);
|
|
1451
|
-
return (0,
|
|
1767
|
+
return (0, import_ts_pattern6.match)(expr2.op).with("==", () => left === right).with("!=", () => left !== right).with(">", () => left > right).with(">=", () => left >= right).with("<", () => left < right).with("<=", () => left <= right).with("&&", () => left && right).with("||", () => left || right).with("in", () => {
|
|
1452
1768
|
const _right = right ?? [];
|
|
1453
1769
|
(0, import_common_helpers4.invariant)(Array.isArray(_right), 'expected array for "in" operator');
|
|
1454
1770
|
return _right.includes(left);
|
|
@@ -1462,7 +1778,7 @@ var ExpressionEvaluator = class {
|
|
|
1462
1778
|
return false;
|
|
1463
1779
|
}
|
|
1464
1780
|
(0, import_common_helpers4.invariant)(Array.isArray(left), "expected array");
|
|
1465
|
-
return (0,
|
|
1781
|
+
return (0, import_ts_pattern6.match)(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
|
|
1466
1782
|
...context,
|
|
1467
1783
|
thisValue: item
|
|
1468
1784
|
}))).with("!", () => left.every((item) => this.evaluate(expr2.right, {
|
|
@@ -1478,11 +1794,11 @@ var ExpressionEvaluator = class {
|
|
|
1478
1794
|
// src/plugins/policy/utils.ts
|
|
1479
1795
|
var import_kysely5 = require("kysely");
|
|
1480
1796
|
function trueNode(dialect) {
|
|
1481
|
-
return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean"));
|
|
1797
|
+
return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean", false));
|
|
1482
1798
|
}
|
|
1483
1799
|
__name(trueNode, "trueNode");
|
|
1484
1800
|
function falseNode(dialect) {
|
|
1485
|
-
return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean"));
|
|
1801
|
+
return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean", false));
|
|
1486
1802
|
}
|
|
1487
1803
|
__name(falseNode, "falseNode");
|
|
1488
1804
|
function isTrueNode(node) {
|
|
@@ -1716,7 +2032,7 @@ var ExpressionTransformer = class {
|
|
|
1716
2032
|
const count = import_kysely6.FunctionNode.create("count", [
|
|
1717
2033
|
import_kysely6.ValueNode.createImmediate(1)
|
|
1718
2034
|
]);
|
|
1719
|
-
const predicateResult = (0,
|
|
2035
|
+
const predicateResult = (0, import_ts_pattern7.match)(expr2.op).with("?", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create(">"), import_kysely6.ValueNode.createImmediate(0))).with("!", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create("="), import_kysely6.ValueNode.createImmediate(0))).with("^", () => import_kysely6.BinaryOperationNode.create(count, import_kysely6.OperatorNode.create("="), import_kysely6.ValueNode.createImmediate(0))).exhaustive();
|
|
1720
2036
|
return this.transform(expr2.left, {
|
|
1721
2037
|
...context,
|
|
1722
2038
|
memberSelect: import_kysely6.SelectionNode.create(import_kysely6.AliasNode.create(predicateResult, import_kysely6.IdentifierNode.create("$t"))),
|
|
@@ -1740,14 +2056,14 @@ var ExpressionTransformer = class {
|
|
|
1740
2056
|
}
|
|
1741
2057
|
}
|
|
1742
2058
|
transformValue(value, type) {
|
|
1743
|
-
return import_kysely6.ValueNode.create(this.dialect.transformPrimitive(value, type) ?? null);
|
|
2059
|
+
return import_kysely6.ValueNode.create(this.dialect.transformPrimitive(value, type, false) ?? null);
|
|
1744
2060
|
}
|
|
1745
2061
|
_unary(expr2, context) {
|
|
1746
2062
|
(0, import_common_helpers5.invariant)(expr2.op === "!", 'only "!" operator is supported');
|
|
1747
2063
|
return import_kysely6.BinaryOperationNode.create(this.transform(expr2.operand, context), this.transformOperator("!="), trueNode(this.dialect));
|
|
1748
2064
|
}
|
|
1749
2065
|
transformOperator(op) {
|
|
1750
|
-
const mappedOp = (0,
|
|
2066
|
+
const mappedOp = (0, import_ts_pattern7.match)(op).with("==", () => "=").otherwise(() => op);
|
|
1751
2067
|
return import_kysely6.OperatorNode.create(mappedOp);
|
|
1752
2068
|
}
|
|
1753
2069
|
_call(expr2, context) {
|
|
@@ -1983,7 +2299,7 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
|
|
|
1983
2299
|
get kysely() {
|
|
1984
2300
|
return this.client.$qb;
|
|
1985
2301
|
}
|
|
1986
|
-
async handle(node, proceed
|
|
2302
|
+
async handle(node, proceed) {
|
|
1987
2303
|
if (!this.isCrudQueryNode(node)) {
|
|
1988
2304
|
throw new RejectedByPolicyError(void 0, "non-CRUD queries are not allowed");
|
|
1989
2305
|
}
|
|
@@ -2003,27 +2319,20 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
|
|
|
2003
2319
|
if (!mutationRequiresTransaction && !node.returning) {
|
|
2004
2320
|
return proceed(this.transformNode(node));
|
|
2005
2321
|
}
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
const
|
|
2013
|
-
if (
|
|
2014
|
-
|
|
2015
|
-
if (readBackResult.rows.length !== result2.rows.length) {
|
|
2016
|
-
readBackError = true;
|
|
2017
|
-
}
|
|
2018
|
-
return readBackResult;
|
|
2019
|
-
} else {
|
|
2020
|
-
return result2;
|
|
2322
|
+
if (import_kysely7.InsertQueryNode.is(node)) {
|
|
2323
|
+
await this.enforcePreCreatePolicy(node, proceed);
|
|
2324
|
+
}
|
|
2325
|
+
const transformedNode = this.transformNode(node);
|
|
2326
|
+
const result = await proceed(transformedNode);
|
|
2327
|
+
if (!this.onlyReturningId(node)) {
|
|
2328
|
+
const readBackResult = await this.processReadBack(node, result, proceed);
|
|
2329
|
+
if (readBackResult.rows.length !== result.rows.length) {
|
|
2330
|
+
throw new RejectedByPolicyError(mutationModel, "result is not allowed to be read back");
|
|
2021
2331
|
}
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2332
|
+
return readBackResult;
|
|
2333
|
+
} else {
|
|
2334
|
+
return result;
|
|
2025
2335
|
}
|
|
2026
|
-
return result;
|
|
2027
2336
|
}
|
|
2028
2337
|
onlyReturningId(node) {
|
|
2029
2338
|
if (!node.returning) {
|
|
@@ -2084,11 +2393,11 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
|
|
|
2084
2393
|
if (typeof item === "object" && item && "kind" in item) {
|
|
2085
2394
|
(0, import_common_helpers6.invariant)(item.kind === "ValueNode", "expecting a ValueNode");
|
|
2086
2395
|
result.push({
|
|
2087
|
-
node: import_kysely7.ValueNode.create(this.dialect.transformPrimitive(item.value, fieldDef.type)),
|
|
2396
|
+
node: import_kysely7.ValueNode.create(this.dialect.transformPrimitive(item.value, fieldDef.type, !!fieldDef.array)),
|
|
2088
2397
|
raw: item.value
|
|
2089
2398
|
});
|
|
2090
2399
|
} else {
|
|
2091
|
-
const value = this.dialect.transformPrimitive(item, fieldDef.type);
|
|
2400
|
+
const value = this.dialect.transformPrimitive(item, fieldDef.type, !!fieldDef.array);
|
|
2092
2401
|
if (Array.isArray(value)) {
|
|
2093
2402
|
result.push({
|
|
2094
2403
|
node: import_kysely7.RawNode.createWithSql(this.dialect.buildArrayLiteralSQL(value)),
|
|
@@ -2157,7 +2466,7 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
|
|
|
2157
2466
|
return disjunction(this.dialect, rows.map((row) => conjunction(this.dialect, idFields.map((field) => import_kysely7.BinaryOperationNode.create(import_kysely7.ColumnNode.create(field), import_kysely7.OperatorNode.create("="), import_kysely7.ValueNode.create(row[field]))))));
|
|
2158
2467
|
}
|
|
2159
2468
|
getMutationModel(node) {
|
|
2160
|
-
const r = (0,
|
|
2469
|
+
const r = (0, import_ts_pattern8.match)(node).when(import_kysely7.InsertQueryNode.is, (node2) => getTableName(node2.into)).when(import_kysely7.UpdateQueryNode.is, (node2) => getTableName(node2.table)).when(import_kysely7.DeleteQueryNode.is, (node2) => {
|
|
2161
2470
|
if (node2.from.froms.length !== 1) {
|
|
2162
2471
|
throw new InternalError("Only one from table is supported for delete");
|
|
2163
2472
|
}
|
|
@@ -2319,9 +2628,18 @@ var PolicyPlugin = class {
|
|
|
2319
2628
|
get description() {
|
|
2320
2629
|
return "Enforces access policies defined in the schema.";
|
|
2321
2630
|
}
|
|
2322
|
-
onKyselyQuery({
|
|
2631
|
+
onKyselyQuery({
|
|
2632
|
+
query,
|
|
2633
|
+
client,
|
|
2634
|
+
proceed
|
|
2635
|
+
/*, transaction*/
|
|
2636
|
+
}) {
|
|
2323
2637
|
const handler = new PolicyHandler(client);
|
|
2324
|
-
return handler.handle(
|
|
2638
|
+
return handler.handle(
|
|
2639
|
+
query,
|
|
2640
|
+
proceed
|
|
2641
|
+
/*, transaction*/
|
|
2642
|
+
);
|
|
2325
2643
|
}
|
|
2326
2644
|
};
|
|
2327
2645
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -2329,4 +2647,4 @@ var PolicyPlugin = class {
|
|
|
2329
2647
|
PolicyPlugin,
|
|
2330
2648
|
RejectedByPolicyError
|
|
2331
2649
|
});
|
|
2332
|
-
//# sourceMappingURL=
|
|
2650
|
+
//# sourceMappingURL=index.cjs.map
|