@zenstackhq/runtime 3.0.0-alpha.2 → 3.0.0-alpha.20
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-DguafRNB.d.cts → contract-XFKcwhq7.d.cts} +970 -785
- package/dist/{contract-DguafRNB.d.ts → contract-XFKcwhq7.d.ts} +970 -785
- package/dist/{utils/pg-utils.cjs → helpers.cjs} +8 -16
- 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 +1774 -892
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +28 -6
- package/dist/index.d.ts +28 -6
- package/dist/index.js +1724 -847
- package/dist/index.js.map +1 -1
- package/dist/plugins/{policy.cjs → policy/index.cjs} +463 -266
- package/dist/plugins/policy/index.cjs.map +1 -0
- package/dist/plugins/{policy.d.ts → policy/index.d.cts} +2 -4
- package/dist/plugins/{policy.d.cts → policy/index.d.ts} +2 -4
- package/dist/plugins/{policy.js → policy/index.js} +435 -228
- package/dist/plugins/policy/index.js.map +1 -0
- package/dist/plugins/policy/plugin.zmodel +33 -0
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.js.map +1 -1
- package/package.json +27 -49
- package/dist/client.cjs +0 -6094
- package/dist/client.cjs.map +0 -1
- package/dist/client.d.cts +0 -19
- package/dist/client.d.ts +0 -19
- package/dist/client.js +0 -6060
- package/dist/client.js.map +0 -1
- package/dist/plugins/policy.cjs.map +0 -1
- package/dist/plugins/policy.js.map +0 -1
- package/dist/utils/pg-utils.cjs.map +0 -1
- package/dist/utils/pg-utils.d.cts +0 -8
- package/dist/utils/pg-utils.d.ts +0 -8
- package/dist/utils/pg-utils.js +0 -16
- package/dist/utils/pg-utils.js.map +0 -1
- package/dist/utils/sqlite-utils.cjs +0 -55
- package/dist/utils/sqlite-utils.cjs.map +0 -1
- package/dist/utils/sqlite-utils.d.cts +0 -8
- package/dist/utils/sqlite-utils.d.ts +0 -8
- package/dist/utils/sqlite-utils.js +0 -22
- package/dist/utils/sqlite-utils.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -31,34 +31,143 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
// src/index.ts
|
|
32
32
|
var src_exports = {};
|
|
33
33
|
__export(src_exports, {
|
|
34
|
-
|
|
34
|
+
InputValidationError: () => InputValidationError,
|
|
35
|
+
InternalError: () => InternalError,
|
|
36
|
+
NotFoundError: () => NotFoundError,
|
|
37
|
+
QueryError: () => QueryError,
|
|
38
|
+
ZenStackClient: () => ZenStackClient,
|
|
39
|
+
definePlugin: () => definePlugin
|
|
35
40
|
});
|
|
36
41
|
module.exports = __toCommonJS(src_exports);
|
|
37
42
|
|
|
38
43
|
// src/client/client-impl.ts
|
|
44
|
+
var import_common_helpers13 = require("@zenstackhq/common-helpers");
|
|
39
45
|
var import_kysely16 = require("kysely");
|
|
40
|
-
var import_ts_pattern19 = require("ts-pattern");
|
|
41
46
|
|
|
42
47
|
// src/client/crud/operations/aggregate.ts
|
|
43
48
|
var import_kysely9 = require("kysely");
|
|
44
|
-
var
|
|
49
|
+
var import_ts_pattern10 = require("ts-pattern");
|
|
50
|
+
|
|
51
|
+
// src/client/query-utils.ts
|
|
52
|
+
var import_ts_pattern = require("ts-pattern");
|
|
53
|
+
|
|
54
|
+
// src/schema/expression.ts
|
|
55
|
+
var ExpressionUtils = {
|
|
56
|
+
literal: /* @__PURE__ */ __name((value) => {
|
|
57
|
+
return {
|
|
58
|
+
kind: "literal",
|
|
59
|
+
value
|
|
60
|
+
};
|
|
61
|
+
}, "literal"),
|
|
62
|
+
array: /* @__PURE__ */ __name((items) => {
|
|
63
|
+
return {
|
|
64
|
+
kind: "array",
|
|
65
|
+
items
|
|
66
|
+
};
|
|
67
|
+
}, "array"),
|
|
68
|
+
call: /* @__PURE__ */ __name((functionName, args) => {
|
|
69
|
+
return {
|
|
70
|
+
kind: "call",
|
|
71
|
+
function: functionName,
|
|
72
|
+
args
|
|
73
|
+
};
|
|
74
|
+
}, "call"),
|
|
75
|
+
binary: /* @__PURE__ */ __name((left, op, right) => {
|
|
76
|
+
return {
|
|
77
|
+
kind: "binary",
|
|
78
|
+
op,
|
|
79
|
+
left,
|
|
80
|
+
right
|
|
81
|
+
};
|
|
82
|
+
}, "binary"),
|
|
83
|
+
unary: /* @__PURE__ */ __name((op, operand) => {
|
|
84
|
+
return {
|
|
85
|
+
kind: "unary",
|
|
86
|
+
op,
|
|
87
|
+
operand
|
|
88
|
+
};
|
|
89
|
+
}, "unary"),
|
|
90
|
+
field: /* @__PURE__ */ __name((field) => {
|
|
91
|
+
return {
|
|
92
|
+
kind: "field",
|
|
93
|
+
field
|
|
94
|
+
};
|
|
95
|
+
}, "field"),
|
|
96
|
+
member: /* @__PURE__ */ __name((receiver, members) => {
|
|
97
|
+
return {
|
|
98
|
+
kind: "member",
|
|
99
|
+
receiver,
|
|
100
|
+
members
|
|
101
|
+
};
|
|
102
|
+
}, "member"),
|
|
103
|
+
_this: /* @__PURE__ */ __name(() => {
|
|
104
|
+
return {
|
|
105
|
+
kind: "this"
|
|
106
|
+
};
|
|
107
|
+
}, "_this"),
|
|
108
|
+
_null: /* @__PURE__ */ __name(() => {
|
|
109
|
+
return {
|
|
110
|
+
kind: "null"
|
|
111
|
+
};
|
|
112
|
+
}, "_null"),
|
|
113
|
+
and: /* @__PURE__ */ __name((expr2, ...expressions) => {
|
|
114
|
+
return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "&&", exp), expr2);
|
|
115
|
+
}, "and"),
|
|
116
|
+
or: /* @__PURE__ */ __name((expr2, ...expressions) => {
|
|
117
|
+
return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "||", exp), expr2);
|
|
118
|
+
}, "or"),
|
|
119
|
+
is: /* @__PURE__ */ __name((value, kind) => {
|
|
120
|
+
return !!value && typeof value === "object" && "kind" in value && value.kind === kind;
|
|
121
|
+
}, "is"),
|
|
122
|
+
isLiteral: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "literal"), "isLiteral"),
|
|
123
|
+
isArray: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "array"), "isArray"),
|
|
124
|
+
isCall: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "call"), "isCall"),
|
|
125
|
+
isNull: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "null"), "isNull"),
|
|
126
|
+
isThis: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "this"), "isThis"),
|
|
127
|
+
isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
|
|
128
|
+
isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
|
|
129
|
+
isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
|
|
130
|
+
isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// src/utils/object-utils.ts
|
|
134
|
+
function extractFields(obj, fields) {
|
|
135
|
+
return Object.fromEntries(Object.entries(obj).filter(([key]) => fields.includes(key)));
|
|
136
|
+
}
|
|
137
|
+
__name(extractFields, "extractFields");
|
|
138
|
+
function fieldsToSelectObject(fields) {
|
|
139
|
+
return Object.fromEntries(fields.map((f) => [
|
|
140
|
+
f,
|
|
141
|
+
true
|
|
142
|
+
]));
|
|
143
|
+
}
|
|
144
|
+
__name(fieldsToSelectObject, "fieldsToSelectObject");
|
|
45
145
|
|
|
46
146
|
// src/client/errors.ts
|
|
147
|
+
var InputValidationError = class extends Error {
|
|
148
|
+
static {
|
|
149
|
+
__name(this, "InputValidationError");
|
|
150
|
+
}
|
|
151
|
+
constructor(message, cause) {
|
|
152
|
+
super(message, {
|
|
153
|
+
cause
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
};
|
|
47
157
|
var QueryError = class extends Error {
|
|
48
158
|
static {
|
|
49
159
|
__name(this, "QueryError");
|
|
50
160
|
}
|
|
51
|
-
constructor(message) {
|
|
52
|
-
super(message
|
|
161
|
+
constructor(message, cause) {
|
|
162
|
+
super(message, {
|
|
163
|
+
cause
|
|
164
|
+
});
|
|
53
165
|
}
|
|
54
166
|
};
|
|
55
167
|
var InternalError = class extends Error {
|
|
56
168
|
static {
|
|
57
169
|
__name(this, "InternalError");
|
|
58
170
|
}
|
|
59
|
-
constructor(message) {
|
|
60
|
-
super(message);
|
|
61
|
-
}
|
|
62
171
|
};
|
|
63
172
|
var NotFoundError = class extends Error {
|
|
64
173
|
static {
|
|
@@ -77,7 +186,7 @@ __name(getModel, "getModel");
|
|
|
77
186
|
function requireModel(schema, model) {
|
|
78
187
|
const matchedName = Object.keys(schema.models).find((k) => k.toLowerCase() === model.toLowerCase());
|
|
79
188
|
if (!matchedName) {
|
|
80
|
-
throw new QueryError(`Model "${model}" not found`);
|
|
189
|
+
throw new QueryError(`Model "${model}" not found in schema`);
|
|
81
190
|
}
|
|
82
191
|
return schema.models[matchedName];
|
|
83
192
|
}
|
|
@@ -141,20 +250,25 @@ function getRelationForeignKeyFieldPairs(schema, model, relationField) {
|
|
|
141
250
|
}
|
|
142
251
|
__name(getRelationForeignKeyFieldPairs, "getRelationForeignKeyFieldPairs");
|
|
143
252
|
function isScalarField(schema, model, field) {
|
|
144
|
-
const fieldDef =
|
|
145
|
-
return !fieldDef
|
|
253
|
+
const fieldDef = getField(schema, model, field);
|
|
254
|
+
return !fieldDef?.relation && !fieldDef?.foreignKeyFor;
|
|
146
255
|
}
|
|
147
256
|
__name(isScalarField, "isScalarField");
|
|
148
257
|
function isForeignKeyField(schema, model, field) {
|
|
149
|
-
const fieldDef =
|
|
150
|
-
return !!fieldDef
|
|
258
|
+
const fieldDef = getField(schema, model, field);
|
|
259
|
+
return !!fieldDef?.foreignKeyFor;
|
|
151
260
|
}
|
|
152
261
|
__name(isForeignKeyField, "isForeignKeyField");
|
|
153
262
|
function isRelationField(schema, model, field) {
|
|
154
|
-
const fieldDef =
|
|
155
|
-
return !!fieldDef
|
|
263
|
+
const fieldDef = getField(schema, model, field);
|
|
264
|
+
return !!fieldDef?.relation;
|
|
156
265
|
}
|
|
157
266
|
__name(isRelationField, "isRelationField");
|
|
267
|
+
function isInheritedField(schema, model, field) {
|
|
268
|
+
const fieldDef = getField(schema, model, field);
|
|
269
|
+
return !!fieldDef?.originModel;
|
|
270
|
+
}
|
|
271
|
+
__name(isInheritedField, "isInheritedField");
|
|
158
272
|
function getUniqueFields(schema, model) {
|
|
159
273
|
const modelDef = requireModel(schema, model);
|
|
160
274
|
const result = [];
|
|
@@ -202,7 +316,7 @@ function buildFieldRef(schema, model, field, options, eb, modelAlias) {
|
|
|
202
316
|
computer = computedFields?.[model]?.[field];
|
|
203
317
|
}
|
|
204
318
|
if (!computer) {
|
|
205
|
-
throw new QueryError(`Computed field "${field}" implementation not provided`);
|
|
319
|
+
throw new QueryError(`Computed field "${field}" implementation not provided for model "${model}"`);
|
|
206
320
|
}
|
|
207
321
|
return computer(eb);
|
|
208
322
|
}
|
|
@@ -307,13 +421,49 @@ function safeJSONStringify(value) {
|
|
|
307
421
|
});
|
|
308
422
|
}
|
|
309
423
|
__name(safeJSONStringify, "safeJSONStringify");
|
|
424
|
+
function extractIdFields(entity, schema, model) {
|
|
425
|
+
const idFields = getIdFields(schema, model);
|
|
426
|
+
return extractFields(entity, idFields);
|
|
427
|
+
}
|
|
428
|
+
__name(extractIdFields, "extractIdFields");
|
|
429
|
+
function getDiscriminatorField(schema, model) {
|
|
430
|
+
const modelDef = requireModel(schema, model);
|
|
431
|
+
const delegateAttr = modelDef.attributes?.find((attr) => attr.name === "@@delegate");
|
|
432
|
+
if (!delegateAttr) {
|
|
433
|
+
return void 0;
|
|
434
|
+
}
|
|
435
|
+
const discriminator = delegateAttr.args?.find((arg) => arg.name === "discriminator");
|
|
436
|
+
if (!discriminator || !ExpressionUtils.isField(discriminator.value)) {
|
|
437
|
+
throw new InternalError(`Discriminator field not defined for model "${model}"`);
|
|
438
|
+
}
|
|
439
|
+
return discriminator.value.field;
|
|
440
|
+
}
|
|
441
|
+
__name(getDiscriminatorField, "getDiscriminatorField");
|
|
442
|
+
function getDelegateDescendantModels(schema, model, collected = /* @__PURE__ */ new Set()) {
|
|
443
|
+
const subModels = Object.values(schema.models).filter((m) => m.baseModel === model);
|
|
444
|
+
subModels.forEach((def) => {
|
|
445
|
+
if (!collected.has(def)) {
|
|
446
|
+
collected.add(def);
|
|
447
|
+
getDelegateDescendantModels(schema, def.name, collected);
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
return [
|
|
451
|
+
...collected
|
|
452
|
+
];
|
|
453
|
+
}
|
|
454
|
+
__name(getDelegateDescendantModels, "getDelegateDescendantModels");
|
|
455
|
+
function aggregate(eb, expr2, op) {
|
|
456
|
+
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();
|
|
457
|
+
}
|
|
458
|
+
__name(aggregate, "aggregate");
|
|
310
459
|
|
|
311
460
|
// src/client/crud/operations/base.ts
|
|
312
461
|
var import_cuid2 = require("@paralleldrive/cuid2");
|
|
462
|
+
var import_common_helpers8 = require("@zenstackhq/common-helpers");
|
|
313
463
|
var import_kysely8 = require("kysely");
|
|
314
464
|
var import_nanoid = require("nanoid");
|
|
315
|
-
var
|
|
316
|
-
var
|
|
465
|
+
var import_node_util = require("util");
|
|
466
|
+
var import_ts_pattern9 = require("ts-pattern");
|
|
317
467
|
var import_ulid = require("ulid");
|
|
318
468
|
var uuid = __toESM(require("uuid"), 1);
|
|
319
469
|
|
|
@@ -330,22 +480,44 @@ var RejectedByPolicyError = class extends Error {
|
|
|
330
480
|
};
|
|
331
481
|
|
|
332
482
|
// src/plugins/policy/policy-handler.ts
|
|
483
|
+
var import_common_helpers6 = require("@zenstackhq/common-helpers");
|
|
333
484
|
var import_kysely7 = require("kysely");
|
|
334
|
-
var
|
|
335
|
-
var import_ts_pattern7 = require("ts-pattern");
|
|
485
|
+
var import_ts_pattern8 = require("ts-pattern");
|
|
336
486
|
|
|
337
487
|
// src/client/crud/dialects/index.ts
|
|
338
|
-
var
|
|
488
|
+
var import_ts_pattern5 = require("ts-pattern");
|
|
339
489
|
|
|
340
490
|
// src/client/crud/dialects/postgresql.ts
|
|
491
|
+
var import_common_helpers2 = require("@zenstackhq/common-helpers");
|
|
341
492
|
var import_kysely2 = require("kysely");
|
|
342
|
-
var
|
|
343
|
-
|
|
493
|
+
var import_ts_pattern3 = require("ts-pattern");
|
|
494
|
+
|
|
495
|
+
// src/client/constants.ts
|
|
496
|
+
var CONTEXT_COMMENT_PREFIX = "-- $$context:";
|
|
497
|
+
var NUMERIC_FIELD_TYPES = [
|
|
498
|
+
"Int",
|
|
499
|
+
"Float",
|
|
500
|
+
"BigInt",
|
|
501
|
+
"Decimal"
|
|
502
|
+
];
|
|
503
|
+
var DELEGATE_JOINED_FIELD_PREFIX = "$delegate$";
|
|
504
|
+
var LOGICAL_COMBINATORS = [
|
|
505
|
+
"AND",
|
|
506
|
+
"OR",
|
|
507
|
+
"NOT"
|
|
508
|
+
];
|
|
509
|
+
var AGGREGATE_OPERATORS = [
|
|
510
|
+
"_count",
|
|
511
|
+
"_sum",
|
|
512
|
+
"_avg",
|
|
513
|
+
"_min",
|
|
514
|
+
"_max"
|
|
515
|
+
];
|
|
344
516
|
|
|
345
517
|
// src/client/crud/dialects/base.ts
|
|
518
|
+
var import_common_helpers = require("@zenstackhq/common-helpers");
|
|
346
519
|
var import_kysely = require("kysely");
|
|
347
|
-
var
|
|
348
|
-
var import_ts_pattern = require("ts-pattern");
|
|
520
|
+
var import_ts_pattern2 = require("ts-pattern");
|
|
349
521
|
|
|
350
522
|
// src/utils/enumerate.ts
|
|
351
523
|
function enumerate(x) {
|
|
@@ -362,7 +534,6 @@ function enumerate(x) {
|
|
|
362
534
|
__name(enumerate, "enumerate");
|
|
363
535
|
|
|
364
536
|
// src/client/crud/dialects/base.ts
|
|
365
|
-
var import_is_plain_object = require("is-plain-object");
|
|
366
537
|
var BaseCrudDialect = class {
|
|
367
538
|
static {
|
|
368
539
|
__name(this, "BaseCrudDialect");
|
|
@@ -373,9 +544,20 @@ var BaseCrudDialect = class {
|
|
|
373
544
|
this.schema = schema;
|
|
374
545
|
this.options = options;
|
|
375
546
|
}
|
|
376
|
-
transformPrimitive(value, _type) {
|
|
547
|
+
transformPrimitive(value, _type, _forArrayField) {
|
|
377
548
|
return value;
|
|
378
549
|
}
|
|
550
|
+
// #region common query builders
|
|
551
|
+
buildSelectModel(eb, model) {
|
|
552
|
+
const modelDef = requireModel(this.schema, model);
|
|
553
|
+
let result = eb.selectFrom(model);
|
|
554
|
+
let joinBase = modelDef.baseModel;
|
|
555
|
+
while (joinBase) {
|
|
556
|
+
result = this.buildDelegateJoin(model, joinBase, result);
|
|
557
|
+
joinBase = requireModel(this.schema, joinBase).baseModel;
|
|
558
|
+
}
|
|
559
|
+
return result;
|
|
560
|
+
}
|
|
379
561
|
buildFilter(eb, model, modelAlias, where) {
|
|
380
562
|
if (where === true || where === void 0) {
|
|
381
563
|
return this.true(eb);
|
|
@@ -392,17 +574,20 @@ var BaseCrudDialect = class {
|
|
|
392
574
|
if (key.startsWith("$")) {
|
|
393
575
|
continue;
|
|
394
576
|
}
|
|
395
|
-
if (key
|
|
577
|
+
if (this.isLogicalCombinator(key)) {
|
|
396
578
|
result = this.and(eb, result, this.buildCompositeFilter(eb, model, modelAlias, key, payload));
|
|
397
579
|
continue;
|
|
398
580
|
}
|
|
399
581
|
const fieldDef = requireField(this.schema, model, key);
|
|
400
582
|
if (fieldDef.relation) {
|
|
401
583
|
result = this.and(eb, result, this.buildRelationFilter(eb, model, modelAlias, key, fieldDef, payload));
|
|
402
|
-
} else if (fieldDef.array) {
|
|
403
|
-
result = this.and(eb, result, this.buildArrayFilter(eb, model, modelAlias, key, fieldDef, payload));
|
|
404
584
|
} else {
|
|
405
|
-
|
|
585
|
+
const fieldRef = buildFieldRef(this.schema, fieldDef.originModel ?? model, key, this.options, eb, fieldDef.originModel ?? modelAlias);
|
|
586
|
+
if (fieldDef.array) {
|
|
587
|
+
result = this.and(eb, result, this.buildArrayFilter(eb, fieldRef, fieldDef, payload));
|
|
588
|
+
} else {
|
|
589
|
+
result = this.and(eb, result, this.buildPrimitiveFilter(eb, fieldRef, fieldDef, payload));
|
|
590
|
+
}
|
|
406
591
|
}
|
|
407
592
|
}
|
|
408
593
|
if ("$expr" in _where && typeof _where["$expr"] === "function") {
|
|
@@ -410,8 +595,11 @@ var BaseCrudDialect = class {
|
|
|
410
595
|
}
|
|
411
596
|
return result;
|
|
412
597
|
}
|
|
598
|
+
isLogicalCombinator(key) {
|
|
599
|
+
return LOGICAL_COMBINATORS.includes(key);
|
|
600
|
+
}
|
|
413
601
|
buildCompositeFilter(eb, model, modelAlias, key, payload) {
|
|
414
|
-
return (0,
|
|
602
|
+
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();
|
|
415
603
|
}
|
|
416
604
|
buildRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
|
|
417
605
|
if (!fieldDef.array) {
|
|
@@ -420,19 +608,26 @@ var BaseCrudDialect = class {
|
|
|
420
608
|
return this.buildToManyRelationFilter(eb, model, modelAlias, field, fieldDef, payload);
|
|
421
609
|
}
|
|
422
610
|
}
|
|
423
|
-
buildToOneRelationFilter(eb, model,
|
|
611
|
+
buildToOneRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
|
|
424
612
|
if (payload === null) {
|
|
425
613
|
const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, model, field);
|
|
426
|
-
if (ownedByModel) {
|
|
427
|
-
return this.and(eb, ...keyPairs.map(({ fk }) => eb(import_kysely.sql.ref(`${
|
|
614
|
+
if (ownedByModel && !fieldDef.originModel) {
|
|
615
|
+
return this.and(eb, ...keyPairs.map(({ fk }) => eb(import_kysely.sql.ref(`${modelAlias}.${fk}`), "is", null)));
|
|
428
616
|
} else {
|
|
429
|
-
return this.buildToOneRelationFilter(eb, model,
|
|
617
|
+
return this.buildToOneRelationFilter(eb, model, modelAlias, field, fieldDef, {
|
|
430
618
|
is: null
|
|
431
619
|
});
|
|
432
620
|
}
|
|
433
621
|
}
|
|
434
|
-
const joinAlias = `${
|
|
435
|
-
const joinPairs = buildJoinPairs(
|
|
622
|
+
const joinAlias = `${modelAlias}$${field}`;
|
|
623
|
+
const joinPairs = buildJoinPairs(
|
|
624
|
+
this.schema,
|
|
625
|
+
model,
|
|
626
|
+
// if field is from a base, use the base model to join
|
|
627
|
+
fieldDef.originModel ?? modelAlias,
|
|
628
|
+
field,
|
|
629
|
+
joinAlias
|
|
630
|
+
);
|
|
436
631
|
const filterResultField = `${field}$filter`;
|
|
437
632
|
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));
|
|
438
633
|
const conditions = [];
|
|
@@ -493,30 +688,29 @@ var BaseCrudDialect = class {
|
|
|
493
688
|
}
|
|
494
689
|
switch (key) {
|
|
495
690
|
case "some": {
|
|
496
|
-
result = this.and(eb, result, eb(
|
|
691
|
+
result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationModel, subPayload)), ">", 0));
|
|
497
692
|
break;
|
|
498
693
|
}
|
|
499
694
|
case "every": {
|
|
500
|
-
result = this.and(eb, result, eb(
|
|
695
|
+
result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => eb1.not(this.buildFilter(eb1, relationModel, relationModel, subPayload))), "=", 0));
|
|
501
696
|
break;
|
|
502
697
|
}
|
|
503
698
|
case "none": {
|
|
504
|
-
result = this.and(eb, result, eb(
|
|
699
|
+
result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationModel, subPayload)), "=", 0));
|
|
505
700
|
break;
|
|
506
701
|
}
|
|
507
702
|
}
|
|
508
703
|
}
|
|
509
704
|
return result;
|
|
510
705
|
}
|
|
511
|
-
buildArrayFilter(eb,
|
|
706
|
+
buildArrayFilter(eb, fieldRef, fieldDef, payload) {
|
|
512
707
|
const clauses = [];
|
|
513
708
|
const fieldType = fieldDef.type;
|
|
514
|
-
const fieldRef = buildFieldRef(this.schema, model, field, this.options, eb, modelAlias);
|
|
515
709
|
for (const [key, _value] of Object.entries(payload)) {
|
|
516
710
|
if (_value === void 0) {
|
|
517
711
|
continue;
|
|
518
712
|
}
|
|
519
|
-
const value = this.transformPrimitive(_value, fieldType);
|
|
713
|
+
const value = this.transformPrimitive(_value, fieldType, !!fieldDef.array);
|
|
520
714
|
switch (key) {
|
|
521
715
|
case "equals": {
|
|
522
716
|
clauses.push(this.buildLiteralFilter(eb, fieldRef, fieldType, eb.val(value)));
|
|
@@ -547,20 +741,24 @@ var BaseCrudDialect = class {
|
|
|
547
741
|
}
|
|
548
742
|
return this.and(eb, ...clauses);
|
|
549
743
|
}
|
|
550
|
-
buildPrimitiveFilter(eb,
|
|
744
|
+
buildPrimitiveFilter(eb, fieldRef, fieldDef, payload) {
|
|
551
745
|
if (payload === null) {
|
|
552
|
-
return eb(
|
|
746
|
+
return eb(fieldRef, "is", null);
|
|
553
747
|
}
|
|
554
748
|
if (isEnum(this.schema, fieldDef.type)) {
|
|
555
|
-
return this.buildEnumFilter(eb,
|
|
749
|
+
return this.buildEnumFilter(eb, fieldRef, fieldDef, payload);
|
|
556
750
|
}
|
|
557
|
-
return (0,
|
|
751
|
+
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", () => {
|
|
752
|
+
throw new InternalError("JSON filters are not supported yet");
|
|
753
|
+
}).with("Unsupported", () => {
|
|
754
|
+
throw new QueryError(`Unsupported field cannot be used in filters`);
|
|
755
|
+
}).exhaustive();
|
|
558
756
|
}
|
|
559
757
|
buildLiteralFilter(eb, lhs, type, rhs) {
|
|
560
|
-
return eb(lhs, "=", rhs !== null && rhs !== void 0 ? this.transformPrimitive(rhs, type) : rhs);
|
|
758
|
+
return eb(lhs, "=", rhs !== null && rhs !== void 0 ? this.transformPrimitive(rhs, type, false) : rhs);
|
|
561
759
|
}
|
|
562
|
-
buildStandardFilter(eb, type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0) {
|
|
563
|
-
if (payload === null || !(0,
|
|
760
|
+
buildStandardFilter(eb, type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0, excludeKeys = []) {
|
|
761
|
+
if (payload === null || !(0, import_common_helpers.isPlainObject)(payload)) {
|
|
564
762
|
return {
|
|
565
763
|
conditions: [
|
|
566
764
|
this.buildLiteralFilter(eb, lhs, type, payload)
|
|
@@ -574,22 +772,29 @@ var BaseCrudDialect = class {
|
|
|
574
772
|
if (onlyForKeys && !onlyForKeys.includes(op)) {
|
|
575
773
|
continue;
|
|
576
774
|
}
|
|
775
|
+
if (excludeKeys.includes(op)) {
|
|
776
|
+
continue;
|
|
777
|
+
}
|
|
577
778
|
const rhs = Array.isArray(value) ? value.map(getRhs) : getRhs(value);
|
|
578
|
-
const condition = (0,
|
|
579
|
-
(0,
|
|
779
|
+
const condition = (0, import_ts_pattern2.match)(op).with("equals", () => rhs === null ? eb(lhs, "is", null) : eb(lhs, "=", rhs)).with("in", () => {
|
|
780
|
+
(0, import_common_helpers.invariant)(Array.isArray(rhs), "right hand side must be an array");
|
|
580
781
|
if (rhs.length === 0) {
|
|
581
782
|
return this.false(eb);
|
|
582
783
|
} else {
|
|
583
784
|
return eb(lhs, "in", rhs);
|
|
584
785
|
}
|
|
585
786
|
}).with("notIn", () => {
|
|
586
|
-
(0,
|
|
787
|
+
(0, import_common_helpers.invariant)(Array.isArray(rhs), "right hand side must be an array");
|
|
587
788
|
if (rhs.length === 0) {
|
|
588
789
|
return this.true(eb);
|
|
589
790
|
} else {
|
|
590
791
|
return eb.not(eb(lhs, "in", rhs));
|
|
591
792
|
}
|
|
592
|
-
}).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))).
|
|
793
|
+
}).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) => {
|
|
794
|
+
const innerResult = this.buildStandardFilter(eb, type, value, aggregate(eb, lhs, op2), getRhs, recurse, throwIfInvalid);
|
|
795
|
+
consumedKeys.push(...innerResult.consumedKeys);
|
|
796
|
+
return this.and(eb, ...innerResult.conditions);
|
|
797
|
+
}).otherwise(() => {
|
|
593
798
|
if (throwIfInvalid) {
|
|
594
799
|
throw new QueryError(`Invalid filter key: ${op}`);
|
|
595
800
|
} else {
|
|
@@ -606,24 +811,21 @@ var BaseCrudDialect = class {
|
|
|
606
811
|
consumedKeys
|
|
607
812
|
};
|
|
608
813
|
}
|
|
609
|
-
buildStringFilter(eb,
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
if (payload && typeof payload === "object" && "mode" in payload && payload.mode === "insensitive") {
|
|
614
|
-
insensitive = true;
|
|
615
|
-
fieldRef = eb.fn("lower", [
|
|
616
|
-
fieldRef
|
|
617
|
-
]);
|
|
814
|
+
buildStringFilter(eb, fieldRef, payload) {
|
|
815
|
+
let mode;
|
|
816
|
+
if (payload && typeof payload === "object" && "mode" in payload) {
|
|
817
|
+
mode = payload.mode;
|
|
618
818
|
}
|
|
619
|
-
const { conditions, consumedKeys } = this.buildStandardFilter(eb, "String", payload,
|
|
819
|
+
const { conditions, consumedKeys } = this.buildStandardFilter(eb, "String", payload, mode === "insensitive" ? eb.fn("lower", [
|
|
820
|
+
fieldRef
|
|
821
|
+
]) : fieldRef, (value) => this.prepStringCasing(eb, value, mode), (value) => this.buildStringFilter(eb, fieldRef, value));
|
|
620
822
|
if (payload && typeof payload === "object") {
|
|
621
823
|
for (const [key, value] of Object.entries(payload)) {
|
|
622
824
|
if (key === "mode" || consumedKeys.includes(key)) {
|
|
623
825
|
continue;
|
|
624
826
|
}
|
|
625
|
-
const condition = (0,
|
|
626
|
-
throw new
|
|
827
|
+
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(() => {
|
|
828
|
+
throw new QueryError(`Invalid string filter key: ${key}`);
|
|
627
829
|
});
|
|
628
830
|
if (condition) {
|
|
629
831
|
conditions.push(condition);
|
|
@@ -632,34 +834,37 @@ var BaseCrudDialect = class {
|
|
|
632
834
|
}
|
|
633
835
|
return this.and(eb, ...conditions);
|
|
634
836
|
}
|
|
635
|
-
prepStringCasing(eb, value,
|
|
837
|
+
prepStringCasing(eb, value, mode) {
|
|
838
|
+
if (!mode || mode === "default") {
|
|
839
|
+
return value === null ? value : import_kysely.sql.val(value);
|
|
840
|
+
}
|
|
636
841
|
if (typeof value === "string") {
|
|
637
|
-
return
|
|
638
|
-
import_kysely.sql.
|
|
639
|
-
])
|
|
842
|
+
return eb.fn("lower", [
|
|
843
|
+
import_kysely.sql.val(value)
|
|
844
|
+
]);
|
|
640
845
|
} else if (Array.isArray(value)) {
|
|
641
|
-
return value.map((v) => this.prepStringCasing(eb, v,
|
|
846
|
+
return value.map((v) => this.prepStringCasing(eb, v, mode));
|
|
642
847
|
} else {
|
|
643
|
-
return value === null ? null : import_kysely.sql.
|
|
848
|
+
return value === null ? null : import_kysely.sql.val(value);
|
|
644
849
|
}
|
|
645
850
|
}
|
|
646
|
-
buildNumberFilter(eb,
|
|
647
|
-
const { conditions } = this.buildStandardFilter(eb, type, payload,
|
|
851
|
+
buildNumberFilter(eb, fieldRef, type, payload) {
|
|
852
|
+
const { conditions } = this.buildStandardFilter(eb, type, payload, fieldRef, (value) => this.transformPrimitive(value, type, false), (value) => this.buildNumberFilter(eb, fieldRef, type, value));
|
|
648
853
|
return this.and(eb, ...conditions);
|
|
649
854
|
}
|
|
650
|
-
buildBooleanFilter(eb,
|
|
651
|
-
const { conditions } = this.buildStandardFilter(eb, "Boolean", payload,
|
|
855
|
+
buildBooleanFilter(eb, fieldRef, payload) {
|
|
856
|
+
const { conditions } = this.buildStandardFilter(eb, "Boolean", payload, fieldRef, (value) => this.transformPrimitive(value, "Boolean", false), (value) => this.buildBooleanFilter(eb, fieldRef, value), true, [
|
|
652
857
|
"equals",
|
|
653
858
|
"not"
|
|
654
859
|
]);
|
|
655
860
|
return this.and(eb, ...conditions);
|
|
656
861
|
}
|
|
657
|
-
buildDateTimeFilter(eb,
|
|
658
|
-
const { conditions } = this.buildStandardFilter(eb, "DateTime", payload,
|
|
862
|
+
buildDateTimeFilter(eb, fieldRef, payload) {
|
|
863
|
+
const { conditions } = this.buildStandardFilter(eb, "DateTime", payload, fieldRef, (value) => this.transformPrimitive(value, "DateTime", false), (value) => this.buildDateTimeFilter(eb, fieldRef, value), true);
|
|
659
864
|
return this.and(eb, ...conditions);
|
|
660
865
|
}
|
|
661
|
-
buildBytesFilter(eb,
|
|
662
|
-
const conditions = this.buildStandardFilter(eb, "Bytes", payload,
|
|
866
|
+
buildBytesFilter(eb, fieldRef, payload) {
|
|
867
|
+
const conditions = this.buildStandardFilter(eb, "Bytes", payload, fieldRef, (value) => this.transformPrimitive(value, "Bytes", false), (value) => this.buildBytesFilter(eb, fieldRef, value), true, [
|
|
663
868
|
"equals",
|
|
664
869
|
"in",
|
|
665
870
|
"notIn",
|
|
@@ -667,8 +872,8 @@ var BaseCrudDialect = class {
|
|
|
667
872
|
]);
|
|
668
873
|
return this.and(eb, ...conditions.conditions);
|
|
669
874
|
}
|
|
670
|
-
buildEnumFilter(eb,
|
|
671
|
-
const conditions = this.buildStandardFilter(eb, "String", payload,
|
|
875
|
+
buildEnumFilter(eb, fieldRef, fieldDef, payload) {
|
|
876
|
+
const conditions = this.buildStandardFilter(eb, "String", payload, fieldRef, (value) => value, (value) => this.buildEnumFilter(eb, fieldRef, fieldDef, value), true, [
|
|
672
877
|
"equals",
|
|
673
878
|
"in",
|
|
674
879
|
"notIn",
|
|
@@ -697,20 +902,18 @@ var BaseCrudDialect = class {
|
|
|
697
902
|
"_min",
|
|
698
903
|
"_max"
|
|
699
904
|
].includes(field)) {
|
|
700
|
-
(0,
|
|
905
|
+
(0, import_common_helpers.invariant)(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
|
|
701
906
|
for (const [k, v] of Object.entries(value)) {
|
|
702
|
-
(0,
|
|
703
|
-
result = result.orderBy((eb) => eb.
|
|
704
|
-
import_kysely.sql.ref(k)
|
|
705
|
-
]), import_kysely.sql.raw(this.negateSort(v, negated)));
|
|
907
|
+
(0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
|
|
908
|
+
result = result.orderBy((eb) => aggregate(eb, import_kysely.sql.ref(`${modelAlias}.${k}`), field), import_kysely.sql.raw(this.negateSort(v, negated)));
|
|
706
909
|
}
|
|
707
910
|
continue;
|
|
708
911
|
}
|
|
709
912
|
switch (field) {
|
|
710
913
|
case "_count": {
|
|
711
|
-
(0,
|
|
914
|
+
(0, import_common_helpers.invariant)(value && typeof value === "object", 'invalid orderBy value for field "_count"');
|
|
712
915
|
for (const [k, v] of Object.entries(value)) {
|
|
713
|
-
(0,
|
|
916
|
+
(0, import_common_helpers.invariant)(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
|
|
714
917
|
result = result.orderBy((eb) => eb.fn.count(import_kysely.sql.ref(k)), import_kysely.sql.raw(this.negateSort(v, negated)));
|
|
715
918
|
}
|
|
716
919
|
continue;
|
|
@@ -732,10 +935,10 @@ var BaseCrudDialect = class {
|
|
|
732
935
|
throw new QueryError(`invalid orderBy value for field "${field}"`);
|
|
733
936
|
}
|
|
734
937
|
if ("_count" in value) {
|
|
735
|
-
(0,
|
|
938
|
+
(0, import_common_helpers.invariant)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
|
|
736
939
|
const sort = this.negateSort(value._count, negated);
|
|
737
940
|
result = result.orderBy((eb) => {
|
|
738
|
-
let subQuery =
|
|
941
|
+
let subQuery = this.buildSelectModel(eb, relationModel);
|
|
739
942
|
const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, relationModel);
|
|
740
943
|
subQuery = subQuery.where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely.sql.ref(left), "=", import_kysely.sql.ref(right)))));
|
|
741
944
|
subQuery = subQuery.select(() => eb.fn.count(eb.lit(1)).as("_count"));
|
|
@@ -754,14 +957,90 @@ var BaseCrudDialect = class {
|
|
|
754
957
|
});
|
|
755
958
|
return result;
|
|
756
959
|
}
|
|
960
|
+
buildSelectAllFields(model, query, omit) {
|
|
961
|
+
const modelDef = requireModel(this.schema, model);
|
|
962
|
+
let result = query;
|
|
963
|
+
for (const field of Object.keys(modelDef.fields)) {
|
|
964
|
+
if (isRelationField(this.schema, model, field)) {
|
|
965
|
+
continue;
|
|
966
|
+
}
|
|
967
|
+
if (omit?.[field] === true) {
|
|
968
|
+
continue;
|
|
969
|
+
}
|
|
970
|
+
result = this.buildSelectField(result, model, model, field);
|
|
971
|
+
}
|
|
972
|
+
const descendants = getDelegateDescendantModels(this.schema, model);
|
|
973
|
+
for (const subModel of descendants) {
|
|
974
|
+
result = this.buildDelegateJoin(model, subModel.name, result);
|
|
975
|
+
result = result.select((eb) => {
|
|
976
|
+
const jsonObject = {};
|
|
977
|
+
for (const field of Object.keys(subModel.fields)) {
|
|
978
|
+
if (isRelationField(this.schema, subModel.name, field) || isInheritedField(this.schema, subModel.name, field)) {
|
|
979
|
+
continue;
|
|
980
|
+
}
|
|
981
|
+
jsonObject[field] = eb.ref(`${subModel.name}.${field}`);
|
|
982
|
+
}
|
|
983
|
+
return this.buildJsonObject(eb, jsonObject).as(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`);
|
|
984
|
+
});
|
|
985
|
+
}
|
|
986
|
+
return result;
|
|
987
|
+
}
|
|
988
|
+
buildSelectField(query, model, modelAlias, field) {
|
|
989
|
+
const fieldDef = requireField(this.schema, model, field);
|
|
990
|
+
if (fieldDef.computed) {
|
|
991
|
+
return query.select((eb) => buildFieldRef(this.schema, model, field, this.options, eb).as(field));
|
|
992
|
+
} else if (!fieldDef.originModel) {
|
|
993
|
+
return query.select(import_kysely.sql.ref(`${modelAlias}.${field}`).as(field));
|
|
994
|
+
} else {
|
|
995
|
+
return this.buildSelectField(query, fieldDef.originModel, fieldDef.originModel, field);
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
buildDelegateJoin(thisModel, otherModel, query) {
|
|
999
|
+
const idFields = getIdFields(this.schema, thisModel);
|
|
1000
|
+
query = query.leftJoin(otherModel, (qb) => {
|
|
1001
|
+
for (const idField of idFields) {
|
|
1002
|
+
qb = qb.onRef(`${thisModel}.${idField}`, "=", `${otherModel}.${idField}`);
|
|
1003
|
+
}
|
|
1004
|
+
return qb;
|
|
1005
|
+
});
|
|
1006
|
+
return query;
|
|
1007
|
+
}
|
|
1008
|
+
buildCountJson(model, eb, parentAlias, payload) {
|
|
1009
|
+
const modelDef = requireModel(this.schema, model);
|
|
1010
|
+
const toManyRelations = Object.entries(modelDef.fields).filter(([, field]) => field.relation && field.array);
|
|
1011
|
+
const selections = payload === true ? {
|
|
1012
|
+
select: toManyRelations.reduce((acc, [field]) => {
|
|
1013
|
+
acc[field] = true;
|
|
1014
|
+
return acc;
|
|
1015
|
+
}, {})
|
|
1016
|
+
} : payload;
|
|
1017
|
+
const jsonObject = {};
|
|
1018
|
+
for (const [field, value] of Object.entries(selections.select)) {
|
|
1019
|
+
const fieldDef = requireField(this.schema, model, field);
|
|
1020
|
+
const fieldModel = fieldDef.type;
|
|
1021
|
+
const joinPairs = buildJoinPairs(this.schema, model, parentAlias, field, fieldModel);
|
|
1022
|
+
let fieldCountQuery = eb.selectFrom(fieldModel).select(eb.fn.countAll().as(`_count$${field}`));
|
|
1023
|
+
for (const [left, right] of joinPairs) {
|
|
1024
|
+
fieldCountQuery = fieldCountQuery.whereRef(left, "=", right);
|
|
1025
|
+
}
|
|
1026
|
+
if (value && typeof value === "object" && "where" in value && value.where && typeof value.where === "object") {
|
|
1027
|
+
const filter = this.buildFilter(eb, fieldModel, fieldModel, value.where);
|
|
1028
|
+
fieldCountQuery = fieldCountQuery.where(filter);
|
|
1029
|
+
}
|
|
1030
|
+
jsonObject[field] = fieldCountQuery;
|
|
1031
|
+
}
|
|
1032
|
+
return this.buildJsonObject(eb, jsonObject);
|
|
1033
|
+
}
|
|
1034
|
+
// #endregion
|
|
1035
|
+
// #region utils
|
|
757
1036
|
negateSort(sort, negated) {
|
|
758
1037
|
return negated ? sort === "asc" ? "desc" : "asc" : sort;
|
|
759
1038
|
}
|
|
760
1039
|
true(eb) {
|
|
761
|
-
return eb.lit(this.transformPrimitive(true, "Boolean"));
|
|
1040
|
+
return eb.lit(this.transformPrimitive(true, "Boolean", false));
|
|
762
1041
|
}
|
|
763
1042
|
false(eb) {
|
|
764
|
-
return eb.lit(this.transformPrimitive(false, "Boolean"));
|
|
1043
|
+
return eb.lit(this.transformPrimitive(false, "Boolean", false));
|
|
765
1044
|
}
|
|
766
1045
|
isTrue(expression) {
|
|
767
1046
|
const node = expression.toOperationNode();
|
|
@@ -810,14 +1089,18 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
810
1089
|
get provider() {
|
|
811
1090
|
return "postgresql";
|
|
812
1091
|
}
|
|
813
|
-
transformPrimitive(value, type) {
|
|
1092
|
+
transformPrimitive(value, type, forArrayField) {
|
|
814
1093
|
if (value === void 0) {
|
|
815
1094
|
return value;
|
|
816
1095
|
}
|
|
817
1096
|
if (Array.isArray(value)) {
|
|
818
|
-
|
|
1097
|
+
if (type === "Json" && !forArrayField) {
|
|
1098
|
+
return JSON.stringify(value);
|
|
1099
|
+
} else {
|
|
1100
|
+
return value.map((v) => this.transformPrimitive(v, type, false));
|
|
1101
|
+
}
|
|
819
1102
|
} else {
|
|
820
|
-
return (0,
|
|
1103
|
+
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);
|
|
821
1104
|
}
|
|
822
1105
|
}
|
|
823
1106
|
buildRelationSelection(query, model, relationField, parentAlias, payload) {
|
|
@@ -831,7 +1114,8 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
831
1114
|
const joinTableName = `${parentName}$${relationField}`;
|
|
832
1115
|
let result = eb.selectFrom(`${relationModel} as ${joinTableName}`);
|
|
833
1116
|
result = eb.selectFrom(() => {
|
|
834
|
-
let subQuery =
|
|
1117
|
+
let subQuery = this.buildSelectModel(eb, relationModel);
|
|
1118
|
+
subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
|
|
835
1119
|
if (payload && typeof payload === "object") {
|
|
836
1120
|
if (payload.where) {
|
|
837
1121
|
subQuery = subQuery.where((eb2) => this.buildFilter(eb2, relationModel, relationModel, payload.where));
|
|
@@ -850,8 +1134,8 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
850
1134
|
if (m2m) {
|
|
851
1135
|
const parentIds = getIdFields(this.schema, model);
|
|
852
1136
|
const relationIds = getIdFields(this.schema, relationModel);
|
|
853
|
-
(0,
|
|
854
|
-
(0,
|
|
1137
|
+
(0, import_common_helpers2.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1138
|
+
(0, import_common_helpers2.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
855
1139
|
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}`)));
|
|
856
1140
|
} else {
|
|
857
1141
|
const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, relationModel);
|
|
@@ -875,34 +1159,57 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
875
1159
|
});
|
|
876
1160
|
return qb;
|
|
877
1161
|
}
|
|
878
|
-
buildRelationObjectArgs(relationModel, relationField, eb, payload,
|
|
1162
|
+
buildRelationObjectArgs(relationModel, relationField, eb, payload, parentAlias) {
|
|
879
1163
|
const relationModelDef = requireModel(this.schema, relationModel);
|
|
880
1164
|
const objArgs = [];
|
|
1165
|
+
const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
|
|
1166
|
+
if (descendantModels.length > 0) {
|
|
1167
|
+
objArgs.push(...descendantModels.map((subModel) => [
|
|
1168
|
+
import_kysely2.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
|
|
1169
|
+
eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
|
|
1170
|
+
]).flatMap((v) => v));
|
|
1171
|
+
}
|
|
881
1172
|
if (payload === true || !payload.select) {
|
|
882
1173
|
objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
|
|
883
1174
|
import_kysely2.sql.lit(field),
|
|
884
1175
|
buildFieldRef(this.schema, relationModel, field, this.options, eb)
|
|
885
1176
|
]).flatMap((v) => v));
|
|
886
1177
|
} else if (payload.select) {
|
|
887
|
-
objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field]) =>
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
1178
|
+
objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
|
|
1179
|
+
if (field === "_count") {
|
|
1180
|
+
const subJson = this.buildCountJson(relationModel, eb, `${parentAlias}$${relationField}`, value);
|
|
1181
|
+
return [
|
|
1182
|
+
import_kysely2.sql.lit(field),
|
|
1183
|
+
subJson
|
|
1184
|
+
];
|
|
1185
|
+
} else {
|
|
1186
|
+
const fieldDef = requireField(this.schema, relationModel, field);
|
|
1187
|
+
const fieldValue = fieldDef.relation ? eb.ref(`${parentAlias}$${relationField}$${field}.$j`) : buildFieldRef(this.schema, relationModel, field, this.options, eb);
|
|
1188
|
+
return [
|
|
1189
|
+
import_kysely2.sql.lit(field),
|
|
1190
|
+
fieldValue
|
|
1191
|
+
];
|
|
1192
|
+
}
|
|
1193
|
+
}).flatMap((v) => v));
|
|
891
1194
|
}
|
|
892
1195
|
if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
|
|
893
1196
|
objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field]) => [
|
|
894
1197
|
import_kysely2.sql.lit(field),
|
|
895
|
-
|
|
1198
|
+
// reference the synthesized JSON field
|
|
1199
|
+
eb.ref(`${parentAlias}$${relationField}$${field}.$j`)
|
|
896
1200
|
]).flatMap((v) => v));
|
|
897
1201
|
}
|
|
898
1202
|
return objArgs;
|
|
899
1203
|
}
|
|
900
|
-
buildRelationJoins(
|
|
1204
|
+
buildRelationJoins(relationModel, relationField, qb, payload, parentName) {
|
|
901
1205
|
let result = qb;
|
|
902
|
-
if (typeof payload === "object"
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
1206
|
+
if (typeof payload === "object") {
|
|
1207
|
+
const selectInclude = payload.include ?? payload.select;
|
|
1208
|
+
if (selectInclude && typeof selectInclude === "object") {
|
|
1209
|
+
Object.entries(selectInclude).filter(([, value]) => value).filter(([field]) => isRelationField(this.schema, relationModel, field)).forEach(([field, value]) => {
|
|
1210
|
+
result = this.buildRelationJSON(relationModel, result, field, `${parentName}$${relationField}`, value);
|
|
1211
|
+
});
|
|
1212
|
+
}
|
|
906
1213
|
}
|
|
907
1214
|
return result;
|
|
908
1215
|
}
|
|
@@ -942,12 +1249,15 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
942
1249
|
return `ARRAY[${values.map((v) => typeof v === "string" ? `'${v}'` : v)}]`;
|
|
943
1250
|
}
|
|
944
1251
|
}
|
|
1252
|
+
get supportInsertWithDefault() {
|
|
1253
|
+
return true;
|
|
1254
|
+
}
|
|
945
1255
|
};
|
|
946
1256
|
|
|
947
1257
|
// src/client/crud/dialects/sqlite.ts
|
|
1258
|
+
var import_common_helpers3 = require("@zenstackhq/common-helpers");
|
|
948
1259
|
var import_kysely3 = require("kysely");
|
|
949
|
-
var
|
|
950
|
-
var import_ts_pattern3 = require("ts-pattern");
|
|
1260
|
+
var import_ts_pattern4 = require("ts-pattern");
|
|
951
1261
|
var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
952
1262
|
static {
|
|
953
1263
|
__name(this, "SqliteCrudDialect");
|
|
@@ -955,26 +1265,31 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
955
1265
|
get provider() {
|
|
956
1266
|
return "sqlite";
|
|
957
1267
|
}
|
|
958
|
-
transformPrimitive(value, type) {
|
|
1268
|
+
transformPrimitive(value, type, _forArrayField) {
|
|
959
1269
|
if (value === void 0) {
|
|
960
1270
|
return value;
|
|
961
1271
|
}
|
|
962
1272
|
if (Array.isArray(value)) {
|
|
963
|
-
return value.map((v) => this.transformPrimitive(v, type));
|
|
1273
|
+
return value.map((v) => this.transformPrimitive(v, type, false));
|
|
964
1274
|
} else {
|
|
965
|
-
|
|
1275
|
+
if (this.schema.typeDefs && type in this.schema.typeDefs) {
|
|
1276
|
+
return JSON.stringify(value);
|
|
1277
|
+
} else {
|
|
1278
|
+
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);
|
|
1279
|
+
}
|
|
966
1280
|
}
|
|
967
1281
|
}
|
|
968
1282
|
buildRelationSelection(query, model, relationField, parentAlias, payload) {
|
|
969
1283
|
return query.select((eb) => this.buildRelationJSON(model, eb, relationField, parentAlias, payload).as(relationField));
|
|
970
1284
|
}
|
|
971
|
-
buildRelationJSON(model, eb, relationField,
|
|
1285
|
+
buildRelationJSON(model, eb, relationField, parentAlias, payload) {
|
|
972
1286
|
const relationFieldDef = requireField(this.schema, model, relationField);
|
|
973
1287
|
const relationModel = relationFieldDef.type;
|
|
974
1288
|
const relationModelDef = requireModel(this.schema, relationModel);
|
|
975
|
-
const subQueryName = `${
|
|
1289
|
+
const subQueryName = `${parentAlias}$${relationField}`;
|
|
976
1290
|
let tbl = eb.selectFrom(() => {
|
|
977
|
-
let subQuery =
|
|
1291
|
+
let subQuery = this.buildSelectModel(eb, relationModel);
|
|
1292
|
+
subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
|
|
978
1293
|
if (payload && typeof payload === "object") {
|
|
979
1294
|
if (payload.where) {
|
|
980
1295
|
subQuery = subQuery.where((eb2) => this.buildFilter(eb2, relationModel, relationModel, payload.where));
|
|
@@ -993,16 +1308,16 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
993
1308
|
if (m2m) {
|
|
994
1309
|
const parentIds = getIdFields(this.schema, model);
|
|
995
1310
|
const relationIds = getIdFields(this.schema, relationModel);
|
|
996
|
-
(0,
|
|
997
|
-
(0,
|
|
998
|
-
subQuery = subQuery.where(eb(eb.ref(`${relationModel}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${
|
|
1311
|
+
(0, import_common_helpers3.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1312
|
+
(0, import_common_helpers3.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1313
|
+
subQuery = subQuery.where(eb(eb.ref(`${relationModel}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentAlias}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
|
|
999
1314
|
} else {
|
|
1000
1315
|
const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
|
|
1001
1316
|
keyPairs.forEach(({ fk, pk }) => {
|
|
1002
1317
|
if (ownedByModel) {
|
|
1003
|
-
subQuery = subQuery.whereRef(`${relationModel}.${pk}`, "=", `${
|
|
1318
|
+
subQuery = subQuery.whereRef(`${relationModel}.${pk}`, "=", `${parentAlias}.${fk}`);
|
|
1004
1319
|
} else {
|
|
1005
|
-
subQuery = subQuery.whereRef(`${relationModel}.${fk}`, "=", `${
|
|
1320
|
+
subQuery = subQuery.whereRef(`${relationModel}.${fk}`, "=", `${parentAlias}.${pk}`);
|
|
1006
1321
|
}
|
|
1007
1322
|
});
|
|
1008
1323
|
}
|
|
@@ -1010,6 +1325,13 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
1010
1325
|
});
|
|
1011
1326
|
tbl = tbl.select(() => {
|
|
1012
1327
|
const objArgs = [];
|
|
1328
|
+
const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
|
|
1329
|
+
if (descendantModels.length > 0) {
|
|
1330
|
+
objArgs.push(...descendantModels.map((subModel) => [
|
|
1331
|
+
import_kysely3.sql.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
|
|
1332
|
+
eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
|
|
1333
|
+
]).flatMap((v) => v));
|
|
1334
|
+
}
|
|
1013
1335
|
if (payload === true || !payload.select) {
|
|
1014
1336
|
objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
|
|
1015
1337
|
import_kysely3.sql.lit(field),
|
|
@@ -1017,160 +1339,92 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
1017
1339
|
]).flatMap((v) => v));
|
|
1018
1340
|
} else if (payload.select) {
|
|
1019
1341
|
objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentName}$${relationField}`, value);
|
|
1342
|
+
if (field === "_count") {
|
|
1343
|
+
const subJson = this.buildCountJson(relationModel, eb, `${parentAlias}$${relationField}`, value);
|
|
1023
1344
|
return [
|
|
1024
1345
|
import_kysely3.sql.lit(field),
|
|
1025
1346
|
subJson
|
|
1026
1347
|
];
|
|
1027
1348
|
} else {
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1349
|
+
const fieldDef = requireField(this.schema, relationModel, field);
|
|
1350
|
+
if (fieldDef.relation) {
|
|
1351
|
+
const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentAlias}$${relationField}`, value);
|
|
1352
|
+
return [
|
|
1353
|
+
import_kysely3.sql.lit(field),
|
|
1354
|
+
subJson
|
|
1355
|
+
];
|
|
1356
|
+
} else {
|
|
1357
|
+
return [
|
|
1358
|
+
import_kysely3.sql.lit(field),
|
|
1359
|
+
buildFieldRef(this.schema, relationModel, field, this.options, eb)
|
|
1360
|
+
];
|
|
1361
|
+
}
|
|
1032
1362
|
}
|
|
1033
1363
|
}).flatMap((v) => v));
|
|
1034
1364
|
}
|
|
1035
1365
|
if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
|
|
1036
1366
|
objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field, value]) => {
|
|
1037
|
-
const subJson = this.buildRelationJSON(relationModel, eb, field, `${
|
|
1367
|
+
const subJson = this.buildRelationJSON(relationModel, eb, field, `${parentAlias}$${relationField}`, value);
|
|
1038
1368
|
return [
|
|
1039
1369
|
import_kysely3.sql.lit(field),
|
|
1040
1370
|
subJson
|
|
1041
1371
|
];
|
|
1042
|
-
}).flatMap((v) => v));
|
|
1043
|
-
}
|
|
1044
|
-
if (relationFieldDef.array) {
|
|
1045
|
-
return eb.fn.coalesce(import_kysely3.sql`json_group_array(json_object(${import_kysely3.sql.join(objArgs)}))`, import_kysely3.sql`json_array()`).as("$j");
|
|
1046
|
-
} else {
|
|
1047
|
-
return import_kysely3.sql`json_object(${import_kysely3.sql.join(objArgs)})`.as("data");
|
|
1048
|
-
}
|
|
1049
|
-
});
|
|
1050
|
-
return tbl;
|
|
1051
|
-
}
|
|
1052
|
-
buildSkipTake(query, skip, take) {
|
|
1053
|
-
if (take !== void 0) {
|
|
1054
|
-
query = query.limit(take);
|
|
1055
|
-
}
|
|
1056
|
-
if (skip !== void 0) {
|
|
1057
|
-
query = query.offset(skip);
|
|
1058
|
-
if (take === void 0) {
|
|
1059
|
-
query = query.limit(-1);
|
|
1060
|
-
}
|
|
1061
|
-
}
|
|
1062
|
-
return query;
|
|
1063
|
-
}
|
|
1064
|
-
buildJsonObject(eb, value) {
|
|
1065
|
-
return eb.fn("json_object", Object.entries(value).flatMap(([key, value2]) => [
|
|
1066
|
-
import_kysely3.sql.lit(key),
|
|
1067
|
-
value2
|
|
1068
|
-
]));
|
|
1069
|
-
}
|
|
1070
|
-
get supportsUpdateWithLimit() {
|
|
1071
|
-
return false;
|
|
1072
|
-
}
|
|
1073
|
-
get supportsDeleteWithLimit() {
|
|
1074
|
-
return false;
|
|
1075
|
-
}
|
|
1076
|
-
get supportsDistinctOn() {
|
|
1077
|
-
return false;
|
|
1078
|
-
}
|
|
1079
|
-
buildArrayLength(eb, array) {
|
|
1080
|
-
return eb.fn("json_array_length", [
|
|
1081
|
-
array
|
|
1082
|
-
]);
|
|
1083
|
-
}
|
|
1084
|
-
buildArrayLiteralSQL(_values) {
|
|
1085
|
-
throw new Error("SQLite does not support array literals");
|
|
1086
|
-
}
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
function getCrudDialect(schema, options) {
|
|
1091
|
-
return (0, import_ts_pattern4.match)(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
|
|
1092
|
-
}
|
|
1093
|
-
__name(getCrudDialect, "getCrudDialect");
|
|
1094
|
-
|
|
1095
|
-
// src/schema/expression.ts
|
|
1096
|
-
var ExpressionUtils = {
|
|
1097
|
-
literal: /* @__PURE__ */ __name((value) => {
|
|
1098
|
-
return {
|
|
1099
|
-
kind: "literal",
|
|
1100
|
-
value
|
|
1101
|
-
};
|
|
1102
|
-
}, "literal"),
|
|
1103
|
-
array: /* @__PURE__ */ __name((items) => {
|
|
1104
|
-
return {
|
|
1105
|
-
kind: "array",
|
|
1106
|
-
items
|
|
1107
|
-
};
|
|
1108
|
-
}, "array"),
|
|
1109
|
-
call: /* @__PURE__ */ __name((functionName, args) => {
|
|
1110
|
-
return {
|
|
1111
|
-
kind: "call",
|
|
1112
|
-
function: functionName,
|
|
1113
|
-
args
|
|
1114
|
-
};
|
|
1115
|
-
}, "call"),
|
|
1116
|
-
binary: /* @__PURE__ */ __name((left, op, right) => {
|
|
1117
|
-
return {
|
|
1118
|
-
kind: "binary",
|
|
1119
|
-
op,
|
|
1120
|
-
left,
|
|
1121
|
-
right
|
|
1122
|
-
};
|
|
1123
|
-
}, "binary"),
|
|
1124
|
-
unary: /* @__PURE__ */ __name((op, operand) => {
|
|
1125
|
-
return {
|
|
1126
|
-
kind: "unary",
|
|
1127
|
-
op,
|
|
1128
|
-
operand
|
|
1129
|
-
};
|
|
1130
|
-
}, "unary"),
|
|
1131
|
-
field: /* @__PURE__ */ __name((field) => {
|
|
1132
|
-
return {
|
|
1133
|
-
kind: "field",
|
|
1134
|
-
field
|
|
1135
|
-
};
|
|
1136
|
-
}, "field"),
|
|
1137
|
-
member: /* @__PURE__ */ __name((receiver, members) => {
|
|
1138
|
-
return {
|
|
1139
|
-
kind: "member",
|
|
1140
|
-
receiver,
|
|
1141
|
-
members
|
|
1142
|
-
};
|
|
1143
|
-
}, "member"),
|
|
1144
|
-
_this: /* @__PURE__ */ __name(() => {
|
|
1145
|
-
return {
|
|
1146
|
-
kind: "this"
|
|
1147
|
-
};
|
|
1148
|
-
}, "_this"),
|
|
1149
|
-
_null: /* @__PURE__ */ __name(() => {
|
|
1150
|
-
return {
|
|
1151
|
-
kind: "null"
|
|
1152
|
-
};
|
|
1153
|
-
}, "_null"),
|
|
1154
|
-
and: /* @__PURE__ */ __name((expr2, ...expressions) => {
|
|
1155
|
-
return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "&&", exp), expr2);
|
|
1156
|
-
}, "and"),
|
|
1157
|
-
or: /* @__PURE__ */ __name((expr2, ...expressions) => {
|
|
1158
|
-
return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "||", exp), expr2);
|
|
1159
|
-
}, "or"),
|
|
1160
|
-
is: /* @__PURE__ */ __name((value, kind) => {
|
|
1161
|
-
return !!value && typeof value === "object" && "kind" in value && value.kind === kind;
|
|
1162
|
-
}, "is"),
|
|
1163
|
-
isLiteral: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "literal"), "isLiteral"),
|
|
1164
|
-
isArray: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "array"), "isArray"),
|
|
1165
|
-
isCall: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "call"), "isCall"),
|
|
1166
|
-
isNull: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "null"), "isNull"),
|
|
1167
|
-
isThis: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "this"), "isThis"),
|
|
1168
|
-
isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
|
|
1169
|
-
isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
|
|
1170
|
-
isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
|
|
1171
|
-
isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
|
|
1372
|
+
}).flatMap((v) => v));
|
|
1373
|
+
}
|
|
1374
|
+
if (relationFieldDef.array) {
|
|
1375
|
+
return eb.fn.coalesce(import_kysely3.sql`json_group_array(json_object(${import_kysely3.sql.join(objArgs)}))`, import_kysely3.sql`json_array()`).as("$j");
|
|
1376
|
+
} else {
|
|
1377
|
+
return import_kysely3.sql`json_object(${import_kysely3.sql.join(objArgs)})`.as("data");
|
|
1378
|
+
}
|
|
1379
|
+
});
|
|
1380
|
+
return tbl;
|
|
1381
|
+
}
|
|
1382
|
+
buildSkipTake(query, skip, take) {
|
|
1383
|
+
if (take !== void 0) {
|
|
1384
|
+
query = query.limit(take);
|
|
1385
|
+
}
|
|
1386
|
+
if (skip !== void 0) {
|
|
1387
|
+
query = query.offset(skip);
|
|
1388
|
+
if (take === void 0) {
|
|
1389
|
+
query = query.limit(-1);
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
return query;
|
|
1393
|
+
}
|
|
1394
|
+
buildJsonObject(eb, value) {
|
|
1395
|
+
return eb.fn("json_object", Object.entries(value).flatMap(([key, value2]) => [
|
|
1396
|
+
import_kysely3.sql.lit(key),
|
|
1397
|
+
value2
|
|
1398
|
+
]));
|
|
1399
|
+
}
|
|
1400
|
+
get supportsUpdateWithLimit() {
|
|
1401
|
+
return false;
|
|
1402
|
+
}
|
|
1403
|
+
get supportsDeleteWithLimit() {
|
|
1404
|
+
return false;
|
|
1405
|
+
}
|
|
1406
|
+
get supportsDistinctOn() {
|
|
1407
|
+
return false;
|
|
1408
|
+
}
|
|
1409
|
+
buildArrayLength(eb, array) {
|
|
1410
|
+
return eb.fn("json_array_length", [
|
|
1411
|
+
array
|
|
1412
|
+
]);
|
|
1413
|
+
}
|
|
1414
|
+
buildArrayLiteralSQL(_values) {
|
|
1415
|
+
throw new Error("SQLite does not support array literals");
|
|
1416
|
+
}
|
|
1417
|
+
get supportInsertWithDefault() {
|
|
1418
|
+
return false;
|
|
1419
|
+
}
|
|
1172
1420
|
};
|
|
1173
1421
|
|
|
1422
|
+
// src/client/crud/dialects/index.ts
|
|
1423
|
+
function getCrudDialect(schema, options) {
|
|
1424
|
+
return (0, import_ts_pattern5.match)(schema.provider.type).with("sqlite", () => new SqliteCrudDialect(schema, options)).with("postgresql", () => new PostgresCrudDialect(schema, options)).exhaustive();
|
|
1425
|
+
}
|
|
1426
|
+
__name(getCrudDialect, "getCrudDialect");
|
|
1427
|
+
|
|
1174
1428
|
// src/utils/default-operation-node-visitor.ts
|
|
1175
1429
|
var import_kysely4 = require("kysely");
|
|
1176
1430
|
var DefaultOperationNodeVisitor = class extends import_kysely4.OperationNodeVisitor {
|
|
@@ -1490,19 +1744,19 @@ var ColumnCollector = class extends DefaultOperationNodeVisitor {
|
|
|
1490
1744
|
};
|
|
1491
1745
|
|
|
1492
1746
|
// src/plugins/policy/expression-transformer.ts
|
|
1747
|
+
var import_common_helpers5 = require("@zenstackhq/common-helpers");
|
|
1493
1748
|
var import_kysely6 = require("kysely");
|
|
1494
|
-
var
|
|
1495
|
-
var import_ts_pattern6 = require("ts-pattern");
|
|
1749
|
+
var import_ts_pattern7 = require("ts-pattern");
|
|
1496
1750
|
|
|
1497
1751
|
// src/plugins/policy/expression-evaluator.ts
|
|
1498
|
-
var
|
|
1499
|
-
var
|
|
1752
|
+
var import_common_helpers4 = require("@zenstackhq/common-helpers");
|
|
1753
|
+
var import_ts_pattern6 = require("ts-pattern");
|
|
1500
1754
|
var ExpressionEvaluator = class {
|
|
1501
1755
|
static {
|
|
1502
1756
|
__name(this, "ExpressionEvaluator");
|
|
1503
1757
|
}
|
|
1504
1758
|
evaluate(expression, context) {
|
|
1505
|
-
const result = (0,
|
|
1759
|
+
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();
|
|
1506
1760
|
return result ?? null;
|
|
1507
1761
|
}
|
|
1508
1762
|
evaluateCall(expr2, context) {
|
|
@@ -1513,7 +1767,7 @@ var ExpressionEvaluator = class {
|
|
|
1513
1767
|
}
|
|
1514
1768
|
}
|
|
1515
1769
|
evaluateUnary(expr2, context) {
|
|
1516
|
-
return (0,
|
|
1770
|
+
return (0, import_ts_pattern6.match)(expr2.op).with("!", () => !this.evaluate(expr2.operand, context)).exhaustive();
|
|
1517
1771
|
}
|
|
1518
1772
|
evaluateMember(expr2, context) {
|
|
1519
1773
|
let val = this.evaluate(expr2.receiver, context);
|
|
@@ -1537,21 +1791,21 @@ var ExpressionEvaluator = class {
|
|
|
1537
1791
|
}
|
|
1538
1792
|
const left = this.evaluate(expr2.left, context);
|
|
1539
1793
|
const right = this.evaluate(expr2.right, context);
|
|
1540
|
-
return (0,
|
|
1794
|
+
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", () => {
|
|
1541
1795
|
const _right = right ?? [];
|
|
1542
|
-
(0,
|
|
1796
|
+
(0, import_common_helpers4.invariant)(Array.isArray(_right), 'expected array for "in" operator');
|
|
1543
1797
|
return _right.includes(left);
|
|
1544
1798
|
}).exhaustive();
|
|
1545
1799
|
}
|
|
1546
1800
|
evaluateCollectionPredicate(expr2, context) {
|
|
1547
1801
|
const op = expr2.op;
|
|
1548
|
-
(0,
|
|
1802
|
+
(0, import_common_helpers4.invariant)(op === "?" || op === "!" || op === "^", 'expected "?" or "!" or "^" operator');
|
|
1549
1803
|
const left = this.evaluate(expr2.left, context);
|
|
1550
1804
|
if (!left) {
|
|
1551
1805
|
return false;
|
|
1552
1806
|
}
|
|
1553
|
-
(0,
|
|
1554
|
-
return (0,
|
|
1807
|
+
(0, import_common_helpers4.invariant)(Array.isArray(left), "expected array");
|
|
1808
|
+
return (0, import_ts_pattern6.match)(op).with("?", () => left.some((item) => this.evaluate(expr2.right, {
|
|
1555
1809
|
...context,
|
|
1556
1810
|
thisValue: item
|
|
1557
1811
|
}))).with("!", () => left.every((item) => this.evaluate(expr2.right, {
|
|
@@ -1567,11 +1821,11 @@ var ExpressionEvaluator = class {
|
|
|
1567
1821
|
// src/plugins/policy/utils.ts
|
|
1568
1822
|
var import_kysely5 = require("kysely");
|
|
1569
1823
|
function trueNode(dialect) {
|
|
1570
|
-
return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean"));
|
|
1824
|
+
return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean", false));
|
|
1571
1825
|
}
|
|
1572
1826
|
__name(trueNode, "trueNode");
|
|
1573
1827
|
function falseNode(dialect) {
|
|
1574
|
-
return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean"));
|
|
1828
|
+
return import_kysely5.ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean", false));
|
|
1575
1829
|
}
|
|
1576
1830
|
__name(falseNode, "falseNode");
|
|
1577
1831
|
function isTrueNode(node) {
|
|
@@ -1772,20 +2026,20 @@ var ExpressionTransformer = class {
|
|
|
1772
2026
|
return import_kysely6.BinaryOperationNode.create(left, this.transformOperator(op), right);
|
|
1773
2027
|
}
|
|
1774
2028
|
transformCollectionPredicate(expr2, context) {
|
|
1775
|
-
(0,
|
|
2029
|
+
(0, import_common_helpers5.invariant)(expr2.op === "?" || expr2.op === "!" || expr2.op === "^", 'expected "?" or "!" or "^" operator');
|
|
1776
2030
|
if (this.isAuthCall(expr2.left) || this.isAuthMember(expr2.left)) {
|
|
1777
2031
|
const value = new ExpressionEvaluator().evaluate(expr2, {
|
|
1778
2032
|
auth: this.auth
|
|
1779
2033
|
});
|
|
1780
2034
|
return this.transformValue(value, "Boolean");
|
|
1781
2035
|
}
|
|
1782
|
-
(0,
|
|
2036
|
+
(0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.left) || ExpressionUtils.isMember(expr2.left), "left operand must be field or member access");
|
|
1783
2037
|
let newContextModel;
|
|
1784
2038
|
if (ExpressionUtils.isField(expr2.left)) {
|
|
1785
2039
|
const fieldDef = requireField(this.schema, context.model, expr2.left.field);
|
|
1786
2040
|
newContextModel = fieldDef.type;
|
|
1787
2041
|
} else {
|
|
1788
|
-
(0,
|
|
2042
|
+
(0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.left.receiver));
|
|
1789
2043
|
const fieldDef = requireField(this.schema, context.model, expr2.left.receiver.field);
|
|
1790
2044
|
newContextModel = fieldDef.type;
|
|
1791
2045
|
for (const member of expr2.left.members) {
|
|
@@ -1805,7 +2059,7 @@ var ExpressionTransformer = class {
|
|
|
1805
2059
|
const count = import_kysely6.FunctionNode.create("count", [
|
|
1806
2060
|
import_kysely6.ValueNode.createImmediate(1)
|
|
1807
2061
|
]);
|
|
1808
|
-
const predicateResult = (0,
|
|
2062
|
+
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();
|
|
1809
2063
|
return this.transform(expr2.left, {
|
|
1810
2064
|
...context,
|
|
1811
2065
|
memberSelect: import_kysely6.SelectionNode.create(import_kysely6.AliasNode.create(predicateResult, import_kysely6.IdentifierNode.create("$t"))),
|
|
@@ -1829,14 +2083,14 @@ var ExpressionTransformer = class {
|
|
|
1829
2083
|
}
|
|
1830
2084
|
}
|
|
1831
2085
|
transformValue(value, type) {
|
|
1832
|
-
return import_kysely6.ValueNode.create(this.dialect.transformPrimitive(value, type) ?? null);
|
|
2086
|
+
return import_kysely6.ValueNode.create(this.dialect.transformPrimitive(value, type, false) ?? null);
|
|
1833
2087
|
}
|
|
1834
2088
|
_unary(expr2, context) {
|
|
1835
|
-
(0,
|
|
2089
|
+
(0, import_common_helpers5.invariant)(expr2.op === "!", 'only "!" operator is supported');
|
|
1836
2090
|
return import_kysely6.BinaryOperationNode.create(this.transform(expr2.operand, context), this.transformOperator("!="), trueNode(this.dialect));
|
|
1837
2091
|
}
|
|
1838
2092
|
transformOperator(op) {
|
|
1839
|
-
const mappedOp = (0,
|
|
2093
|
+
const mappedOp = (0, import_ts_pattern7.match)(op).with("==", () => "=").otherwise(() => op);
|
|
1840
2094
|
return import_kysely6.OperatorNode.create(mappedOp);
|
|
1841
2095
|
}
|
|
1842
2096
|
_call(expr2, context) {
|
|
@@ -1875,10 +2129,10 @@ var ExpressionTransformer = class {
|
|
|
1875
2129
|
if (this.isAuthCall(expr2.receiver)) {
|
|
1876
2130
|
return this.valueMemberAccess(this.auth, expr2, this.authType);
|
|
1877
2131
|
}
|
|
1878
|
-
(0,
|
|
2132
|
+
(0, import_common_helpers5.invariant)(ExpressionUtils.isField(expr2.receiver), "expect receiver to be field expression");
|
|
1879
2133
|
const { memberFilter, memberSelect, ...restContext } = context;
|
|
1880
2134
|
const receiver = this.transform(expr2.receiver, restContext);
|
|
1881
|
-
(0,
|
|
2135
|
+
(0, import_common_helpers5.invariant)(import_kysely6.SelectQueryNode.is(receiver), "expected receiver to be select query");
|
|
1882
2136
|
const receiverField = requireField(this.schema, context.model, expr2.receiver.field);
|
|
1883
2137
|
const memberFields = [];
|
|
1884
2138
|
let currType = receiverField.type;
|
|
@@ -1902,7 +2156,7 @@ var ExpressionTransformer = class {
|
|
|
1902
2156
|
thisEntity: void 0
|
|
1903
2157
|
});
|
|
1904
2158
|
if (currNode) {
|
|
1905
|
-
(0,
|
|
2159
|
+
(0, import_common_helpers5.invariant)(import_kysely6.SelectQueryNode.is(currNode), "expected select query node");
|
|
1906
2160
|
currNode = {
|
|
1907
2161
|
...relation,
|
|
1908
2162
|
selections: [
|
|
@@ -1919,8 +2173,8 @@ var ExpressionTransformer = class {
|
|
|
1919
2173
|
};
|
|
1920
2174
|
}
|
|
1921
2175
|
} else {
|
|
1922
|
-
(0,
|
|
1923
|
-
(0,
|
|
2176
|
+
(0, import_common_helpers5.invariant)(i === expr2.members.length - 1, "plain field access must be the last segment");
|
|
2177
|
+
(0, import_common_helpers5.invariant)(!currNode, "plain field access must be the last segment");
|
|
1924
2178
|
currNode = import_kysely6.ColumnNode.create(member);
|
|
1925
2179
|
}
|
|
1926
2180
|
}
|
|
@@ -2072,7 +2326,7 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
|
|
|
2072
2326
|
get kysely() {
|
|
2073
2327
|
return this.client.$qb;
|
|
2074
2328
|
}
|
|
2075
|
-
async handle(node, proceed
|
|
2329
|
+
async handle(node, proceed) {
|
|
2076
2330
|
if (!this.isCrudQueryNode(node)) {
|
|
2077
2331
|
throw new RejectedByPolicyError(void 0, "non-CRUD queries are not allowed");
|
|
2078
2332
|
}
|
|
@@ -2092,27 +2346,20 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
|
|
|
2092
2346
|
if (!mutationRequiresTransaction && !node.returning) {
|
|
2093
2347
|
return proceed(this.transformNode(node));
|
|
2094
2348
|
}
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
const
|
|
2102
|
-
if (
|
|
2103
|
-
|
|
2104
|
-
if (readBackResult.rows.length !== result2.rows.length) {
|
|
2105
|
-
readBackError = true;
|
|
2106
|
-
}
|
|
2107
|
-
return readBackResult;
|
|
2108
|
-
} else {
|
|
2109
|
-
return result2;
|
|
2349
|
+
if (import_kysely7.InsertQueryNode.is(node)) {
|
|
2350
|
+
await this.enforcePreCreatePolicy(node, proceed);
|
|
2351
|
+
}
|
|
2352
|
+
const transformedNode = this.transformNode(node);
|
|
2353
|
+
const result = await proceed(transformedNode);
|
|
2354
|
+
if (!this.onlyReturningId(node)) {
|
|
2355
|
+
const readBackResult = await this.processReadBack(node, result, proceed);
|
|
2356
|
+
if (readBackResult.rows.length !== result.rows.length) {
|
|
2357
|
+
throw new RejectedByPolicyError(mutationModel, "result is not allowed to be read back");
|
|
2110
2358
|
}
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2359
|
+
return readBackResult;
|
|
2360
|
+
} else {
|
|
2361
|
+
return result;
|
|
2114
2362
|
}
|
|
2115
|
-
return result;
|
|
2116
2363
|
}
|
|
2117
2364
|
onlyReturningId(node) {
|
|
2118
2365
|
if (!node.returning) {
|
|
@@ -2165,19 +2412,19 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
|
|
|
2165
2412
|
}
|
|
2166
2413
|
}
|
|
2167
2414
|
unwrapCreateValueRow(data, model, fields) {
|
|
2168
|
-
(0,
|
|
2415
|
+
(0, import_common_helpers6.invariant)(data.length === fields.length, "data length must match fields length");
|
|
2169
2416
|
const result = [];
|
|
2170
2417
|
for (let i = 0; i < data.length; i++) {
|
|
2171
2418
|
const item = data[i];
|
|
2172
2419
|
const fieldDef = requireField(this.client.$schema, model, fields[i]);
|
|
2173
2420
|
if (typeof item === "object" && item && "kind" in item) {
|
|
2174
|
-
(0,
|
|
2421
|
+
(0, import_common_helpers6.invariant)(item.kind === "ValueNode", "expecting a ValueNode");
|
|
2175
2422
|
result.push({
|
|
2176
|
-
node: import_kysely7.ValueNode.create(this.dialect.transformPrimitive(item.value, fieldDef.type)),
|
|
2423
|
+
node: import_kysely7.ValueNode.create(this.dialect.transformPrimitive(item.value, fieldDef.type, !!fieldDef.array)),
|
|
2177
2424
|
raw: item.value
|
|
2178
2425
|
});
|
|
2179
2426
|
} else {
|
|
2180
|
-
const value = this.dialect.transformPrimitive(item, fieldDef.type);
|
|
2427
|
+
const value = this.dialect.transformPrimitive(item, fieldDef.type, !!fieldDef.array);
|
|
2181
2428
|
if (Array.isArray(value)) {
|
|
2182
2429
|
result.push({
|
|
2183
2430
|
node: import_kysely7.RawNode.createWithSql(this.dialect.buildArrayLiteralSQL(value)),
|
|
@@ -2246,7 +2493,7 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
|
|
|
2246
2493
|
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]))))));
|
|
2247
2494
|
}
|
|
2248
2495
|
getMutationModel(node) {
|
|
2249
|
-
const r = (0,
|
|
2496
|
+
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) => {
|
|
2250
2497
|
if (node2.from.froms.length !== 1) {
|
|
2251
2498
|
throw new InternalError("Only one from table is supported for delete");
|
|
2252
2499
|
}
|
|
@@ -2379,8 +2626,8 @@ var PolicyHandler = class extends import_kysely7.OperationNodeTransformer {
|
|
|
2379
2626
|
const modelDef = requireModel(this.client.$schema, modelName);
|
|
2380
2627
|
const result = [];
|
|
2381
2628
|
const extractOperations = /* @__PURE__ */ __name((expr2) => {
|
|
2382
|
-
(0,
|
|
2383
|
-
(0,
|
|
2629
|
+
(0, import_common_helpers6.invariant)(ExpressionUtils.isLiteral(expr2), "expecting a literal");
|
|
2630
|
+
(0, import_common_helpers6.invariant)(typeof expr2.value === "string", "expecting a string literal");
|
|
2384
2631
|
return expr2.value.split(",").filter((v) => !!v).map((v) => v.trim());
|
|
2385
2632
|
}, "extractOperations");
|
|
2386
2633
|
if (modelDef.attributes) {
|
|
@@ -2408,20 +2655,29 @@ var PolicyPlugin = class {
|
|
|
2408
2655
|
get description() {
|
|
2409
2656
|
return "Enforces access policies defined in the schema.";
|
|
2410
2657
|
}
|
|
2411
|
-
onKyselyQuery({
|
|
2658
|
+
onKyselyQuery({
|
|
2659
|
+
query,
|
|
2660
|
+
client,
|
|
2661
|
+
proceed
|
|
2662
|
+
/*, transaction*/
|
|
2663
|
+
}) {
|
|
2412
2664
|
const handler = new PolicyHandler(client);
|
|
2413
|
-
return handler.handle(
|
|
2665
|
+
return handler.handle(
|
|
2666
|
+
query,
|
|
2667
|
+
proceed
|
|
2668
|
+
/*, transaction*/
|
|
2669
|
+
);
|
|
2414
2670
|
}
|
|
2415
2671
|
};
|
|
2416
2672
|
|
|
2417
2673
|
// src/utils/clone.ts
|
|
2418
|
-
var
|
|
2674
|
+
var import_common_helpers7 = require("@zenstackhq/common-helpers");
|
|
2419
2675
|
function clone(value) {
|
|
2420
2676
|
if (Array.isArray(value)) {
|
|
2421
2677
|
return value.map((v) => clone(v));
|
|
2422
2678
|
}
|
|
2423
2679
|
if (typeof value === "object") {
|
|
2424
|
-
if (!value || !(0,
|
|
2680
|
+
if (!value || !(0, import_common_helpers7.isPlainObject)(value)) {
|
|
2425
2681
|
return value;
|
|
2426
2682
|
}
|
|
2427
2683
|
const result = {};
|
|
@@ -2434,28 +2690,6 @@ function clone(value) {
|
|
|
2434
2690
|
}
|
|
2435
2691
|
__name(clone, "clone");
|
|
2436
2692
|
|
|
2437
|
-
// src/utils/object-utils.ts
|
|
2438
|
-
function extractFields(obj, fields) {
|
|
2439
|
-
return Object.fromEntries(Object.entries(obj).filter(([key]) => fields.includes(key)));
|
|
2440
|
-
}
|
|
2441
|
-
__name(extractFields, "extractFields");
|
|
2442
|
-
function fieldsToSelectObject(fields) {
|
|
2443
|
-
return Object.fromEntries(fields.map((f) => [
|
|
2444
|
-
f,
|
|
2445
|
-
true
|
|
2446
|
-
]));
|
|
2447
|
-
}
|
|
2448
|
-
__name(fieldsToSelectObject, "fieldsToSelectObject");
|
|
2449
|
-
|
|
2450
|
-
// src/client/constants.ts
|
|
2451
|
-
var CONTEXT_COMMENT_PREFIX = "-- $$context:";
|
|
2452
|
-
var NUMERIC_FIELD_TYPES = [
|
|
2453
|
-
"Int",
|
|
2454
|
-
"Float",
|
|
2455
|
-
"BigInt",
|
|
2456
|
-
"Decimal"
|
|
2457
|
-
];
|
|
2458
|
-
|
|
2459
2693
|
// src/client/crud/operations/base.ts
|
|
2460
2694
|
var BaseOperationHandler = class {
|
|
2461
2695
|
static {
|
|
@@ -2499,17 +2733,17 @@ var BaseOperationHandler = class {
|
|
|
2499
2733
|
getField(model, field) {
|
|
2500
2734
|
return getField(this.schema, model, field);
|
|
2501
2735
|
}
|
|
2502
|
-
exists(kysely, model, filter) {
|
|
2736
|
+
async exists(kysely, model, filter) {
|
|
2503
2737
|
const idFields = getIdFields(this.schema, model);
|
|
2504
2738
|
const _filter = flattenCompoundUniqueFilters(this.schema, model, filter);
|
|
2505
2739
|
const query = kysely.selectFrom(model).where((eb) => eb.and(_filter)).select(idFields.map((f) => kysely.dynamic.ref(f))).limit(1).modifyEnd(this.makeContextComment({
|
|
2506
2740
|
model,
|
|
2507
2741
|
operation: "read"
|
|
2508
2742
|
}));
|
|
2509
|
-
return
|
|
2743
|
+
return this.executeQueryTakeFirst(kysely, query, "exists");
|
|
2510
2744
|
}
|
|
2511
2745
|
async read(kysely, model, args) {
|
|
2512
|
-
let query =
|
|
2746
|
+
let query = this.dialect.buildSelectModel((0, import_kysely8.expressionBuilder)(), model);
|
|
2513
2747
|
if (args?.where) {
|
|
2514
2748
|
query = query.where((eb) => this.dialect.buildFilter(eb, model, model, args?.where));
|
|
2515
2749
|
}
|
|
@@ -2529,15 +2763,16 @@ var BaseOperationHandler = class {
|
|
|
2529
2763
|
query = query.distinctOn(distinct.map((f) => import_kysely8.sql.ref(`${model}.${f}`)));
|
|
2530
2764
|
} else {
|
|
2531
2765
|
inMemoryDistinct = distinct;
|
|
2766
|
+
query = distinct.reduce((acc, field) => acc.select((eb) => buildFieldRef(this.schema, model, field, this.options, eb).as(`$distinct$${field}`)), query);
|
|
2532
2767
|
}
|
|
2533
2768
|
}
|
|
2534
|
-
if (args
|
|
2535
|
-
query = this.buildFieldSelection(model, query, args
|
|
2769
|
+
if (args && "select" in args && args.select) {
|
|
2770
|
+
query = this.buildFieldSelection(model, query, args.select, model);
|
|
2536
2771
|
} else {
|
|
2537
|
-
query = this.
|
|
2772
|
+
query = this.dialect.buildSelectAllFields(model, query, args?.omit);
|
|
2538
2773
|
}
|
|
2539
|
-
if (args
|
|
2540
|
-
query = this.buildFieldSelection(model, query, args
|
|
2774
|
+
if (args && "include" in args && args.include) {
|
|
2775
|
+
query = this.buildFieldSelection(model, query, args.include, model);
|
|
2541
2776
|
}
|
|
2542
2777
|
if (args?.cursor) {
|
|
2543
2778
|
query = this.buildCursorFilter(model, query, args.cursor, args.orderBy, negateOrderBy);
|
|
@@ -2547,23 +2782,35 @@ var BaseOperationHandler = class {
|
|
|
2547
2782
|
operation: "read"
|
|
2548
2783
|
}));
|
|
2549
2784
|
let result = [];
|
|
2785
|
+
const queryId = {
|
|
2786
|
+
queryId: `zenstack-${(0, import_cuid2.createId)()}`
|
|
2787
|
+
};
|
|
2788
|
+
const compiled = kysely.getExecutor().compileQuery(query.toOperationNode(), queryId);
|
|
2550
2789
|
try {
|
|
2551
|
-
|
|
2790
|
+
const r = await kysely.getExecutor().executeQuery(compiled, queryId);
|
|
2791
|
+
result = r.rows;
|
|
2552
2792
|
} catch (err) {
|
|
2553
|
-
|
|
2554
|
-
|
|
2793
|
+
let message = `Failed to execute query: ${err}, sql: ${compiled.sql}`;
|
|
2794
|
+
if (this.options.debug) {
|
|
2795
|
+
message += `, parameters:
|
|
2796
|
+
${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
|
|
2797
|
+
}
|
|
2798
|
+
throw new QueryError(message, err);
|
|
2555
2799
|
}
|
|
2556
2800
|
if (inMemoryDistinct) {
|
|
2557
2801
|
const distinctResult = [];
|
|
2558
2802
|
const seen = /* @__PURE__ */ new Set();
|
|
2559
2803
|
for (const r of result) {
|
|
2560
|
-
const key = safeJSONStringify(inMemoryDistinct.map((f) => r[f]));
|
|
2804
|
+
const key = safeJSONStringify(inMemoryDistinct.map((f) => r[`$distinct$${f}`]));
|
|
2561
2805
|
if (!seen.has(key)) {
|
|
2562
2806
|
distinctResult.push(r);
|
|
2563
2807
|
seen.add(key);
|
|
2564
2808
|
}
|
|
2565
2809
|
}
|
|
2566
2810
|
result = distinctResult;
|
|
2811
|
+
for (const r of result) {
|
|
2812
|
+
Object.keys(r).filter((k) => k.startsWith("$distinct$")).forEach((k) => delete r[k]);
|
|
2813
|
+
}
|
|
2567
2814
|
}
|
|
2568
2815
|
return result;
|
|
2569
2816
|
}
|
|
@@ -2586,65 +2833,22 @@ var BaseOperationHandler = class {
|
|
|
2586
2833
|
}
|
|
2587
2834
|
const fieldDef = this.requireField(model, field);
|
|
2588
2835
|
if (!fieldDef.relation) {
|
|
2589
|
-
result = this.
|
|
2836
|
+
result = this.dialect.buildSelectField(result, model, parentAlias, field);
|
|
2590
2837
|
} else {
|
|
2591
2838
|
if (!fieldDef.array && !fieldDef.optional && payload.where) {
|
|
2592
2839
|
throw new QueryError(`Field "${field}" doesn't support filtering`);
|
|
2593
2840
|
}
|
|
2594
|
-
|
|
2841
|
+
if (fieldDef.originModel) {
|
|
2842
|
+
result = this.dialect.buildRelationSelection(result, fieldDef.originModel, field, fieldDef.originModel, payload);
|
|
2843
|
+
} else {
|
|
2844
|
+
result = this.dialect.buildRelationSelection(result, model, field, parentAlias, payload);
|
|
2845
|
+
}
|
|
2595
2846
|
}
|
|
2596
2847
|
}
|
|
2597
2848
|
return result;
|
|
2598
2849
|
}
|
|
2599
2850
|
buildCountSelection(query, model, parentAlias, payload) {
|
|
2600
|
-
|
|
2601
|
-
const toManyRelations = Object.entries(modelDef.fields).filter(([, field]) => field.relation && field.array);
|
|
2602
|
-
const selections = payload === true ? {
|
|
2603
|
-
select: toManyRelations.reduce((acc, [field]) => {
|
|
2604
|
-
acc[field] = true;
|
|
2605
|
-
return acc;
|
|
2606
|
-
}, {})
|
|
2607
|
-
} : payload;
|
|
2608
|
-
const eb = (0, import_kysely8.expressionBuilder)();
|
|
2609
|
-
const jsonObject = {};
|
|
2610
|
-
for (const [field, value] of Object.entries(selections.select)) {
|
|
2611
|
-
const fieldDef = requireField(this.schema, model, field);
|
|
2612
|
-
const fieldModel = fieldDef.type;
|
|
2613
|
-
const jointTable = `${parentAlias}$${field}$count`;
|
|
2614
|
-
const joinPairs = buildJoinPairs(this.schema, model, parentAlias, field, jointTable);
|
|
2615
|
-
query = query.leftJoin((eb2) => {
|
|
2616
|
-
let result = eb2.selectFrom(fieldModel).selectAll();
|
|
2617
|
-
if (value && typeof value === "object" && "where" in value && value.where && typeof value.where === "object") {
|
|
2618
|
-
const filter = this.dialect.buildFilter(eb2, fieldModel, fieldModel, value.where);
|
|
2619
|
-
result = result.where(filter);
|
|
2620
|
-
}
|
|
2621
|
-
return result.as(jointTable);
|
|
2622
|
-
}, (join) => {
|
|
2623
|
-
for (const [left, right] of joinPairs) {
|
|
2624
|
-
join = join.onRef(left, "=", right);
|
|
2625
|
-
}
|
|
2626
|
-
return join;
|
|
2627
|
-
});
|
|
2628
|
-
jsonObject[field] = this.countIdDistinct(eb, fieldDef.type, jointTable);
|
|
2629
|
-
}
|
|
2630
|
-
query = query.select((eb2) => this.dialect.buildJsonObject(eb2, jsonObject).as("_count"));
|
|
2631
|
-
return query;
|
|
2632
|
-
}
|
|
2633
|
-
countIdDistinct(eb, model, table) {
|
|
2634
|
-
const idFields = getIdFields(this.schema, model);
|
|
2635
|
-
return eb.fn.count(import_kysely8.sql.join(idFields.map((f) => import_kysely8.sql.ref(`${table}.${f}`)))).distinct();
|
|
2636
|
-
}
|
|
2637
|
-
buildSelectAllScalarFields(model, query, omit) {
|
|
2638
|
-
const modelDef = this.requireModel(model);
|
|
2639
|
-
return Object.keys(modelDef.fields).filter((f) => !isRelationField(this.schema, model, f)).filter((f) => omit?.[f] !== true).reduce((acc, f) => this.selectField(acc, model, model, f), query);
|
|
2640
|
-
}
|
|
2641
|
-
selectField(query, model, modelAlias, field) {
|
|
2642
|
-
const fieldDef = this.requireField(model, field);
|
|
2643
|
-
if (!fieldDef.computed) {
|
|
2644
|
-
return query.select(import_kysely8.sql.ref(`${modelAlias}.${field}`).as(field));
|
|
2645
|
-
} else {
|
|
2646
|
-
return query.select((eb) => buildFieldRef(this.schema, model, field, this.options, eb).as(field));
|
|
2647
|
-
}
|
|
2851
|
+
return query.select((eb) => this.dialect.buildCountJson(model, eb, parentAlias, payload).as("_count"));
|
|
2648
2852
|
}
|
|
2649
2853
|
buildCursorFilter(model, query, cursor, orderBy, negateOrderBy) {
|
|
2650
2854
|
if (!orderBy) {
|
|
@@ -2668,9 +2872,12 @@ var BaseOperationHandler = class {
|
|
|
2668
2872
|
result = result.where((eb2) => eb2.or(filters));
|
|
2669
2873
|
return result;
|
|
2670
2874
|
}
|
|
2671
|
-
async create(kysely, model, data, fromRelation) {
|
|
2875
|
+
async create(kysely, model, data, fromRelation, creatingForDelegate = false) {
|
|
2672
2876
|
const modelDef = this.requireModel(model);
|
|
2673
|
-
|
|
2877
|
+
if (modelDef.isDelegate && !creatingForDelegate) {
|
|
2878
|
+
throw new QueryError(`Model "${this.model}" is a delegate and cannot be created directly.`);
|
|
2879
|
+
}
|
|
2880
|
+
let createFields = {};
|
|
2674
2881
|
let parentUpdateTask = void 0;
|
|
2675
2882
|
let m2m = void 0;
|
|
2676
2883
|
if (fromRelation) {
|
|
@@ -2689,7 +2896,7 @@ var BaseOperationHandler = class {
|
|
|
2689
2896
|
model: fromRelation.model,
|
|
2690
2897
|
operation: "update"
|
|
2691
2898
|
}));
|
|
2692
|
-
return
|
|
2899
|
+
return this.executeQuery(kysely, query2, "update");
|
|
2693
2900
|
}, "parentUpdateTask");
|
|
2694
2901
|
}
|
|
2695
2902
|
}
|
|
@@ -2699,14 +2906,14 @@ var BaseOperationHandler = class {
|
|
|
2699
2906
|
const fieldDef = this.requireField(model, field);
|
|
2700
2907
|
if (isScalarField(this.schema, model, field) || isForeignKeyField(this.schema, model, field)) {
|
|
2701
2908
|
if (fieldDef.array && value && typeof value === "object" && "set" in value && Array.isArray(value.set)) {
|
|
2702
|
-
createFields[field] = this.dialect.transformPrimitive(value.set, fieldDef.type);
|
|
2909
|
+
createFields[field] = this.dialect.transformPrimitive(value.set, fieldDef.type, true);
|
|
2703
2910
|
} else {
|
|
2704
|
-
createFields[field] = this.dialect.transformPrimitive(value, fieldDef.type);
|
|
2911
|
+
createFields[field] = this.dialect.transformPrimitive(value, fieldDef.type, !!fieldDef.array);
|
|
2705
2912
|
}
|
|
2706
2913
|
} else {
|
|
2707
2914
|
const subM2M = getManyToManyRelation(this.schema, model, field);
|
|
2708
2915
|
if (!subM2M && fieldDef.relation?.fields && fieldDef.relation?.references) {
|
|
2709
|
-
const fkValues = await this.
|
|
2916
|
+
const fkValues = await this.processOwnedRelationForCreate(kysely, fieldDef, value);
|
|
2710
2917
|
for (let i = 0; i < fieldDef.relation.fields.length; i++) {
|
|
2711
2918
|
createFields[fieldDef.relation.fields[i]] = fkValues[fieldDef.relation.references[i]];
|
|
2712
2919
|
}
|
|
@@ -2718,16 +2925,20 @@ var BaseOperationHandler = class {
|
|
|
2718
2925
|
}
|
|
2719
2926
|
}
|
|
2720
2927
|
}
|
|
2928
|
+
if (modelDef.baseModel) {
|
|
2929
|
+
const baseCreateResult = await this.processBaseModelCreate(kysely, modelDef.baseModel, createFields, model);
|
|
2930
|
+
createFields = baseCreateResult.remainingFields;
|
|
2931
|
+
}
|
|
2721
2932
|
const updatedData = this.fillGeneratedValues(modelDef, createFields);
|
|
2722
2933
|
const idFields = getIdFields(this.schema, model);
|
|
2723
|
-
const query = kysely.insertInto(model).values(updatedData).returning(idFields).modifyEnd(this.makeContextComment({
|
|
2934
|
+
const query = kysely.insertInto(model).$if(Object.keys(updatedData).length === 0, (qb) => qb.defaultValues()).$if(Object.keys(updatedData).length > 0, (qb) => qb.values(updatedData)).returning(idFields).modifyEnd(this.makeContextComment({
|
|
2724
2935
|
model,
|
|
2725
2936
|
operation: "create"
|
|
2726
2937
|
}));
|
|
2727
|
-
const createdEntity = await
|
|
2938
|
+
const createdEntity = await this.executeQueryTakeFirst(kysely, query, "create");
|
|
2728
2939
|
if (Object.keys(postCreateRelations).length > 0) {
|
|
2729
2940
|
const relationPromises = Object.entries(postCreateRelations).map(([field, subPayload]) => {
|
|
2730
|
-
return this.
|
|
2941
|
+
return this.processNoneOwnedRelationForCreate(kysely, model, field, subPayload, createdEntity);
|
|
2731
2942
|
});
|
|
2732
2943
|
await Promise.all(relationPromises);
|
|
2733
2944
|
}
|
|
@@ -2739,10 +2950,32 @@ var BaseOperationHandler = class {
|
|
|
2739
2950
|
}
|
|
2740
2951
|
return createdEntity;
|
|
2741
2952
|
}
|
|
2953
|
+
async processBaseModelCreate(kysely, model, createFields, forModel) {
|
|
2954
|
+
const thisCreateFields = {};
|
|
2955
|
+
const remainingFields = {};
|
|
2956
|
+
Object.entries(createFields).forEach(([field, value]) => {
|
|
2957
|
+
const fieldDef = this.getField(model, field);
|
|
2958
|
+
if (fieldDef) {
|
|
2959
|
+
thisCreateFields[field] = value;
|
|
2960
|
+
} else {
|
|
2961
|
+
remainingFields[field] = value;
|
|
2962
|
+
}
|
|
2963
|
+
});
|
|
2964
|
+
const discriminatorField = getDiscriminatorField(this.schema, model);
|
|
2965
|
+
(0, import_common_helpers8.invariant)(discriminatorField, `Base model "${model}" must have a discriminator field`);
|
|
2966
|
+
thisCreateFields[discriminatorField] = forModel;
|
|
2967
|
+
const baseEntity = await this.create(kysely, model, thisCreateFields, void 0, true);
|
|
2968
|
+
const idValues = extractIdFields(baseEntity, this.schema, model);
|
|
2969
|
+
Object.assign(remainingFields, idValues);
|
|
2970
|
+
return {
|
|
2971
|
+
baseEntity,
|
|
2972
|
+
remainingFields
|
|
2973
|
+
};
|
|
2974
|
+
}
|
|
2742
2975
|
buildFkAssignments(model, relationField, entity) {
|
|
2743
2976
|
const parentFkFields = {};
|
|
2744
|
-
(0,
|
|
2745
|
-
(0,
|
|
2977
|
+
(0, import_common_helpers8.invariant)(relationField, "parentField must be defined if parentModel is defined");
|
|
2978
|
+
(0, import_common_helpers8.invariant)(entity, "parentEntity must be defined if parentModel is defined");
|
|
2746
2979
|
const { keyPairs } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
|
|
2747
2980
|
for (const pair of keyPairs) {
|
|
2748
2981
|
if (!(pair.pk in entity)) {
|
|
@@ -2769,8 +3002,8 @@ var BaseOperationHandler = class {
|
|
|
2769
3002
|
].sort((a, b) => a.model.localeCompare(b.model));
|
|
2770
3003
|
const firstIds = getIdFields(this.schema, sortedRecords[0].model);
|
|
2771
3004
|
const secondIds = getIdFields(this.schema, sortedRecords[1].model);
|
|
2772
|
-
(0,
|
|
2773
|
-
(0,
|
|
3005
|
+
(0, import_common_helpers8.invariant)(firstIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
3006
|
+
(0, import_common_helpers8.invariant)(secondIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
2774
3007
|
if (action === "connect") {
|
|
2775
3008
|
const result = await kysely.insertInto(joinTable).values({
|
|
2776
3009
|
A: sortedRecords[0].entity[firstIds[0]],
|
|
@@ -2787,14 +3020,14 @@ var BaseOperationHandler = class {
|
|
|
2787
3020
|
}
|
|
2788
3021
|
}
|
|
2789
3022
|
resetManyToManyRelation(kysely, model, field, parentIds) {
|
|
2790
|
-
(0,
|
|
3023
|
+
(0, import_common_helpers8.invariant)(Object.keys(parentIds).length === 1, "parentIds must have exactly one field");
|
|
2791
3024
|
const parentId = Object.values(parentIds)[0];
|
|
2792
3025
|
const m2m = getManyToManyRelation(this.schema, model, field);
|
|
2793
|
-
(0,
|
|
3026
|
+
(0, import_common_helpers8.invariant)(m2m, "not a many-to-many relation");
|
|
2794
3027
|
const eb = (0, import_kysely8.expressionBuilder)();
|
|
2795
3028
|
return kysely.deleteFrom(m2m.joinTable).where(eb(`${m2m.joinTable}.${m2m.parentFkName}`, "=", parentId)).execute();
|
|
2796
3029
|
}
|
|
2797
|
-
async
|
|
3030
|
+
async processOwnedRelationForCreate(kysely, relationField, payload) {
|
|
2798
3031
|
if (!payload) {
|
|
2799
3032
|
return;
|
|
2800
3033
|
}
|
|
@@ -2812,7 +3045,7 @@ var BaseOperationHandler = class {
|
|
|
2812
3045
|
}
|
|
2813
3046
|
case "connect": {
|
|
2814
3047
|
const referencedPkFields = relationField.relation.references;
|
|
2815
|
-
(0,
|
|
3048
|
+
(0, import_common_helpers8.invariant)(referencedPkFields, "relation must have fields info");
|
|
2816
3049
|
const extractedFks = extractFields(subPayload, referencedPkFields);
|
|
2817
3050
|
if (Object.keys(extractedFks).length === referencedPkFields.length) {
|
|
2818
3051
|
result = extractedFks;
|
|
@@ -2844,21 +3077,27 @@ var BaseOperationHandler = class {
|
|
|
2844
3077
|
}
|
|
2845
3078
|
return result;
|
|
2846
3079
|
}
|
|
2847
|
-
|
|
3080
|
+
processNoneOwnedRelationForCreate(kysely, contextModel, relationFieldName, payload, parentEntity) {
|
|
2848
3081
|
const relationFieldDef = this.requireField(contextModel, relationFieldName);
|
|
2849
3082
|
const relationModel = relationFieldDef.type;
|
|
2850
3083
|
const tasks = [];
|
|
3084
|
+
const fromRelationContext = {
|
|
3085
|
+
model: contextModel,
|
|
3086
|
+
field: relationFieldName,
|
|
3087
|
+
ids: parentEntity
|
|
3088
|
+
};
|
|
2851
3089
|
for (const [action, subPayload] of Object.entries(payload)) {
|
|
2852
3090
|
if (!subPayload) {
|
|
2853
3091
|
continue;
|
|
2854
3092
|
}
|
|
2855
3093
|
switch (action) {
|
|
2856
3094
|
case "create": {
|
|
2857
|
-
tasks.push(...enumerate(subPayload).map((item) => this.create(kysely, relationModel, item,
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
3095
|
+
tasks.push(...enumerate(subPayload).map((item) => this.create(kysely, relationModel, item, fromRelationContext)));
|
|
3096
|
+
break;
|
|
3097
|
+
}
|
|
3098
|
+
case "createMany": {
|
|
3099
|
+
(0, import_common_helpers8.invariant)(relationFieldDef.array, "relation must be an array for createMany");
|
|
3100
|
+
tasks.push(this.createMany(kysely, relationModel, subPayload, false, fromRelationContext));
|
|
2862
3101
|
break;
|
|
2863
3102
|
}
|
|
2864
3103
|
case "connect": {
|
|
@@ -2888,6 +3127,11 @@ var BaseOperationHandler = class {
|
|
|
2888
3127
|
return Promise.all(tasks);
|
|
2889
3128
|
}
|
|
2890
3129
|
async createMany(kysely, model, input, returnData, fromRelation) {
|
|
3130
|
+
if (!input.data || Array.isArray(input.data) && input.data.length === 0) {
|
|
3131
|
+
return returnData ? [] : {
|
|
3132
|
+
count: 0
|
|
3133
|
+
};
|
|
3134
|
+
}
|
|
2891
3135
|
const modelDef = this.requireModel(model);
|
|
2892
3136
|
let relationKeyPairs = [];
|
|
2893
3137
|
if (fromRelation) {
|
|
@@ -2897,12 +3141,12 @@ var BaseOperationHandler = class {
|
|
|
2897
3141
|
}
|
|
2898
3142
|
relationKeyPairs = keyPairs;
|
|
2899
3143
|
}
|
|
2900
|
-
|
|
3144
|
+
let createData = enumerate(input.data).map((item) => {
|
|
2901
3145
|
const newItem = {};
|
|
2902
3146
|
for (const [name, value] of Object.entries(item)) {
|
|
2903
3147
|
const fieldDef = this.requireField(model, name);
|
|
2904
|
-
(0,
|
|
2905
|
-
newItem[name] = this.dialect.transformPrimitive(value, fieldDef.type);
|
|
3148
|
+
(0, import_common_helpers8.invariant)(!fieldDef.relation, "createMany does not support relations");
|
|
3149
|
+
newItem[name] = this.dialect.transformPrimitive(value, fieldDef.type, !!fieldDef.array);
|
|
2906
3150
|
}
|
|
2907
3151
|
if (fromRelation) {
|
|
2908
3152
|
for (const { fk, pk } of relationKeyPairs) {
|
|
@@ -2911,14 +3155,44 @@ var BaseOperationHandler = class {
|
|
|
2911
3155
|
}
|
|
2912
3156
|
return this.fillGeneratedValues(modelDef, newItem);
|
|
2913
3157
|
});
|
|
3158
|
+
if (!this.dialect.supportInsertWithDefault) {
|
|
3159
|
+
const allPassedFields = createData.reduce((acc, item) => {
|
|
3160
|
+
Object.keys(item).forEach((field) => {
|
|
3161
|
+
if (!acc.includes(field)) {
|
|
3162
|
+
acc.push(field);
|
|
3163
|
+
}
|
|
3164
|
+
});
|
|
3165
|
+
return acc;
|
|
3166
|
+
}, []);
|
|
3167
|
+
for (const item of createData) {
|
|
3168
|
+
if (Object.keys(item).length === allPassedFields.length) {
|
|
3169
|
+
continue;
|
|
3170
|
+
}
|
|
3171
|
+
for (const field of allPassedFields) {
|
|
3172
|
+
if (!(field in item)) {
|
|
3173
|
+
const fieldDef = this.requireField(model, field);
|
|
3174
|
+
if (fieldDef.default !== void 0 && fieldDef.default !== null && typeof fieldDef.default !== "object") {
|
|
3175
|
+
item[field] = this.dialect.transformPrimitive(fieldDef.default, fieldDef.type, !!fieldDef.array);
|
|
3176
|
+
}
|
|
3177
|
+
}
|
|
3178
|
+
}
|
|
3179
|
+
}
|
|
3180
|
+
}
|
|
3181
|
+
if (modelDef.baseModel) {
|
|
3182
|
+
if (input.skipDuplicates) {
|
|
3183
|
+
throw new QueryError('"skipDuplicates" options is not supported for polymorphic models');
|
|
3184
|
+
}
|
|
3185
|
+
const baseCreateResult = await this.processBaseModelCreateMany(kysely, modelDef.baseModel, createData, !!input.skipDuplicates, model);
|
|
3186
|
+
createData = baseCreateResult.remainingFieldRows;
|
|
3187
|
+
}
|
|
2914
3188
|
const query = kysely.insertInto(model).values(createData).$if(!!input.skipDuplicates, (qb) => qb.onConflict((oc) => oc.doNothing())).modifyEnd(this.makeContextComment({
|
|
2915
3189
|
model,
|
|
2916
3190
|
operation: "create"
|
|
2917
3191
|
}));
|
|
2918
3192
|
if (!returnData) {
|
|
2919
|
-
const result = await
|
|
3193
|
+
const result = await this.executeQuery(kysely, query, "createMany");
|
|
2920
3194
|
return {
|
|
2921
|
-
count: Number(result.
|
|
3195
|
+
count: Number(result.numAffectedRows)
|
|
2922
3196
|
};
|
|
2923
3197
|
} else {
|
|
2924
3198
|
const idFields = getIdFields(this.schema, model);
|
|
@@ -2926,10 +3200,46 @@ var BaseOperationHandler = class {
|
|
|
2926
3200
|
return result;
|
|
2927
3201
|
}
|
|
2928
3202
|
}
|
|
3203
|
+
async processBaseModelCreateMany(kysely, model, createRows, skipDuplicates, forModel) {
|
|
3204
|
+
const thisCreateRows = [];
|
|
3205
|
+
const remainingFieldRows = [];
|
|
3206
|
+
const discriminatorField = getDiscriminatorField(this.schema, model);
|
|
3207
|
+
(0, import_common_helpers8.invariant)(discriminatorField, `Base model "${model}" must have a discriminator field`);
|
|
3208
|
+
for (const createFields of createRows) {
|
|
3209
|
+
const thisCreateFields = {};
|
|
3210
|
+
const remainingFields = {};
|
|
3211
|
+
Object.entries(createFields).forEach(([field, value]) => {
|
|
3212
|
+
const fieldDef = this.getField(model, field);
|
|
3213
|
+
if (fieldDef) {
|
|
3214
|
+
thisCreateFields[field] = value;
|
|
3215
|
+
} else {
|
|
3216
|
+
remainingFields[field] = value;
|
|
3217
|
+
}
|
|
3218
|
+
});
|
|
3219
|
+
thisCreateFields[discriminatorField] = forModel;
|
|
3220
|
+
thisCreateRows.push(thisCreateFields);
|
|
3221
|
+
remainingFieldRows.push(remainingFields);
|
|
3222
|
+
}
|
|
3223
|
+
const baseEntities = await this.createMany(kysely, model, {
|
|
3224
|
+
data: thisCreateRows,
|
|
3225
|
+
skipDuplicates
|
|
3226
|
+
}, true);
|
|
3227
|
+
for (let i = 0; i < baseEntities.length; i++) {
|
|
3228
|
+
const idValues = extractIdFields(baseEntities[i], this.schema, model);
|
|
3229
|
+
Object.assign(remainingFieldRows[i], idValues);
|
|
3230
|
+
}
|
|
3231
|
+
return {
|
|
3232
|
+
baseEntities,
|
|
3233
|
+
remainingFieldRows
|
|
3234
|
+
};
|
|
3235
|
+
}
|
|
2929
3236
|
fillGeneratedValues(modelDef, data) {
|
|
2930
3237
|
const fields = modelDef.fields;
|
|
2931
3238
|
const values = clone(data);
|
|
2932
|
-
for (const field
|
|
3239
|
+
for (const [field, fieldDef] of Object.entries(fields)) {
|
|
3240
|
+
if (fieldDef.originModel) {
|
|
3241
|
+
continue;
|
|
3242
|
+
}
|
|
2933
3243
|
if (!(field in data)) {
|
|
2934
3244
|
if (typeof fields[field]?.default === "object" && "kind" in fields[field].default) {
|
|
2935
3245
|
const generated = this.evalGenerator(fields[field].default);
|
|
@@ -2937,7 +3247,7 @@ var BaseOperationHandler = class {
|
|
|
2937
3247
|
values[field] = generated;
|
|
2938
3248
|
}
|
|
2939
3249
|
} else if (fields[field]?.updatedAt) {
|
|
2940
|
-
values[field] = this.dialect.transformPrimitive(/* @__PURE__ */ new Date(), "DateTime");
|
|
3250
|
+
values[field] = this.dialect.transformPrimitive(/* @__PURE__ */ new Date(), "DateTime", false);
|
|
2941
3251
|
}
|
|
2942
3252
|
}
|
|
2943
3253
|
}
|
|
@@ -2945,7 +3255,7 @@ var BaseOperationHandler = class {
|
|
|
2945
3255
|
}
|
|
2946
3256
|
evalGenerator(defaultValue) {
|
|
2947
3257
|
if (ExpressionUtils.isCall(defaultValue)) {
|
|
2948
|
-
return (0,
|
|
3258
|
+
return (0, import_ts_pattern9.match)(defaultValue.function).with("cuid", () => (0, import_cuid2.createId)()).with("uuid", () => defaultValue.args?.[0] && ExpressionUtils.isLiteral(defaultValue.args?.[0]) && defaultValue.args[0].value === 7 ? uuid.v7() : uuid.v4()).with("nanoid", () => defaultValue.args?.[0] && ExpressionUtils.isLiteral(defaultValue.args[0]) && typeof defaultValue.args[0].value === "number" ? (0, import_nanoid.nanoid)(defaultValue.args[0].value) : (0, import_nanoid.nanoid)()).with("ulid", () => (0, import_ulid.ulid)()).otherwise(() => void 0);
|
|
2949
3259
|
} else if (ExpressionUtils.isMember(defaultValue) && ExpressionUtils.isCall(defaultValue.receiver) && defaultValue.receiver.function === "auth") {
|
|
2950
3260
|
let val = this.client.$auth;
|
|
2951
3261
|
for (const member of defaultValue.members) {
|
|
@@ -2980,7 +3290,7 @@ var BaseOperationHandler = class {
|
|
|
2980
3290
|
}
|
|
2981
3291
|
} else {
|
|
2982
3292
|
const fromRelationFieldDef = this.requireField(fromRelation.model, fromRelation.field);
|
|
2983
|
-
(0,
|
|
3293
|
+
(0, import_common_helpers8.invariant)(fromRelationFieldDef.relation?.opposite);
|
|
2984
3294
|
parentWhere[fromRelationFieldDef.relation.opposite] = {
|
|
2985
3295
|
some: fromRelation.ids
|
|
2986
3296
|
};
|
|
@@ -3002,32 +3312,37 @@ var BaseOperationHandler = class {
|
|
|
3002
3312
|
if (finalData === data) {
|
|
3003
3313
|
finalData = clone(data);
|
|
3004
3314
|
}
|
|
3005
|
-
finalData[fieldName] = this.dialect.transformPrimitive(/* @__PURE__ */ new Date(), "DateTime");
|
|
3315
|
+
finalData[fieldName] = this.dialect.transformPrimitive(/* @__PURE__ */ new Date(), "DateTime", false);
|
|
3006
3316
|
}
|
|
3007
3317
|
}
|
|
3008
3318
|
if (Object.keys(finalData).length === 0) {
|
|
3009
|
-
|
|
3010
|
-
|
|
3319
|
+
return combinedWhere;
|
|
3320
|
+
}
|
|
3321
|
+
let needIdRead = false;
|
|
3322
|
+
if (modelDef.baseModel && !this.isIdFilter(model, combinedWhere)) {
|
|
3323
|
+
needIdRead = true;
|
|
3324
|
+
}
|
|
3325
|
+
if (needIdRead) {
|
|
3326
|
+
const readResult = await this.readUnique(kysely, model, {
|
|
3327
|
+
where: combinedWhere,
|
|
3328
|
+
select: this.makeIdSelect(model)
|
|
3011
3329
|
});
|
|
3012
|
-
if (!
|
|
3330
|
+
if (!readResult && throwIfNotFound) {
|
|
3013
3331
|
throw new NotFoundError(model);
|
|
3014
3332
|
}
|
|
3015
|
-
|
|
3333
|
+
combinedWhere = readResult;
|
|
3334
|
+
}
|
|
3335
|
+
if (modelDef.baseModel) {
|
|
3336
|
+
const baseUpdateResult = await this.processBaseModelUpdate(kysely, modelDef.baseModel, combinedWhere, finalData, throwIfNotFound);
|
|
3337
|
+
finalData = baseUpdateResult.remainingFields;
|
|
3338
|
+
combinedWhere = baseUpdateResult.baseEntity;
|
|
3016
3339
|
}
|
|
3017
3340
|
const updateFields = {};
|
|
3018
3341
|
let thisEntity = void 0;
|
|
3019
3342
|
for (const field in finalData) {
|
|
3020
3343
|
const fieldDef = this.requireField(model, field);
|
|
3021
3344
|
if (isScalarField(this.schema, model, field) || isForeignKeyField(this.schema, model, field)) {
|
|
3022
|
-
|
|
3023
|
-
updateFields[field] = this.transformIncrementalUpdate(model, field, fieldDef, finalData[field]);
|
|
3024
|
-
continue;
|
|
3025
|
-
}
|
|
3026
|
-
if (fieldDef.array && typeof finalData[field] === "object" && !Array.isArray(finalData[field]) && finalData[field]) {
|
|
3027
|
-
updateFields[field] = this.transformScalarListUpdate(model, field, fieldDef, finalData[field]);
|
|
3028
|
-
continue;
|
|
3029
|
-
}
|
|
3030
|
-
updateFields[field] = this.dialect.transformPrimitive(finalData[field], fieldDef.type);
|
|
3345
|
+
updateFields[field] = this.processScalarFieldUpdateData(model, field, finalData);
|
|
3031
3346
|
} else {
|
|
3032
3347
|
if (!allowRelationUpdate) {
|
|
3033
3348
|
throw new QueryError(`Relation update not allowed for field "${field}"`);
|
|
@@ -3049,16 +3364,14 @@ var BaseOperationHandler = class {
|
|
|
3049
3364
|
}
|
|
3050
3365
|
}
|
|
3051
3366
|
if (Object.keys(updateFields).length === 0) {
|
|
3052
|
-
return
|
|
3053
|
-
where: combinedWhere
|
|
3054
|
-
});
|
|
3367
|
+
return combinedWhere;
|
|
3055
3368
|
} else {
|
|
3056
3369
|
const idFields = getIdFields(this.schema, model);
|
|
3057
3370
|
const query = kysely.updateTable(model).where((eb) => this.dialect.buildFilter(eb, model, model, combinedWhere)).set(updateFields).returning(idFields).modifyEnd(this.makeContextComment({
|
|
3058
3371
|
model,
|
|
3059
3372
|
operation: "update"
|
|
3060
3373
|
}));
|
|
3061
|
-
const updatedEntity = await
|
|
3374
|
+
const updatedEntity = await this.executeQueryTakeFirst(kysely, query, "update");
|
|
3062
3375
|
if (!updatedEntity) {
|
|
3063
3376
|
if (throwIfNotFound) {
|
|
3064
3377
|
throw new NotFoundError(model);
|
|
@@ -3069,23 +3382,72 @@ var BaseOperationHandler = class {
|
|
|
3069
3382
|
return updatedEntity;
|
|
3070
3383
|
}
|
|
3071
3384
|
}
|
|
3385
|
+
processScalarFieldUpdateData(model, field, data) {
|
|
3386
|
+
const fieldDef = this.requireField(model, field);
|
|
3387
|
+
if (this.isNumericIncrementalUpdate(fieldDef, data[field])) {
|
|
3388
|
+
return this.transformIncrementalUpdate(model, field, fieldDef, data[field]);
|
|
3389
|
+
}
|
|
3390
|
+
if (fieldDef.array && typeof data[field] === "object" && !Array.isArray(data[field]) && data[field]) {
|
|
3391
|
+
return this.transformScalarListUpdate(model, field, fieldDef, data[field]);
|
|
3392
|
+
}
|
|
3393
|
+
return this.dialect.transformPrimitive(data[field], fieldDef.type, !!fieldDef.array);
|
|
3394
|
+
}
|
|
3395
|
+
isNumericIncrementalUpdate(fieldDef, value) {
|
|
3396
|
+
if (!this.isNumericField(fieldDef)) {
|
|
3397
|
+
return false;
|
|
3398
|
+
}
|
|
3399
|
+
if (typeof value !== "object" || !value) {
|
|
3400
|
+
return false;
|
|
3401
|
+
}
|
|
3402
|
+
return [
|
|
3403
|
+
"increment",
|
|
3404
|
+
"decrement",
|
|
3405
|
+
"multiply",
|
|
3406
|
+
"divide",
|
|
3407
|
+
"set"
|
|
3408
|
+
].some((key) => key in value);
|
|
3409
|
+
}
|
|
3410
|
+
isIdFilter(model, filter) {
|
|
3411
|
+
if (!filter || typeof filter !== "object") {
|
|
3412
|
+
return false;
|
|
3413
|
+
}
|
|
3414
|
+
const idFields = getIdFields(this.schema, model);
|
|
3415
|
+
return idFields.length === Object.keys(filter).length && idFields.every((field) => field in filter);
|
|
3416
|
+
}
|
|
3417
|
+
async processBaseModelUpdate(kysely, model, where, updateFields, throwIfNotFound) {
|
|
3418
|
+
const thisUpdateFields = {};
|
|
3419
|
+
const remainingFields = {};
|
|
3420
|
+
Object.entries(updateFields).forEach(([field, value]) => {
|
|
3421
|
+
const fieldDef = this.getField(model, field);
|
|
3422
|
+
if (fieldDef) {
|
|
3423
|
+
thisUpdateFields[field] = value;
|
|
3424
|
+
} else {
|
|
3425
|
+
remainingFields[field] = value;
|
|
3426
|
+
}
|
|
3427
|
+
});
|
|
3428
|
+
const baseEntity = await this.update(kysely, model, where, thisUpdateFields, void 0, void 0, throwIfNotFound);
|
|
3429
|
+
return {
|
|
3430
|
+
baseEntity,
|
|
3431
|
+
remainingFields
|
|
3432
|
+
};
|
|
3433
|
+
}
|
|
3072
3434
|
transformIncrementalUpdate(model, field, fieldDef, payload) {
|
|
3073
|
-
(0,
|
|
3435
|
+
(0, import_common_helpers8.invariant)(Object.keys(payload).length === 1, 'Only one of "set", "increment", "decrement", "multiply", or "divide" can be provided');
|
|
3074
3436
|
const key = Object.keys(payload)[0];
|
|
3075
|
-
const value = this.dialect.transformPrimitive(payload[key], fieldDef.type);
|
|
3437
|
+
const value = this.dialect.transformPrimitive(payload[key], fieldDef.type, false);
|
|
3076
3438
|
const eb = (0, import_kysely8.expressionBuilder)();
|
|
3077
3439
|
const fieldRef = buildFieldRef(this.schema, model, field, this.options, eb);
|
|
3078
|
-
return (0,
|
|
3440
|
+
return (0, import_ts_pattern9.match)(key).with("set", () => value).with("increment", () => eb(fieldRef, "+", value)).with("decrement", () => eb(fieldRef, "-", value)).with("multiply", () => eb(fieldRef, "*", value)).with("divide", () => eb(fieldRef, "/", value)).otherwise(() => {
|
|
3079
3441
|
throw new InternalError(`Invalid incremental update operation: ${key}`);
|
|
3080
3442
|
});
|
|
3081
3443
|
}
|
|
3082
3444
|
transformScalarListUpdate(model, field, fieldDef, payload) {
|
|
3083
|
-
(0,
|
|
3445
|
+
(0, import_common_helpers8.invariant)(Object.keys(payload).length === 1, 'Only one of "set", "push" can be provided');
|
|
3084
3446
|
const key = Object.keys(payload)[0];
|
|
3085
|
-
const value = this.dialect.transformPrimitive(payload[key], fieldDef.type);
|
|
3447
|
+
const value = this.dialect.transformPrimitive(payload[key], fieldDef.type, true);
|
|
3086
3448
|
const eb = (0, import_kysely8.expressionBuilder)();
|
|
3087
3449
|
const fieldRef = buildFieldRef(this.schema, model, field, this.options, eb);
|
|
3088
|
-
return (0,
|
|
3450
|
+
return (0, import_ts_pattern9.match)(key).with("set", () => value).with("push", () => {
|
|
3089
3451
|
return eb(fieldRef, "||", eb.val(ensureArray(value)));
|
|
3090
3452
|
}).otherwise(() => {
|
|
3091
3453
|
throw new InternalError(`Invalid array update operation: ${key}`);
|
|
@@ -3097,7 +3459,7 @@ var BaseOperationHandler = class {
|
|
|
3097
3459
|
makeContextComment(context) {
|
|
3098
3460
|
return import_kysely8.sql.raw(`${CONTEXT_COMMENT_PREFIX}${JSON.stringify(context)}`);
|
|
3099
3461
|
}
|
|
3100
|
-
async updateMany(kysely, model, where, data, limit, returnData) {
|
|
3462
|
+
async updateMany(kysely, model, where, data, limit, returnData, filterModel) {
|
|
3101
3463
|
if (typeof data !== "object") {
|
|
3102
3464
|
throw new InternalError("data must be an object");
|
|
3103
3465
|
}
|
|
@@ -3106,49 +3468,79 @@ var BaseOperationHandler = class {
|
|
|
3106
3468
|
count: 0
|
|
3107
3469
|
};
|
|
3108
3470
|
}
|
|
3109
|
-
const
|
|
3471
|
+
const modelDef = this.requireModel(model);
|
|
3472
|
+
if (modelDef.baseModel && limit !== void 0) {
|
|
3473
|
+
throw new QueryError("Updating with a limit is not supported for polymorphic models");
|
|
3474
|
+
}
|
|
3475
|
+
filterModel ??= model;
|
|
3476
|
+
let updateFields = {};
|
|
3110
3477
|
for (const field in data) {
|
|
3111
|
-
const fieldDef = this.requireField(model, field);
|
|
3112
3478
|
if (isRelationField(this.schema, model, field)) {
|
|
3113
3479
|
continue;
|
|
3114
3480
|
}
|
|
3115
|
-
updateFields[field] = this.
|
|
3481
|
+
updateFields[field] = this.processScalarFieldUpdateData(model, field, data);
|
|
3482
|
+
}
|
|
3483
|
+
let shouldFallbackToIdFilter = false;
|
|
3484
|
+
if (limit !== void 0 && !this.dialect.supportsUpdateWithLimit) {
|
|
3485
|
+
shouldFallbackToIdFilter = true;
|
|
3486
|
+
}
|
|
3487
|
+
if (modelDef.isDelegate || modelDef.baseModel) {
|
|
3488
|
+
shouldFallbackToIdFilter = true;
|
|
3489
|
+
}
|
|
3490
|
+
let resultFromBaseModel = void 0;
|
|
3491
|
+
if (modelDef.baseModel) {
|
|
3492
|
+
const baseResult = await this.processBaseModelUpdateMany(kysely, modelDef.baseModel, where, updateFields, filterModel);
|
|
3493
|
+
updateFields = baseResult.remainingFields;
|
|
3494
|
+
resultFromBaseModel = baseResult.baseResult;
|
|
3495
|
+
}
|
|
3496
|
+
if (Object.keys(updateFields).length === 0) {
|
|
3497
|
+
return resultFromBaseModel ?? (returnData ? [] : {
|
|
3498
|
+
count: 0
|
|
3499
|
+
});
|
|
3116
3500
|
}
|
|
3117
3501
|
let query = kysely.updateTable(model).set(updateFields);
|
|
3118
|
-
if (
|
|
3119
|
-
query = query.where((eb) => this.dialect.buildFilter(eb, model, model, where));
|
|
3502
|
+
if (!shouldFallbackToIdFilter) {
|
|
3503
|
+
query = query.where((eb) => this.dialect.buildFilter(eb, model, model, where)).$if(limit !== void 0, (qb) => qb.limit(limit));
|
|
3120
3504
|
} else {
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
query = query.where((eb) => eb(eb.refTuple(
|
|
3125
|
-
...this.buildIdFieldRefs(kysely, model)
|
|
3126
|
-
), "in", kysely.selectFrom(model).where((eb2) => this.dialect.buildFilter(eb2, model, model, where)).select(this.buildIdFieldRefs(kysely, model)).limit(limit)));
|
|
3127
|
-
}
|
|
3505
|
+
query = query.where((eb) => eb(eb.refTuple(
|
|
3506
|
+
...this.buildIdFieldRefs(kysely, model)
|
|
3507
|
+
), "in", this.dialect.buildSelectModel(eb, filterModel).where(this.dialect.buildFilter(eb, filterModel, filterModel, where)).select(this.buildIdFieldRefs(kysely, filterModel)).$if(limit !== void 0, (qb) => qb.limit(limit))));
|
|
3128
3508
|
}
|
|
3129
3509
|
query = query.modifyEnd(this.makeContextComment({
|
|
3130
3510
|
model,
|
|
3131
3511
|
operation: "update"
|
|
3132
3512
|
}));
|
|
3133
|
-
|
|
3134
|
-
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3513
|
+
if (!returnData) {
|
|
3514
|
+
const result = await this.executeQuery(kysely, query, "update");
|
|
3515
|
+
return {
|
|
3516
|
+
count: Number(result.numAffectedRows)
|
|
3517
|
+
};
|
|
3518
|
+
} else {
|
|
3519
|
+
const idFields = getIdFields(this.schema, model);
|
|
3520
|
+
const result = await query.returning(idFields).execute();
|
|
3521
|
+
return result;
|
|
3522
|
+
}
|
|
3523
|
+
}
|
|
3524
|
+
async processBaseModelUpdateMany(kysely, model, where, updateFields, filterModel) {
|
|
3525
|
+
const thisUpdateFields = {};
|
|
3526
|
+
const remainingFields = {};
|
|
3527
|
+
Object.entries(updateFields).forEach(([field, value]) => {
|
|
3528
|
+
const fieldDef = this.getField(model, field);
|
|
3529
|
+
if (fieldDef) {
|
|
3530
|
+
thisUpdateFields[field] = value;
|
|
3139
3531
|
} else {
|
|
3140
|
-
|
|
3141
|
-
const result = await query.returning(idFields).execute();
|
|
3142
|
-
return result;
|
|
3532
|
+
remainingFields[field] = value;
|
|
3143
3533
|
}
|
|
3144
|
-
}
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3534
|
+
});
|
|
3535
|
+
const baseResult = await this.updateMany(kysely, model, where, thisUpdateFields, void 0, false, filterModel);
|
|
3536
|
+
return {
|
|
3537
|
+
baseResult,
|
|
3538
|
+
remainingFields
|
|
3539
|
+
};
|
|
3148
3540
|
}
|
|
3149
3541
|
buildIdFieldRefs(kysely, model) {
|
|
3150
3542
|
const idFields = getIdFields(this.schema, model);
|
|
3151
|
-
return idFields.map((f) => kysely.dynamic.ref(f));
|
|
3543
|
+
return idFields.map((f) => kysely.dynamic.ref(`${model}.${f}`));
|
|
3152
3544
|
}
|
|
3153
3545
|
async processRelationUpdates(kysely, model, field, fieldDef, parentIds, args, throwIfNotFound) {
|
|
3154
3546
|
const tasks = [];
|
|
@@ -3161,12 +3553,12 @@ var BaseOperationHandler = class {
|
|
|
3161
3553
|
for (const [key, value] of Object.entries(args)) {
|
|
3162
3554
|
switch (key) {
|
|
3163
3555
|
case "create": {
|
|
3164
|
-
(0,
|
|
3556
|
+
(0, import_common_helpers8.invariant)(!Array.isArray(value) || fieldDef.array, "relation must be an array if create is an array");
|
|
3165
3557
|
tasks.push(...enumerate(value).map((item) => this.create(kysely, fieldModel, item, fromRelationContext)));
|
|
3166
3558
|
break;
|
|
3167
3559
|
}
|
|
3168
3560
|
case "createMany": {
|
|
3169
|
-
(0,
|
|
3561
|
+
(0, import_common_helpers8.invariant)(fieldDef.array, "relation must be an array for createMany");
|
|
3170
3562
|
tasks.push(this.createMany(kysely, fieldModel, value, false, fromRelationContext));
|
|
3171
3563
|
break;
|
|
3172
3564
|
}
|
|
@@ -3183,7 +3575,7 @@ var BaseOperationHandler = class {
|
|
|
3183
3575
|
break;
|
|
3184
3576
|
}
|
|
3185
3577
|
case "set": {
|
|
3186
|
-
(0,
|
|
3578
|
+
(0, import_common_helpers8.invariant)(fieldDef.array, "relation must be an array");
|
|
3187
3579
|
tasks.push(this.setRelation(kysely, fieldModel, value, fromRelationContext));
|
|
3188
3580
|
break;
|
|
3189
3581
|
}
|
|
@@ -3252,7 +3644,7 @@ var BaseOperationHandler = class {
|
|
|
3252
3644
|
const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
|
|
3253
3645
|
let updateResult;
|
|
3254
3646
|
if (ownedByModel) {
|
|
3255
|
-
(0,
|
|
3647
|
+
(0, import_common_helpers8.invariant)(_data.length === 1, "only one entity can be connected");
|
|
3256
3648
|
const target = await this.readUnique(kysely, model, {
|
|
3257
3649
|
where: _data[0]
|
|
3258
3650
|
});
|
|
@@ -3266,7 +3658,7 @@ var BaseOperationHandler = class {
|
|
|
3266
3658
|
model: fromRelation.model,
|
|
3267
3659
|
operation: "update"
|
|
3268
3660
|
}));
|
|
3269
|
-
updateResult = await
|
|
3661
|
+
updateResult = await this.executeQuery(kysely, query, "connect");
|
|
3270
3662
|
} else {
|
|
3271
3663
|
const relationFieldDef = this.requireField(fromRelation.model, fromRelation.field);
|
|
3272
3664
|
if (!relationFieldDef.array) {
|
|
@@ -3277,7 +3669,7 @@ var BaseOperationHandler = class {
|
|
|
3277
3669
|
model: fromRelation.model,
|
|
3278
3670
|
operation: "update"
|
|
3279
3671
|
}));
|
|
3280
|
-
await
|
|
3672
|
+
await this.executeQuery(kysely, query2, "disconnect");
|
|
3281
3673
|
}
|
|
3282
3674
|
const query = kysely.updateTable(model).where((eb) => eb.or(_data.map((d) => eb.and(d)))).set(keyPairs.reduce((acc, { fk, pk }) => ({
|
|
3283
3675
|
...acc,
|
|
@@ -3286,9 +3678,9 @@ var BaseOperationHandler = class {
|
|
|
3286
3678
|
model,
|
|
3287
3679
|
operation: "update"
|
|
3288
3680
|
}));
|
|
3289
|
-
updateResult = await
|
|
3681
|
+
updateResult = await this.executeQuery(kysely, query, "connect");
|
|
3290
3682
|
}
|
|
3291
|
-
if (_data.length > updateResult.
|
|
3683
|
+
if (_data.length > updateResult.numAffectedRows) {
|
|
3292
3684
|
throw new NotFoundError(model);
|
|
3293
3685
|
}
|
|
3294
3686
|
}
|
|
@@ -3342,7 +3734,7 @@ var BaseOperationHandler = class {
|
|
|
3342
3734
|
const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
|
|
3343
3735
|
const eb = (0, import_kysely8.expressionBuilder)();
|
|
3344
3736
|
if (ownedByModel) {
|
|
3345
|
-
(0,
|
|
3737
|
+
(0, import_common_helpers8.invariant)(disconnectConditions.length === 1, "only one entity can be disconnected");
|
|
3346
3738
|
const condition = disconnectConditions[0];
|
|
3347
3739
|
const query = kysely.updateTable(fromRelation.model).where(eb.and(fromRelation.ids)).$if(condition !== true, (qb) => qb.where(eb(
|
|
3348
3740
|
// @ts-ignore
|
|
@@ -3356,7 +3748,7 @@ var BaseOperationHandler = class {
|
|
|
3356
3748
|
model: fromRelation.model,
|
|
3357
3749
|
operation: "update"
|
|
3358
3750
|
}));
|
|
3359
|
-
await
|
|
3751
|
+
await this.executeQuery(kysely, query, "disconnect");
|
|
3360
3752
|
} else {
|
|
3361
3753
|
const query = kysely.updateTable(model).where(eb.and([
|
|
3362
3754
|
// fk filter
|
|
@@ -3373,7 +3765,7 @@ var BaseOperationHandler = class {
|
|
|
3373
3765
|
model,
|
|
3374
3766
|
operation: "update"
|
|
3375
3767
|
}));
|
|
3376
|
-
await
|
|
3768
|
+
await this.executeQuery(kysely, query, "disconnect");
|
|
3377
3769
|
}
|
|
3378
3770
|
}
|
|
3379
3771
|
}
|
|
@@ -3411,7 +3803,7 @@ var BaseOperationHandler = class {
|
|
|
3411
3803
|
model,
|
|
3412
3804
|
operation: "update"
|
|
3413
3805
|
}));
|
|
3414
|
-
await
|
|
3806
|
+
await this.executeQuery(kysely, query, "disconnect");
|
|
3415
3807
|
if (_data.length > 0) {
|
|
3416
3808
|
const query2 = kysely.updateTable(model).where((eb) => eb.or(_data.map((d) => eb.and(d)))).set(keyPairs.reduce((acc, { fk, pk }) => ({
|
|
3417
3809
|
...acc,
|
|
@@ -3420,8 +3812,8 @@ var BaseOperationHandler = class {
|
|
|
3420
3812
|
model,
|
|
3421
3813
|
operation: "update"
|
|
3422
3814
|
}));
|
|
3423
|
-
const r = await
|
|
3424
|
-
if (_data.length > r.
|
|
3815
|
+
const r = await this.executeQuery(kysely, query2, "connect");
|
|
3816
|
+
if (_data.length > r.numAffectedRows) {
|
|
3425
3817
|
throw new NotFoundError(model);
|
|
3426
3818
|
}
|
|
3427
3819
|
}
|
|
@@ -3450,7 +3842,7 @@ var BaseOperationHandler = class {
|
|
|
3450
3842
|
const m2m = getManyToManyRelation(this.schema, fromRelation.model, fromRelation.field);
|
|
3451
3843
|
if (m2m) {
|
|
3452
3844
|
const fieldDef = this.requireField(fromRelation.model, fromRelation.field);
|
|
3453
|
-
(0,
|
|
3845
|
+
(0, import_common_helpers8.invariant)(fieldDef.relation?.opposite);
|
|
3454
3846
|
deleteResult = await this.delete(kysely, model, {
|
|
3455
3847
|
AND: [
|
|
3456
3848
|
{
|
|
@@ -3462,7 +3854,7 @@ var BaseOperationHandler = class {
|
|
|
3462
3854
|
OR: deleteConditions
|
|
3463
3855
|
}
|
|
3464
3856
|
]
|
|
3465
|
-
}
|
|
3857
|
+
});
|
|
3466
3858
|
} else {
|
|
3467
3859
|
const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, fromRelation.model, fromRelation.field);
|
|
3468
3860
|
if (ownedByModel) {
|
|
@@ -3473,7 +3865,7 @@ var BaseOperationHandler = class {
|
|
|
3473
3865
|
throw new NotFoundError(model);
|
|
3474
3866
|
}
|
|
3475
3867
|
const fieldDef = this.requireField(fromRelation.model, fromRelation.field);
|
|
3476
|
-
(0,
|
|
3868
|
+
(0, import_common_helpers8.invariant)(fieldDef.relation?.opposite);
|
|
3477
3869
|
deleteResult = await this.delete(kysely, model, {
|
|
3478
3870
|
AND: [
|
|
3479
3871
|
// filter for parent
|
|
@@ -3485,7 +3877,7 @@ var BaseOperationHandler = class {
|
|
|
3485
3877
|
OR: deleteConditions
|
|
3486
3878
|
}
|
|
3487
3879
|
]
|
|
3488
|
-
}
|
|
3880
|
+
});
|
|
3489
3881
|
} else {
|
|
3490
3882
|
deleteResult = await this.delete(kysely, model, {
|
|
3491
3883
|
AND: [
|
|
@@ -3497,7 +3889,7 @@ var BaseOperationHandler = class {
|
|
|
3497
3889
|
OR: deleteConditions
|
|
3498
3890
|
}
|
|
3499
3891
|
]
|
|
3500
|
-
}
|
|
3892
|
+
});
|
|
3501
3893
|
}
|
|
3502
3894
|
}
|
|
3503
3895
|
if (throwForNotFound && expectedDeleteCount > deleteResult.count) {
|
|
@@ -3508,33 +3900,59 @@ var BaseOperationHandler = class {
|
|
|
3508
3900
|
return enumerate(data).map((item) => flattenCompoundUniqueFilters(this.schema, model, item));
|
|
3509
3901
|
}
|
|
3510
3902
|
// #endregion
|
|
3511
|
-
async delete(kysely, model, where, limit,
|
|
3903
|
+
async delete(kysely, model, where, limit, filterModel) {
|
|
3904
|
+
filterModel ??= model;
|
|
3905
|
+
const modelDef = this.requireModel(model);
|
|
3906
|
+
if (modelDef.baseModel) {
|
|
3907
|
+
if (limit !== void 0) {
|
|
3908
|
+
throw new QueryError("Deleting with a limit is not supported for polymorphic models");
|
|
3909
|
+
}
|
|
3910
|
+
return this.processBaseModelDelete(kysely, modelDef.baseModel, where, limit, filterModel);
|
|
3911
|
+
}
|
|
3512
3912
|
let query = kysely.deleteFrom(model);
|
|
3513
|
-
|
|
3913
|
+
let needIdFilter = false;
|
|
3914
|
+
if (limit !== void 0 && !this.dialect.supportsDeleteWithLimit) {
|
|
3915
|
+
needIdFilter = true;
|
|
3916
|
+
}
|
|
3917
|
+
if (modelDef.isDelegate || modelDef.baseModel) {
|
|
3918
|
+
needIdFilter = true;
|
|
3919
|
+
}
|
|
3920
|
+
if (!needIdFilter) {
|
|
3514
3921
|
query = query.where((eb) => this.dialect.buildFilter(eb, model, model, where));
|
|
3515
3922
|
} else {
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
query = query.where((eb) => eb(eb.refTuple(
|
|
3520
|
-
...this.buildIdFieldRefs(kysely, model)
|
|
3521
|
-
), "in", kysely.selectFrom(model).where((eb2) => this.dialect.buildFilter(eb2, model, model, where)).select(this.buildIdFieldRefs(kysely, model)).limit(limit)));
|
|
3522
|
-
}
|
|
3923
|
+
query = query.where((eb) => eb(eb.refTuple(
|
|
3924
|
+
...this.buildIdFieldRefs(kysely, model)
|
|
3925
|
+
), "in", this.dialect.buildSelectModel(eb, filterModel).where((eb2) => this.dialect.buildFilter(eb2, filterModel, filterModel, where)).select(this.buildIdFieldRefs(kysely, filterModel)).$if(limit !== void 0, (qb) => qb.limit(limit))));
|
|
3523
3926
|
}
|
|
3927
|
+
await this.processDelegateRelationDelete(kysely, modelDef, where, limit);
|
|
3524
3928
|
query = query.modifyEnd(this.makeContextComment({
|
|
3525
3929
|
model,
|
|
3526
3930
|
operation: "delete"
|
|
3527
3931
|
}));
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
}
|
|
3532
|
-
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3932
|
+
const result = await this.executeQuery(kysely, query, "delete");
|
|
3933
|
+
return {
|
|
3934
|
+
count: Number(result.numAffectedRows)
|
|
3935
|
+
};
|
|
3936
|
+
}
|
|
3937
|
+
async processDelegateRelationDelete(kysely, modelDef, where, limit) {
|
|
3938
|
+
for (const fieldDef of Object.values(modelDef.fields)) {
|
|
3939
|
+
if (fieldDef.relation && fieldDef.relation.opposite) {
|
|
3940
|
+
const oppositeModelDef = this.requireModel(fieldDef.type);
|
|
3941
|
+
const oppositeRelation = this.requireField(fieldDef.type, fieldDef.relation.opposite);
|
|
3942
|
+
if (oppositeModelDef.baseModel && oppositeRelation.relation?.onDelete === "Cascade") {
|
|
3943
|
+
if (limit !== void 0) {
|
|
3944
|
+
throw new QueryError("Deleting with a limit is not supported for polymorphic models");
|
|
3945
|
+
}
|
|
3946
|
+
await this.delete(kysely, fieldDef.type, {
|
|
3947
|
+
[fieldDef.relation.opposite]: where
|
|
3948
|
+
}, void 0);
|
|
3949
|
+
}
|
|
3950
|
+
}
|
|
3536
3951
|
}
|
|
3537
3952
|
}
|
|
3953
|
+
async processBaseModelDelete(kysely, model, where, limit, filterModel) {
|
|
3954
|
+
return this.delete(kysely, model, where, limit, filterModel);
|
|
3955
|
+
}
|
|
3538
3956
|
makeIdSelect(model) {
|
|
3539
3957
|
const modelDef = this.requireModel(model);
|
|
3540
3958
|
return modelDef.idFields.reduce((acc, f) => {
|
|
@@ -3543,7 +3961,7 @@ var BaseOperationHandler = class {
|
|
|
3543
3961
|
}, {});
|
|
3544
3962
|
}
|
|
3545
3963
|
trimResult(data, args) {
|
|
3546
|
-
if (!args.select) {
|
|
3964
|
+
if (!("select" in args) || !args.select) {
|
|
3547
3965
|
return data;
|
|
3548
3966
|
}
|
|
3549
3967
|
return Object.keys(args.select).reduce((acc, field) => {
|
|
@@ -3553,9 +3971,9 @@ var BaseOperationHandler = class {
|
|
|
3553
3971
|
}
|
|
3554
3972
|
needReturnRelations(model, args) {
|
|
3555
3973
|
let returnRelation = false;
|
|
3556
|
-
if (args.include) {
|
|
3974
|
+
if ("include" in args && args.include) {
|
|
3557
3975
|
returnRelation = Object.keys(args.include).length > 0;
|
|
3558
|
-
} else if (args.select) {
|
|
3976
|
+
} else if ("select" in args && args.select) {
|
|
3559
3977
|
returnRelation = Object.entries(args.select).some(([K, v]) => {
|
|
3560
3978
|
const fieldDef = this.requireField(model, K);
|
|
3561
3979
|
return fieldDef.relation && v;
|
|
@@ -3563,11 +3981,13 @@ var BaseOperationHandler = class {
|
|
|
3563
3981
|
}
|
|
3564
3982
|
return returnRelation;
|
|
3565
3983
|
}
|
|
3566
|
-
async safeTransaction(callback) {
|
|
3984
|
+
async safeTransaction(callback, isolationLevel) {
|
|
3567
3985
|
if (this.kysely.isTransaction) {
|
|
3568
3986
|
return callback(this.kysely);
|
|
3569
3987
|
} else {
|
|
3570
|
-
|
|
3988
|
+
let txBuilder = this.kysely.transaction();
|
|
3989
|
+
txBuilder = txBuilder.setIsolationLevel(isolationLevel ?? "repeatable read");
|
|
3990
|
+
return txBuilder.execute(callback);
|
|
3571
3991
|
}
|
|
3572
3992
|
}
|
|
3573
3993
|
// Given a unique filter of a model, return the entity ids by trying to
|
|
@@ -3586,6 +4006,47 @@ var BaseOperationHandler = class {
|
|
|
3586
4006
|
where: uniqueFilter
|
|
3587
4007
|
});
|
|
3588
4008
|
}
|
|
4009
|
+
/**
|
|
4010
|
+
* Normalize input args to strip `undefined` fields
|
|
4011
|
+
*/
|
|
4012
|
+
normalizeArgs(args) {
|
|
4013
|
+
if (!args) {
|
|
4014
|
+
return;
|
|
4015
|
+
}
|
|
4016
|
+
const newArgs = clone(args);
|
|
4017
|
+
this.doNormalizeArgs(newArgs);
|
|
4018
|
+
return newArgs;
|
|
4019
|
+
}
|
|
4020
|
+
doNormalizeArgs(args) {
|
|
4021
|
+
if (args && typeof args === "object") {
|
|
4022
|
+
for (const [key, value] of Object.entries(args)) {
|
|
4023
|
+
if (value === void 0) {
|
|
4024
|
+
delete args[key];
|
|
4025
|
+
} else if (value && (0, import_common_helpers8.isPlainObject)(value)) {
|
|
4026
|
+
this.doNormalizeArgs(value);
|
|
4027
|
+
}
|
|
4028
|
+
}
|
|
4029
|
+
}
|
|
4030
|
+
}
|
|
4031
|
+
makeQueryId(operation) {
|
|
4032
|
+
return {
|
|
4033
|
+
queryId: `${operation}-${(0, import_cuid2.createId)()}`
|
|
4034
|
+
};
|
|
4035
|
+
}
|
|
4036
|
+
executeQuery(kysely, query, operation) {
|
|
4037
|
+
return kysely.executeQuery(query.compile(), this.makeQueryId(operation));
|
|
4038
|
+
}
|
|
4039
|
+
async executeQueryTakeFirst(kysely, query, operation) {
|
|
4040
|
+
const result = await kysely.executeQuery(query.compile(), this.makeQueryId(operation));
|
|
4041
|
+
return result.rows[0];
|
|
4042
|
+
}
|
|
4043
|
+
async executeQueryTakeFirstOrThrow(kysely, query, operation) {
|
|
4044
|
+
const result = await kysely.executeQuery(query.compile(), this.makeQueryId(operation));
|
|
4045
|
+
if (result.rows.length === 0) {
|
|
4046
|
+
throw new QueryError("No rows found");
|
|
4047
|
+
}
|
|
4048
|
+
return result.rows[0];
|
|
4049
|
+
}
|
|
3589
4050
|
};
|
|
3590
4051
|
|
|
3591
4052
|
// src/client/crud/operations/aggregate.ts
|
|
@@ -3594,21 +4055,37 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
|
|
|
3594
4055
|
__name(this, "AggregateOperationHandler");
|
|
3595
4056
|
}
|
|
3596
4057
|
async handle(_operation, args) {
|
|
3597
|
-
const
|
|
4058
|
+
const normalizedArgs = this.normalizeArgs(args);
|
|
4059
|
+
const parsedArgs = this.inputValidator.validateAggregateArgs(this.model, normalizedArgs);
|
|
3598
4060
|
let query = this.kysely.selectFrom((eb) => {
|
|
3599
|
-
let subQuery =
|
|
3600
|
-
const
|
|
3601
|
-
|
|
4061
|
+
let subQuery = this.dialect.buildSelectModel(eb, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
|
|
4062
|
+
const selectedFields = [];
|
|
4063
|
+
for (const [key, value] of Object.entries(parsedArgs)) {
|
|
4064
|
+
if (key.startsWith("_") && value && typeof value === "object") {
|
|
4065
|
+
Object.entries(value).filter(([field]) => field !== "_all").filter(([, val]) => val === true).forEach(([field]) => {
|
|
4066
|
+
if (!selectedFields.includes(field)) selectedFields.push(field);
|
|
4067
|
+
});
|
|
4068
|
+
}
|
|
4069
|
+
}
|
|
4070
|
+
if (selectedFields.length > 0) {
|
|
4071
|
+
for (const field of selectedFields) {
|
|
4072
|
+
subQuery = this.dialect.buildSelectField(subQuery, this.model, this.model, field);
|
|
4073
|
+
}
|
|
4074
|
+
} else {
|
|
4075
|
+
subQuery = subQuery.select(() => eb.lit(1).as("_all"));
|
|
4076
|
+
}
|
|
4077
|
+
const skip = parsedArgs?.skip;
|
|
4078
|
+
let take = parsedArgs?.take;
|
|
3602
4079
|
let negateOrderBy = false;
|
|
3603
4080
|
if (take !== void 0 && take < 0) {
|
|
3604
4081
|
negateOrderBy = true;
|
|
3605
4082
|
take = -take;
|
|
3606
4083
|
}
|
|
3607
4084
|
subQuery = this.dialect.buildSkipTake(subQuery, skip, take);
|
|
3608
|
-
subQuery = this.dialect.buildOrderBy(subQuery, this.model, this.model,
|
|
4085
|
+
subQuery = this.dialect.buildOrderBy(subQuery, this.model, this.model, parsedArgs.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
|
|
3609
4086
|
return subQuery.as("$sub");
|
|
3610
4087
|
});
|
|
3611
|
-
for (const [key, value] of Object.entries(
|
|
4088
|
+
for (const [key, value] of Object.entries(parsedArgs)) {
|
|
3612
4089
|
switch (key) {
|
|
3613
4090
|
case "_count": {
|
|
3614
4091
|
if (value === true) {
|
|
@@ -3633,7 +4110,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
|
|
|
3633
4110
|
Object.entries(value).forEach(([field, val]) => {
|
|
3634
4111
|
if (val === true) {
|
|
3635
4112
|
query = query.select((eb) => {
|
|
3636
|
-
const fn = (0,
|
|
4113
|
+
const fn = (0, import_ts_pattern10.match)(key).with("_sum", () => eb.fn.sum).with("_avg", () => eb.fn.avg).with("_max", () => eb.fn.max).with("_min", () => eb.fn.min).exhaustive();
|
|
3637
4114
|
return fn(import_kysely9.sql.ref(`$sub.${field}`)).as(`${key}.${field}`);
|
|
3638
4115
|
});
|
|
3639
4116
|
}
|
|
@@ -3642,9 +4119,9 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
|
|
|
3642
4119
|
}
|
|
3643
4120
|
}
|
|
3644
4121
|
}
|
|
3645
|
-
const result = await
|
|
4122
|
+
const result = await this.executeQuery(this.kysely, query, "aggregate");
|
|
3646
4123
|
const ret = {};
|
|
3647
|
-
for (const [key, value] of Object.entries(result)) {
|
|
4124
|
+
for (const [key, value] of Object.entries(result.rows[0])) {
|
|
3648
4125
|
if (key === "_count") {
|
|
3649
4126
|
ret[key] = value;
|
|
3650
4127
|
continue;
|
|
@@ -3666,7 +4143,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
|
|
|
3666
4143
|
val = parseFloat(val);
|
|
3667
4144
|
} else {
|
|
3668
4145
|
if (op === "_sum" || op === "_min" || op === "_max") {
|
|
3669
|
-
val = (0,
|
|
4146
|
+
val = (0, import_ts_pattern10.match)(type).with("Int", () => parseInt(value, 10)).with("BigInt", () => BigInt(value)).with("Float", () => parseFloat(value)).with("Decimal", () => parseFloat(value)).otherwise(() => value);
|
|
3670
4147
|
}
|
|
3671
4148
|
}
|
|
3672
4149
|
}
|
|
@@ -3687,34 +4164,47 @@ var CountOperationHandler = class extends BaseOperationHandler {
|
|
|
3687
4164
|
__name(this, "CountOperationHandler");
|
|
3688
4165
|
}
|
|
3689
4166
|
async handle(_operation, args) {
|
|
3690
|
-
const
|
|
4167
|
+
const normalizedArgs = this.normalizeArgs(args);
|
|
4168
|
+
const parsedArgs = this.inputValidator.validateCountArgs(this.model, normalizedArgs);
|
|
4169
|
+
const subQueryName = "$sub";
|
|
3691
4170
|
let query = this.kysely.selectFrom((eb) => {
|
|
3692
|
-
let subQuery =
|
|
3693
|
-
|
|
3694
|
-
|
|
4171
|
+
let subQuery = this.dialect.buildSelectModel(eb, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
|
|
4172
|
+
if (parsedArgs?.select && typeof parsedArgs.select === "object") {
|
|
4173
|
+
for (const [key, value] of Object.entries(parsedArgs.select)) {
|
|
4174
|
+
if (key !== "_all" && value === true) {
|
|
4175
|
+
subQuery = this.dialect.buildSelectField(subQuery, this.model, this.model, key);
|
|
4176
|
+
}
|
|
4177
|
+
}
|
|
4178
|
+
} else {
|
|
4179
|
+
subQuery = subQuery.select(() => eb.lit(1).as("_all"));
|
|
4180
|
+
}
|
|
4181
|
+
subQuery = this.dialect.buildSkipTake(subQuery, parsedArgs?.skip, parsedArgs?.take);
|
|
4182
|
+
return subQuery.as(subQueryName);
|
|
3695
4183
|
});
|
|
3696
|
-
if (
|
|
3697
|
-
query = query.select((eb) => Object.keys(
|
|
3698
|
-
|
|
4184
|
+
if (parsedArgs?.select && typeof parsedArgs.select === "object") {
|
|
4185
|
+
query = query.select((eb) => Object.keys(parsedArgs.select).map((key) => key === "_all" ? eb.cast(eb.fn.countAll(), "integer").as("_all") : eb.cast(eb.fn.count(import_kysely10.sql.ref(`${subQueryName}.${key}`)), "integer").as(key)));
|
|
4186
|
+
const result = await this.executeQuery(this.kysely, query, "count");
|
|
4187
|
+
return result.rows[0];
|
|
3699
4188
|
} else {
|
|
3700
4189
|
query = query.select((eb) => eb.cast(eb.fn.countAll(), "integer").as("count"));
|
|
3701
|
-
const result = await
|
|
3702
|
-
return result.count;
|
|
4190
|
+
const result = await this.executeQuery(this.kysely, query, "count");
|
|
4191
|
+
return result.rows[0].count;
|
|
3703
4192
|
}
|
|
3704
4193
|
}
|
|
3705
4194
|
};
|
|
3706
4195
|
|
|
3707
4196
|
// src/client/crud/operations/create.ts
|
|
3708
|
-
var
|
|
4197
|
+
var import_ts_pattern11 = require("ts-pattern");
|
|
3709
4198
|
var CreateOperationHandler = class extends BaseOperationHandler {
|
|
3710
4199
|
static {
|
|
3711
4200
|
__name(this, "CreateOperationHandler");
|
|
3712
4201
|
}
|
|
3713
4202
|
async handle(operation, args) {
|
|
3714
|
-
|
|
3715
|
-
|
|
4203
|
+
const normalizedArgs = this.normalizeArgs(args);
|
|
4204
|
+
return (0, import_ts_pattern11.match)(operation).with("create", () => this.runCreate(this.inputValidator.validateCreateArgs(this.model, normalizedArgs))).with("createMany", () => {
|
|
4205
|
+
return this.runCreateMany(this.inputValidator.validateCreateManyArgs(this.model, normalizedArgs));
|
|
3716
4206
|
}).with("createManyAndReturn", () => {
|
|
3717
|
-
return this.runCreateManyAndReturn(this.inputValidator.validateCreateManyAndReturnArgs(this.model,
|
|
4207
|
+
return this.runCreateManyAndReturn(this.inputValidator.validateCreateManyAndReturnArgs(this.model, normalizedArgs));
|
|
3718
4208
|
}).exhaustive();
|
|
3719
4209
|
}
|
|
3720
4210
|
async runCreate(args) {
|
|
@@ -3758,13 +4248,14 @@ var CreateOperationHandler = class extends BaseOperationHandler {
|
|
|
3758
4248
|
};
|
|
3759
4249
|
|
|
3760
4250
|
// src/client/crud/operations/delete.ts
|
|
3761
|
-
var
|
|
4251
|
+
var import_ts_pattern12 = require("ts-pattern");
|
|
3762
4252
|
var DeleteOperationHandler = class extends BaseOperationHandler {
|
|
3763
4253
|
static {
|
|
3764
4254
|
__name(this, "DeleteOperationHandler");
|
|
3765
4255
|
}
|
|
3766
4256
|
async handle(operation, args) {
|
|
3767
|
-
|
|
4257
|
+
const normalizedArgs = this.normalizeArgs(args);
|
|
4258
|
+
return (0, import_ts_pattern12.match)(operation).with("delete", () => this.runDelete(this.inputValidator.validateDeleteArgs(this.model, normalizedArgs))).with("deleteMany", () => this.runDeleteMany(this.inputValidator.validateDeleteManyArgs(this.model, normalizedArgs))).exhaustive();
|
|
3768
4259
|
}
|
|
3769
4260
|
async runDelete(args) {
|
|
3770
4261
|
const existing = await this.readUnique(this.kysely, this.model, {
|
|
@@ -3776,15 +4267,19 @@ var DeleteOperationHandler = class extends BaseOperationHandler {
|
|
|
3776
4267
|
if (!existing) {
|
|
3777
4268
|
throw new NotFoundError(this.model);
|
|
3778
4269
|
}
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
3782
|
-
|
|
4270
|
+
await this.safeTransaction(async (tx) => {
|
|
4271
|
+
const result = await this.delete(tx, this.model, args.where);
|
|
4272
|
+
if (result.count === 0) {
|
|
4273
|
+
throw new NotFoundError(this.model);
|
|
4274
|
+
}
|
|
4275
|
+
});
|
|
3783
4276
|
return existing;
|
|
3784
4277
|
}
|
|
3785
4278
|
async runDeleteMany(args) {
|
|
3786
|
-
|
|
3787
|
-
|
|
4279
|
+
return await this.safeTransaction(async (tx) => {
|
|
4280
|
+
const result = await this.delete(tx, this.model, args?.where, args?.limit);
|
|
4281
|
+
return result;
|
|
4282
|
+
});
|
|
3788
4283
|
}
|
|
3789
4284
|
};
|
|
3790
4285
|
|
|
@@ -3794,7 +4289,8 @@ var FindOperationHandler = class extends BaseOperationHandler {
|
|
|
3794
4289
|
__name(this, "FindOperationHandler");
|
|
3795
4290
|
}
|
|
3796
4291
|
async handle(operation, args, validateArgs = true) {
|
|
3797
|
-
const
|
|
4292
|
+
const normalizedArgs = this.normalizeArgs(args);
|
|
4293
|
+
const parsedArgs = validateArgs ? this.inputValidator.validateFindArgs(this.model, operation === "findUnique", normalizedArgs) : normalizedArgs;
|
|
3798
4294
|
const result = await this.read(this.client.$qb, this.model, parsedArgs);
|
|
3799
4295
|
const finalResult = operation === "findMany" ? result : result[0] ?? null;
|
|
3800
4296
|
return finalResult;
|
|
@@ -3803,17 +4299,18 @@ var FindOperationHandler = class extends BaseOperationHandler {
|
|
|
3803
4299
|
|
|
3804
4300
|
// src/client/crud/operations/group-by.ts
|
|
3805
4301
|
var import_kysely11 = require("kysely");
|
|
3806
|
-
var
|
|
3807
|
-
var
|
|
4302
|
+
var import_ts_pattern13 = require("ts-pattern");
|
|
4303
|
+
var GroupByOperationHandler = class extends BaseOperationHandler {
|
|
3808
4304
|
static {
|
|
3809
|
-
__name(this, "
|
|
4305
|
+
__name(this, "GroupByOperationHandler");
|
|
3810
4306
|
}
|
|
3811
4307
|
async handle(_operation, args) {
|
|
3812
|
-
const
|
|
4308
|
+
const normalizedArgs = this.normalizeArgs(args);
|
|
4309
|
+
const parsedArgs = this.inputValidator.validateGroupByArgs(this.model, normalizedArgs);
|
|
3813
4310
|
let query = this.kysely.selectFrom((eb) => {
|
|
3814
|
-
let subQuery = eb.selectFrom(this.model).selectAll().where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model,
|
|
3815
|
-
const skip =
|
|
3816
|
-
let take =
|
|
4311
|
+
let subQuery = eb.selectFrom(this.model).selectAll().where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
|
|
4312
|
+
const skip = parsedArgs?.skip;
|
|
4313
|
+
let take = parsedArgs?.take;
|
|
3817
4314
|
let negateOrderBy = false;
|
|
3818
4315
|
if (take !== void 0 && take < 0) {
|
|
3819
4316
|
negateOrderBy = true;
|
|
@@ -3823,20 +4320,20 @@ var GroupByeOperationHandler = class extends BaseOperationHandler {
|
|
|
3823
4320
|
subQuery = this.dialect.buildOrderBy(subQuery, this.model, this.model, void 0, skip !== void 0 || take !== void 0, negateOrderBy);
|
|
3824
4321
|
return subQuery.as("$sub");
|
|
3825
4322
|
});
|
|
3826
|
-
const bys = typeof
|
|
3827
|
-
|
|
3828
|
-
] :
|
|
3829
|
-
query = query.groupBy(bys);
|
|
3830
|
-
if (
|
|
3831
|
-
query = this.dialect.buildOrderBy(query, this.model, "$sub",
|
|
4323
|
+
const bys = typeof parsedArgs.by === "string" ? [
|
|
4324
|
+
parsedArgs.by
|
|
4325
|
+
] : parsedArgs.by;
|
|
4326
|
+
query = query.groupBy(bys.map((by) => import_kysely11.sql.ref(`$sub.${by}`)));
|
|
4327
|
+
if (parsedArgs.orderBy) {
|
|
4328
|
+
query = this.dialect.buildOrderBy(query, this.model, "$sub", parsedArgs.orderBy, false, false);
|
|
3832
4329
|
}
|
|
3833
|
-
if (
|
|
3834
|
-
query = query.having((
|
|
4330
|
+
if (parsedArgs.having) {
|
|
4331
|
+
query = query.having((eb) => this.dialect.buildFilter(eb, this.model, "$sub", parsedArgs.having));
|
|
3835
4332
|
}
|
|
3836
4333
|
for (const by of bys) {
|
|
3837
4334
|
query = query.select(() => import_kysely11.sql.ref(`$sub.${by}`).as(by));
|
|
3838
4335
|
}
|
|
3839
|
-
for (const [key, value] of Object.entries(
|
|
4336
|
+
for (const [key, value] of Object.entries(parsedArgs)) {
|
|
3840
4337
|
switch (key) {
|
|
3841
4338
|
case "_count": {
|
|
3842
4339
|
if (value === true) {
|
|
@@ -3861,7 +4358,7 @@ var GroupByeOperationHandler = class extends BaseOperationHandler {
|
|
|
3861
4358
|
Object.entries(value).forEach(([field, val]) => {
|
|
3862
4359
|
if (val === true) {
|
|
3863
4360
|
query = query.select((eb) => {
|
|
3864
|
-
const fn = (0,
|
|
4361
|
+
const fn = (0, import_ts_pattern13.match)(key).with("_sum", () => eb.fn.sum).with("_avg", () => eb.fn.avg).with("_max", () => eb.fn.max).with("_min", () => eb.fn.min).exhaustive();
|
|
3865
4362
|
return fn(import_kysely11.sql.ref(`$sub.${field}`)).as(`${key}.${field}`);
|
|
3866
4363
|
});
|
|
3867
4364
|
}
|
|
@@ -3870,8 +4367,8 @@ var GroupByeOperationHandler = class extends BaseOperationHandler {
|
|
|
3870
4367
|
}
|
|
3871
4368
|
}
|
|
3872
4369
|
}
|
|
3873
|
-
const result = await
|
|
3874
|
-
return result.map((row) => this.postProcessRow(row));
|
|
4370
|
+
const result = await this.executeQuery(this.kysely, query, "groupBy");
|
|
4371
|
+
return result.rows.map((row) => this.postProcessRow(row));
|
|
3875
4372
|
}
|
|
3876
4373
|
postProcessRow(row) {
|
|
3877
4374
|
const ret = {};
|
|
@@ -3898,7 +4395,7 @@ var GroupByeOperationHandler = class extends BaseOperationHandler {
|
|
|
3898
4395
|
val = parseFloat(val);
|
|
3899
4396
|
} else {
|
|
3900
4397
|
if (op === "_sum" || op === "_min" || op === "_max") {
|
|
3901
|
-
val = (0,
|
|
4398
|
+
val = (0, import_ts_pattern13.match)(type).with("Int", () => parseInt(value, 10)).with("BigInt", () => BigInt(value)).with("Float", () => parseFloat(value)).with("Decimal", () => parseFloat(value)).otherwise(() => value);
|
|
3902
4399
|
}
|
|
3903
4400
|
}
|
|
3904
4401
|
}
|
|
@@ -3913,31 +4410,45 @@ var GroupByeOperationHandler = class extends BaseOperationHandler {
|
|
|
3913
4410
|
};
|
|
3914
4411
|
|
|
3915
4412
|
// src/client/crud/operations/update.ts
|
|
3916
|
-
var
|
|
4413
|
+
var import_ts_pattern14 = require("ts-pattern");
|
|
3917
4414
|
var UpdateOperationHandler = class extends BaseOperationHandler {
|
|
3918
4415
|
static {
|
|
3919
4416
|
__name(this, "UpdateOperationHandler");
|
|
3920
4417
|
}
|
|
3921
4418
|
async handle(operation, args) {
|
|
3922
|
-
|
|
4419
|
+
const normalizedArgs = this.normalizeArgs(args);
|
|
4420
|
+
return (0, import_ts_pattern14.match)(operation).with("update", () => this.runUpdate(this.inputValidator.validateUpdateArgs(this.model, normalizedArgs))).with("updateMany", () => this.runUpdateMany(this.inputValidator.validateUpdateManyArgs(this.model, normalizedArgs))).with("updateManyAndReturn", () => this.runUpdateManyAndReturn(this.inputValidator.validateUpdateManyAndReturnArgs(this.model, normalizedArgs))).with("upsert", () => this.runUpsert(this.inputValidator.validateUpsertArgs(this.model, normalizedArgs))).exhaustive();
|
|
3923
4421
|
}
|
|
3924
4422
|
async runUpdate(args) {
|
|
3925
|
-
const
|
|
3926
|
-
const
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
4423
|
+
const readBackResult = await this.safeTransaction(async (tx) => {
|
|
4424
|
+
const updateResult = await this.update(tx, this.model, args.where, args.data);
|
|
4425
|
+
const readFilter = updateResult ?? args.where;
|
|
4426
|
+
let readBackResult2 = void 0;
|
|
4427
|
+
try {
|
|
4428
|
+
readBackResult2 = await this.readUnique(tx, this.model, {
|
|
4429
|
+
select: args.select,
|
|
4430
|
+
include: args.include,
|
|
4431
|
+
omit: args.omit,
|
|
4432
|
+
where: readFilter
|
|
4433
|
+
});
|
|
4434
|
+
} catch {
|
|
4435
|
+
}
|
|
4436
|
+
return readBackResult2;
|
|
3933
4437
|
});
|
|
3934
|
-
if (!
|
|
3935
|
-
|
|
4438
|
+
if (!readBackResult) {
|
|
4439
|
+
if (this.hasPolicyEnabled) {
|
|
4440
|
+
throw new RejectedByPolicyError(this.model, "result is not allowed to be read back");
|
|
4441
|
+
} else {
|
|
4442
|
+
return null;
|
|
4443
|
+
}
|
|
4444
|
+
} else {
|
|
4445
|
+
return readBackResult;
|
|
3936
4446
|
}
|
|
3937
|
-
return result;
|
|
3938
4447
|
}
|
|
3939
4448
|
async runUpdateMany(args) {
|
|
3940
|
-
return this.
|
|
4449
|
+
return this.safeTransaction(async (tx) => {
|
|
4450
|
+
return this.updateMany(tx, this.model, args.where, args.data, args.limit, false);
|
|
4451
|
+
});
|
|
3941
4452
|
}
|
|
3942
4453
|
async runUpdateManyAndReturn(args) {
|
|
3943
4454
|
if (!args) {
|
|
@@ -3975,19 +4486,19 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
|
|
|
3975
4486
|
};
|
|
3976
4487
|
|
|
3977
4488
|
// src/client/crud/validator.ts
|
|
4489
|
+
var import_common_helpers9 = require("@zenstackhq/common-helpers");
|
|
3978
4490
|
var import_decimal = __toESM(require("decimal.js"), 1);
|
|
3979
4491
|
var import_json_stable_stringify = __toESM(require("json-stable-stringify"), 1);
|
|
3980
|
-
var
|
|
4492
|
+
var import_ts_pattern15 = require("ts-pattern");
|
|
3981
4493
|
var import_zod = require("zod");
|
|
3982
4494
|
var InputValidator = class {
|
|
3983
4495
|
static {
|
|
3984
4496
|
__name(this, "InputValidator");
|
|
3985
4497
|
}
|
|
3986
4498
|
schema;
|
|
3987
|
-
schemaCache;
|
|
4499
|
+
schemaCache = /* @__PURE__ */ new Map();
|
|
3988
4500
|
constructor(schema) {
|
|
3989
4501
|
this.schema = schema;
|
|
3990
|
-
this.schemaCache = /* @__PURE__ */ new Map();
|
|
3991
4502
|
}
|
|
3992
4503
|
validateFindArgs(model, unique, args) {
|
|
3993
4504
|
return this.validate(model, "find", {
|
|
@@ -4044,7 +4555,7 @@ var InputValidator = class {
|
|
|
4044
4555
|
}
|
|
4045
4556
|
const { error } = schema.safeParse(args);
|
|
4046
4557
|
if (error) {
|
|
4047
|
-
throw new
|
|
4558
|
+
throw new InputValidationError(`Invalid ${operation} args: ${error.message}`, error);
|
|
4048
4559
|
}
|
|
4049
4560
|
return args;
|
|
4050
4561
|
}
|
|
@@ -4063,11 +4574,11 @@ var InputValidator = class {
|
|
|
4063
4574
|
fields["distinct"] = this.makeDistinctSchema(model).optional();
|
|
4064
4575
|
fields["cursor"] = this.makeCursorSchema(model).optional();
|
|
4065
4576
|
if (options.collection) {
|
|
4066
|
-
fields["skip"] =
|
|
4067
|
-
fields["take"] =
|
|
4577
|
+
fields["skip"] = this.makeSkipSchema().optional();
|
|
4578
|
+
fields["take"] = this.makeTakeSchema().optional();
|
|
4068
4579
|
fields["orderBy"] = this.orArray(this.makeOrderBySchema(model, true, false), true).optional();
|
|
4069
4580
|
}
|
|
4070
|
-
let result = import_zod.z.
|
|
4581
|
+
let result = import_zod.z.strictObject(fields);
|
|
4071
4582
|
result = this.refineForSelectIncludeMutuallyExclusive(result);
|
|
4072
4583
|
result = this.refineForSelectOmitMutuallyExclusive(result);
|
|
4073
4584
|
if (!options.unique) {
|
|
@@ -4076,22 +4587,50 @@ var InputValidator = class {
|
|
|
4076
4587
|
return result;
|
|
4077
4588
|
}
|
|
4078
4589
|
makePrimitiveSchema(type) {
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
import_zod.z.
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4590
|
+
if (this.schema.typeDefs && type in this.schema.typeDefs) {
|
|
4591
|
+
return this.makeTypeDefSchema(type);
|
|
4592
|
+
} else {
|
|
4593
|
+
return (0, import_ts_pattern15.match)(type).with("String", () => import_zod.z.string()).with("Int", () => import_zod.z.int()).with("Float", () => import_zod.z.number()).with("Boolean", () => import_zod.z.boolean()).with("BigInt", () => import_zod.z.union([
|
|
4594
|
+
import_zod.z.int(),
|
|
4595
|
+
import_zod.z.bigint()
|
|
4596
|
+
])).with("Decimal", () => import_zod.z.union([
|
|
4597
|
+
import_zod.z.number(),
|
|
4598
|
+
import_zod.z.instanceof(import_decimal.default),
|
|
4599
|
+
import_zod.z.string()
|
|
4600
|
+
])).with("DateTime", () => import_zod.z.union([
|
|
4601
|
+
import_zod.z.date(),
|
|
4602
|
+
import_zod.z.string().datetime()
|
|
4603
|
+
])).with("Bytes", () => import_zod.z.instanceof(Uint8Array)).otherwise(() => import_zod.z.unknown());
|
|
4604
|
+
}
|
|
4605
|
+
}
|
|
4606
|
+
makeTypeDefSchema(type) {
|
|
4607
|
+
const key = `$typedef-${type}`;
|
|
4608
|
+
let schema = this.schemaCache.get(key);
|
|
4609
|
+
if (schema) {
|
|
4610
|
+
return schema;
|
|
4611
|
+
}
|
|
4612
|
+
const typeDef = this.schema.typeDefs?.[type];
|
|
4613
|
+
(0, import_common_helpers9.invariant)(typeDef, `Type definition "${type}" not found in schema`);
|
|
4614
|
+
schema = import_zod.z.looseObject(Object.fromEntries(Object.entries(typeDef.fields).map(([field, def]) => {
|
|
4615
|
+
let fieldSchema = this.makePrimitiveSchema(def.type);
|
|
4616
|
+
if (def.array) {
|
|
4617
|
+
fieldSchema = fieldSchema.array();
|
|
4618
|
+
}
|
|
4619
|
+
if (def.optional) {
|
|
4620
|
+
fieldSchema = fieldSchema.optional();
|
|
4621
|
+
}
|
|
4622
|
+
return [
|
|
4623
|
+
field,
|
|
4624
|
+
fieldSchema
|
|
4625
|
+
];
|
|
4626
|
+
})));
|
|
4627
|
+
this.schemaCache.set(key, schema);
|
|
4628
|
+
return schema;
|
|
4629
|
+
}
|
|
4630
|
+
makeWhereSchema(model, unique, withoutRelationFields = false, withAggregations = false) {
|
|
4092
4631
|
const modelDef = getModel(this.schema, model);
|
|
4093
4632
|
if (!modelDef) {
|
|
4094
|
-
throw new QueryError(`Model "${model}" not found`);
|
|
4633
|
+
throw new QueryError(`Model "${model}" not found in schema`);
|
|
4095
4634
|
}
|
|
4096
4635
|
const fields = {};
|
|
4097
4636
|
for (const field of Object.keys(modelDef.fields)) {
|
|
@@ -4106,7 +4645,7 @@ var InputValidator = class {
|
|
|
4106
4645
|
if (fieldDef.array) {
|
|
4107
4646
|
fieldSchema = import_zod.z.union([
|
|
4108
4647
|
fieldSchema,
|
|
4109
|
-
import_zod.z.
|
|
4648
|
+
import_zod.z.strictObject({
|
|
4110
4649
|
some: fieldSchema.optional(),
|
|
4111
4650
|
every: fieldSchema.optional(),
|
|
4112
4651
|
none: fieldSchema.optional()
|
|
@@ -4115,7 +4654,7 @@ var InputValidator = class {
|
|
|
4115
4654
|
} else {
|
|
4116
4655
|
fieldSchema = import_zod.z.union([
|
|
4117
4656
|
fieldSchema,
|
|
4118
|
-
import_zod.z.
|
|
4657
|
+
import_zod.z.strictObject({
|
|
4119
4658
|
is: fieldSchema.optional(),
|
|
4120
4659
|
isNot: fieldSchema.optional()
|
|
4121
4660
|
})
|
|
@@ -4125,12 +4664,12 @@ var InputValidator = class {
|
|
|
4125
4664
|
const enumDef = getEnum(this.schema, fieldDef.type);
|
|
4126
4665
|
if (enumDef) {
|
|
4127
4666
|
if (Object.keys(enumDef).length > 0) {
|
|
4128
|
-
fieldSchema = this.makeEnumFilterSchema(enumDef, !!fieldDef.optional);
|
|
4667
|
+
fieldSchema = this.makeEnumFilterSchema(enumDef, !!fieldDef.optional, withAggregations);
|
|
4129
4668
|
}
|
|
4130
4669
|
} else if (fieldDef.array) {
|
|
4131
4670
|
fieldSchema = this.makeArrayFilterSchema(fieldDef.type);
|
|
4132
4671
|
} else {
|
|
4133
|
-
fieldSchema = this.makePrimitiveFilterSchema(fieldDef.type, !!fieldDef.optional);
|
|
4672
|
+
fieldSchema = this.makePrimitiveFilterSchema(fieldDef.type, !!fieldDef.optional, withAggregations);
|
|
4134
4673
|
}
|
|
4135
4674
|
}
|
|
4136
4675
|
if (fieldSchema) {
|
|
@@ -4141,18 +4680,32 @@ var InputValidator = class {
|
|
|
4141
4680
|
const uniqueFields = getUniqueFields(this.schema, model);
|
|
4142
4681
|
for (const uniqueField of uniqueFields) {
|
|
4143
4682
|
if ("defs" in uniqueField) {
|
|
4144
|
-
fields[uniqueField.name] = import_zod.z.object(Object.fromEntries(Object.entries(uniqueField.defs).map(([key, def]) =>
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
|
|
4683
|
+
fields[uniqueField.name] = import_zod.z.object(Object.fromEntries(Object.entries(uniqueField.defs).map(([key, def]) => {
|
|
4684
|
+
(0, import_common_helpers9.invariant)(!def.relation, "unique field cannot be a relation");
|
|
4685
|
+
let fieldSchema;
|
|
4686
|
+
const enumDef = getEnum(this.schema, def.type);
|
|
4687
|
+
if (enumDef) {
|
|
4688
|
+
if (Object.keys(enumDef).length > 0) {
|
|
4689
|
+
fieldSchema = this.makeEnumFilterSchema(enumDef, !!def.optional, false);
|
|
4690
|
+
} else {
|
|
4691
|
+
fieldSchema = import_zod.z.never();
|
|
4692
|
+
}
|
|
4693
|
+
} else {
|
|
4694
|
+
fieldSchema = this.makePrimitiveFilterSchema(def.type, !!def.optional, false);
|
|
4695
|
+
}
|
|
4696
|
+
return [
|
|
4697
|
+
key,
|
|
4698
|
+
fieldSchema
|
|
4699
|
+
];
|
|
4700
|
+
}))).optional();
|
|
4148
4701
|
}
|
|
4149
4702
|
}
|
|
4150
4703
|
}
|
|
4151
|
-
fields["$expr"] = import_zod.z.
|
|
4704
|
+
fields["$expr"] = import_zod.z.custom((v) => typeof v === "function").optional();
|
|
4152
4705
|
fields["AND"] = this.orArray(import_zod.z.lazy(() => this.makeWhereSchema(model, false, withoutRelationFields)), true).optional();
|
|
4153
4706
|
fields["OR"] = import_zod.z.lazy(() => this.makeWhereSchema(model, false, withoutRelationFields)).array().optional();
|
|
4154
4707
|
fields["NOT"] = this.orArray(import_zod.z.lazy(() => this.makeWhereSchema(model, false, withoutRelationFields)), true).optional();
|
|
4155
|
-
const baseWhere = import_zod.z.
|
|
4708
|
+
const baseWhere = import_zod.z.strictObject(fields);
|
|
4156
4709
|
let result = baseWhere;
|
|
4157
4710
|
if (unique) {
|
|
4158
4711
|
const uniqueFields = getUniqueFields(this.schema, model);
|
|
@@ -4171,21 +4724,25 @@ var InputValidator = class {
|
|
|
4171
4724
|
}
|
|
4172
4725
|
return result;
|
|
4173
4726
|
}
|
|
4174
|
-
makeEnumFilterSchema(enumDef, optional) {
|
|
4727
|
+
makeEnumFilterSchema(enumDef, optional, withAggregations) {
|
|
4175
4728
|
const baseSchema = import_zod.z.enum(Object.keys(enumDef));
|
|
4176
|
-
const components = this.makeCommonPrimitiveFilterComponents(baseSchema, optional, () => import_zod.z.lazy(() => this.makeEnumFilterSchema(enumDef, optional))
|
|
4729
|
+
const components = this.makeCommonPrimitiveFilterComponents(baseSchema, optional, () => import_zod.z.lazy(() => this.makeEnumFilterSchema(enumDef, optional, withAggregations)), [
|
|
4730
|
+
"equals",
|
|
4731
|
+
"in",
|
|
4732
|
+
"notIn",
|
|
4733
|
+
"not"
|
|
4734
|
+
], withAggregations ? [
|
|
4735
|
+
"_count",
|
|
4736
|
+
"_min",
|
|
4737
|
+
"_max"
|
|
4738
|
+
] : void 0);
|
|
4177
4739
|
return import_zod.z.union([
|
|
4178
4740
|
this.nullableIf(baseSchema, optional),
|
|
4179
|
-
import_zod.z.
|
|
4180
|
-
equals: components.equals,
|
|
4181
|
-
in: components.in,
|
|
4182
|
-
notIn: components.notIn,
|
|
4183
|
-
not: components.not
|
|
4184
|
-
})
|
|
4741
|
+
import_zod.z.strictObject(components)
|
|
4185
4742
|
]);
|
|
4186
4743
|
}
|
|
4187
4744
|
makeArrayFilterSchema(type) {
|
|
4188
|
-
return import_zod.z.
|
|
4745
|
+
return import_zod.z.strictObject({
|
|
4189
4746
|
equals: this.makePrimitiveSchema(type).array().optional(),
|
|
4190
4747
|
has: this.makePrimitiveSchema(type).optional(),
|
|
4191
4748
|
hasEvery: this.makePrimitiveSchema(type).array().optional(),
|
|
@@ -4193,39 +4750,59 @@ var InputValidator = class {
|
|
|
4193
4750
|
isEmpty: import_zod.z.boolean().optional()
|
|
4194
4751
|
});
|
|
4195
4752
|
}
|
|
4196
|
-
makePrimitiveFilterSchema(type, optional) {
|
|
4197
|
-
|
|
4753
|
+
makePrimitiveFilterSchema(type, optional, withAggregations) {
|
|
4754
|
+
if (this.schema.typeDefs && type in this.schema.typeDefs) {
|
|
4755
|
+
return this.makeTypeDefFilterSchema(type, optional);
|
|
4756
|
+
}
|
|
4757
|
+
return (0, import_ts_pattern15.match)(type).with("String", () => this.makeStringFilterSchema(optional, withAggregations)).with(import_ts_pattern15.P.union("Int", "Float", "Decimal", "BigInt"), (type2) => this.makeNumberFilterSchema(this.makePrimitiveSchema(type2), optional, withAggregations)).with("Boolean", () => this.makeBooleanFilterSchema(optional, withAggregations)).with("DateTime", () => this.makeDateTimeFilterSchema(optional, withAggregations)).with("Bytes", () => this.makeBytesFilterSchema(optional, withAggregations)).with("Json", () => import_zod.z.any()).with("Unsupported", () => import_zod.z.never()).exhaustive();
|
|
4758
|
+
}
|
|
4759
|
+
makeTypeDefFilterSchema(_type, _optional) {
|
|
4760
|
+
return import_zod.z.never();
|
|
4198
4761
|
}
|
|
4199
|
-
makeDateTimeFilterSchema(optional) {
|
|
4762
|
+
makeDateTimeFilterSchema(optional, withAggregations) {
|
|
4200
4763
|
return this.makeCommonPrimitiveFilterSchema(import_zod.z.union([
|
|
4201
|
-
import_zod.z.
|
|
4764
|
+
import_zod.z.iso.datetime(),
|
|
4202
4765
|
import_zod.z.date()
|
|
4203
|
-
]), optional, () => import_zod.z.lazy(() => this.makeDateTimeFilterSchema(optional))
|
|
4204
|
-
|
|
4205
|
-
|
|
4766
|
+
]), optional, () => import_zod.z.lazy(() => this.makeDateTimeFilterSchema(optional, withAggregations)), withAggregations ? [
|
|
4767
|
+
"_count",
|
|
4768
|
+
"_min",
|
|
4769
|
+
"_max"
|
|
4770
|
+
] : void 0);
|
|
4771
|
+
}
|
|
4772
|
+
makeBooleanFilterSchema(optional, withAggregations) {
|
|
4773
|
+
const components = this.makeCommonPrimitiveFilterComponents(import_zod.z.boolean(), optional, () => import_zod.z.lazy(() => this.makeBooleanFilterSchema(optional, withAggregations)), [
|
|
4774
|
+
"equals",
|
|
4775
|
+
"not"
|
|
4776
|
+
], withAggregations ? [
|
|
4777
|
+
"_count",
|
|
4778
|
+
"_min",
|
|
4779
|
+
"_max"
|
|
4780
|
+
] : void 0);
|
|
4206
4781
|
return import_zod.z.union([
|
|
4207
4782
|
this.nullableIf(import_zod.z.boolean(), optional),
|
|
4208
|
-
import_zod.z.
|
|
4209
|
-
equals: this.nullableIf(import_zod.z.boolean(), optional).optional(),
|
|
4210
|
-
not: import_zod.z.lazy(() => this.makeBooleanFilterSchema(optional)).optional()
|
|
4211
|
-
})
|
|
4783
|
+
import_zod.z.strictObject(components)
|
|
4212
4784
|
]);
|
|
4213
4785
|
}
|
|
4214
|
-
makeBytesFilterSchema(optional) {
|
|
4786
|
+
makeBytesFilterSchema(optional, withAggregations) {
|
|
4215
4787
|
const baseSchema = import_zod.z.instanceof(Uint8Array);
|
|
4216
|
-
const components = this.makeCommonPrimitiveFilterComponents(baseSchema, optional, () => import_zod.z.instanceof(Uint8Array)
|
|
4788
|
+
const components = this.makeCommonPrimitiveFilterComponents(baseSchema, optional, () => import_zod.z.instanceof(Uint8Array), [
|
|
4789
|
+
"equals",
|
|
4790
|
+
"in",
|
|
4791
|
+
"notIn",
|
|
4792
|
+
"not"
|
|
4793
|
+
], withAggregations ? [
|
|
4794
|
+
"_count",
|
|
4795
|
+
"_min",
|
|
4796
|
+
"_max"
|
|
4797
|
+
] : void 0);
|
|
4217
4798
|
return import_zod.z.union([
|
|
4218
4799
|
this.nullableIf(baseSchema, optional),
|
|
4219
|
-
import_zod.z.
|
|
4220
|
-
equals: components.equals,
|
|
4221
|
-
in: components.in,
|
|
4222
|
-
notIn: components.notIn,
|
|
4223
|
-
not: components.not
|
|
4224
|
-
})
|
|
4800
|
+
import_zod.z.strictObject(components)
|
|
4225
4801
|
]);
|
|
4226
4802
|
}
|
|
4227
|
-
makeCommonPrimitiveFilterComponents(baseSchema, optional, makeThis) {
|
|
4228
|
-
|
|
4803
|
+
makeCommonPrimitiveFilterComponents(baseSchema, optional, makeThis, supportedOperators = void 0, withAggregations = void 0) {
|
|
4804
|
+
const commonAggSchema = /* @__PURE__ */ __name(() => this.makeCommonPrimitiveFilterSchema(baseSchema, false, makeThis, void 0).optional(), "commonAggSchema");
|
|
4805
|
+
let result = {
|
|
4229
4806
|
equals: this.nullableIf(baseSchema.optional(), optional),
|
|
4230
4807
|
notEquals: this.nullableIf(baseSchema.optional(), optional),
|
|
4231
4808
|
in: baseSchema.array().optional(),
|
|
@@ -4234,20 +4811,70 @@ var InputValidator = class {
|
|
|
4234
4811
|
lte: baseSchema.optional(),
|
|
4235
4812
|
gt: baseSchema.optional(),
|
|
4236
4813
|
gte: baseSchema.optional(),
|
|
4237
|
-
not: makeThis().optional()
|
|
4814
|
+
not: makeThis().optional(),
|
|
4815
|
+
...withAggregations?.includes("_count") ? {
|
|
4816
|
+
_count: this.makeNumberFilterSchema(import_zod.z.int(), false, false).optional()
|
|
4817
|
+
} : {},
|
|
4818
|
+
...withAggregations?.includes("_avg") ? {
|
|
4819
|
+
_avg: commonAggSchema()
|
|
4820
|
+
} : {},
|
|
4821
|
+
...withAggregations?.includes("_sum") ? {
|
|
4822
|
+
_sum: commonAggSchema()
|
|
4823
|
+
} : {},
|
|
4824
|
+
...withAggregations?.includes("_min") ? {
|
|
4825
|
+
_min: commonAggSchema()
|
|
4826
|
+
} : {},
|
|
4827
|
+
...withAggregations?.includes("_max") ? {
|
|
4828
|
+
_max: commonAggSchema()
|
|
4829
|
+
} : {}
|
|
4238
4830
|
};
|
|
4831
|
+
if (supportedOperators) {
|
|
4832
|
+
const keys = [
|
|
4833
|
+
...supportedOperators,
|
|
4834
|
+
...withAggregations ?? []
|
|
4835
|
+
];
|
|
4836
|
+
result = extractFields(result, keys);
|
|
4837
|
+
}
|
|
4838
|
+
return result;
|
|
4239
4839
|
}
|
|
4240
|
-
makeCommonPrimitiveFilterSchema(baseSchema, optional, makeThis) {
|
|
4840
|
+
makeCommonPrimitiveFilterSchema(baseSchema, optional, makeThis, withAggregations = void 0) {
|
|
4241
4841
|
return import_zod.z.union([
|
|
4242
4842
|
this.nullableIf(baseSchema, optional),
|
|
4243
|
-
import_zod.z.
|
|
4843
|
+
import_zod.z.strictObject(this.makeCommonPrimitiveFilterComponents(baseSchema, optional, makeThis, void 0, withAggregations))
|
|
4244
4844
|
]);
|
|
4245
4845
|
}
|
|
4246
|
-
makeNumberFilterSchema(baseSchema, optional) {
|
|
4247
|
-
return this.makeCommonPrimitiveFilterSchema(baseSchema, optional, () => import_zod.z.lazy(() => this.makeNumberFilterSchema(baseSchema, optional))
|
|
4846
|
+
makeNumberFilterSchema(baseSchema, optional, withAggregations) {
|
|
4847
|
+
return this.makeCommonPrimitiveFilterSchema(baseSchema, optional, () => import_zod.z.lazy(() => this.makeNumberFilterSchema(baseSchema, optional, withAggregations)), withAggregations ? [
|
|
4848
|
+
"_count",
|
|
4849
|
+
"_avg",
|
|
4850
|
+
"_sum",
|
|
4851
|
+
"_min",
|
|
4852
|
+
"_max"
|
|
4853
|
+
] : void 0);
|
|
4854
|
+
}
|
|
4855
|
+
makeStringFilterSchema(optional, withAggregations) {
|
|
4856
|
+
return import_zod.z.union([
|
|
4857
|
+
this.nullableIf(import_zod.z.string(), optional),
|
|
4858
|
+
import_zod.z.strictObject({
|
|
4859
|
+
...this.makeCommonPrimitiveFilterComponents(import_zod.z.string(), optional, () => import_zod.z.lazy(() => this.makeStringFilterSchema(optional, withAggregations)), void 0, withAggregations ? [
|
|
4860
|
+
"_count",
|
|
4861
|
+
"_min",
|
|
4862
|
+
"_max"
|
|
4863
|
+
] : void 0),
|
|
4864
|
+
startsWith: import_zod.z.string().optional(),
|
|
4865
|
+
endsWith: import_zod.z.string().optional(),
|
|
4866
|
+
contains: import_zod.z.string().optional(),
|
|
4867
|
+
...this.providerSupportsCaseSensitivity ? {
|
|
4868
|
+
mode: this.makeStringModeSchema().optional()
|
|
4869
|
+
} : {}
|
|
4870
|
+
})
|
|
4871
|
+
]);
|
|
4248
4872
|
}
|
|
4249
|
-
|
|
4250
|
-
return
|
|
4873
|
+
makeStringModeSchema() {
|
|
4874
|
+
return import_zod.z.union([
|
|
4875
|
+
import_zod.z.literal("default"),
|
|
4876
|
+
import_zod.z.literal("insensitive")
|
|
4877
|
+
]);
|
|
4251
4878
|
}
|
|
4252
4879
|
makeSelectSchema(model) {
|
|
4253
4880
|
const modelDef = requireModel(this.schema, model);
|
|
@@ -4257,7 +4884,7 @@ var InputValidator = class {
|
|
|
4257
4884
|
if (fieldDef.relation) {
|
|
4258
4885
|
fields[field] = import_zod.z.union([
|
|
4259
4886
|
import_zod.z.literal(true),
|
|
4260
|
-
import_zod.z.
|
|
4887
|
+
import_zod.z.strictObject({
|
|
4261
4888
|
select: import_zod.z.lazy(() => this.makeSelectSchema(fieldDef.type)).optional(),
|
|
4262
4889
|
include: import_zod.z.lazy(() => this.makeIncludeSchema(fieldDef.type)).optional()
|
|
4263
4890
|
})
|
|
@@ -4266,22 +4893,24 @@ var InputValidator = class {
|
|
|
4266
4893
|
fields[field] = import_zod.z.boolean().optional();
|
|
4267
4894
|
}
|
|
4268
4895
|
}
|
|
4269
|
-
const toManyRelations = Object.
|
|
4896
|
+
const toManyRelations = Object.values(modelDef.fields).filter((def) => def.relation && def.array);
|
|
4270
4897
|
if (toManyRelations.length > 0) {
|
|
4271
4898
|
fields["_count"] = import_zod.z.union([
|
|
4272
4899
|
import_zod.z.literal(true),
|
|
4273
|
-
import_zod.z.
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
import_zod.z.
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4900
|
+
import_zod.z.strictObject({
|
|
4901
|
+
select: import_zod.z.strictObject(toManyRelations.reduce((acc, fieldDef) => ({
|
|
4902
|
+
...acc,
|
|
4903
|
+
[fieldDef.name]: import_zod.z.union([
|
|
4904
|
+
import_zod.z.boolean(),
|
|
4905
|
+
import_zod.z.strictObject({
|
|
4906
|
+
where: this.makeWhereSchema(fieldDef.type, false, false)
|
|
4907
|
+
})
|
|
4908
|
+
]).optional()
|
|
4909
|
+
}), {}))
|
|
4910
|
+
})
|
|
4282
4911
|
]).optional();
|
|
4283
4912
|
}
|
|
4284
|
-
return import_zod.z.
|
|
4913
|
+
return import_zod.z.strictObject(fields);
|
|
4285
4914
|
}
|
|
4286
4915
|
makeOmitSchema(model) {
|
|
4287
4916
|
const modelDef = requireModel(this.schema, model);
|
|
@@ -4292,7 +4921,7 @@ var InputValidator = class {
|
|
|
4292
4921
|
fields[field] = import_zod.z.boolean().optional();
|
|
4293
4922
|
}
|
|
4294
4923
|
}
|
|
4295
|
-
return import_zod.z.
|
|
4924
|
+
return import_zod.z.strictObject(fields);
|
|
4296
4925
|
}
|
|
4297
4926
|
makeIncludeSchema(model) {
|
|
4298
4927
|
const modelDef = requireModel(this.schema, model);
|
|
@@ -4302,15 +4931,20 @@ var InputValidator = class {
|
|
|
4302
4931
|
if (fieldDef.relation) {
|
|
4303
4932
|
fields[field] = import_zod.z.union([
|
|
4304
4933
|
import_zod.z.literal(true),
|
|
4305
|
-
import_zod.z.
|
|
4934
|
+
import_zod.z.strictObject({
|
|
4306
4935
|
select: import_zod.z.lazy(() => this.makeSelectSchema(fieldDef.type)).optional(),
|
|
4307
4936
|
include: import_zod.z.lazy(() => this.makeIncludeSchema(fieldDef.type)).optional(),
|
|
4308
|
-
|
|
4937
|
+
omit: import_zod.z.lazy(() => this.makeOmitSchema(fieldDef.type)).optional(),
|
|
4938
|
+
where: import_zod.z.lazy(() => this.makeWhereSchema(fieldDef.type, false)).optional(),
|
|
4939
|
+
orderBy: import_zod.z.lazy(() => this.makeOrderBySchema(fieldDef.type, true, false)).optional(),
|
|
4940
|
+
skip: this.makeSkipSchema().optional(),
|
|
4941
|
+
take: this.makeTakeSchema().optional(),
|
|
4942
|
+
distinct: this.makeDistinctSchema(fieldDef.type).optional()
|
|
4309
4943
|
})
|
|
4310
4944
|
]).optional();
|
|
4311
4945
|
}
|
|
4312
4946
|
}
|
|
4313
|
-
return import_zod.z.
|
|
4947
|
+
return import_zod.z.strictObject(fields);
|
|
4314
4948
|
}
|
|
4315
4949
|
makeOrderBySchema(model, withRelation, WithAggregation) {
|
|
4316
4950
|
const modelDef = requireModel(this.schema, model);
|
|
@@ -4323,13 +4957,21 @@ var InputValidator = class {
|
|
|
4323
4957
|
const fieldDef = requireField(this.schema, model, field);
|
|
4324
4958
|
if (fieldDef.relation) {
|
|
4325
4959
|
if (withRelation) {
|
|
4326
|
-
fields[field] = import_zod.z.lazy(() =>
|
|
4960
|
+
fields[field] = import_zod.z.lazy(() => {
|
|
4961
|
+
let relationOrderBy = this.makeOrderBySchema(fieldDef.type, withRelation, WithAggregation);
|
|
4962
|
+
if (fieldDef.array) {
|
|
4963
|
+
relationOrderBy = relationOrderBy.extend({
|
|
4964
|
+
_count: sort
|
|
4965
|
+
});
|
|
4966
|
+
}
|
|
4967
|
+
return relationOrderBy.optional();
|
|
4968
|
+
});
|
|
4327
4969
|
}
|
|
4328
4970
|
} else {
|
|
4329
4971
|
if (fieldDef.optional) {
|
|
4330
4972
|
fields[field] = import_zod.z.union([
|
|
4331
4973
|
sort,
|
|
4332
|
-
import_zod.z.
|
|
4974
|
+
import_zod.z.strictObject({
|
|
4333
4975
|
sort,
|
|
4334
4976
|
nulls: import_zod.z.union([
|
|
4335
4977
|
import_zod.z.literal("first"),
|
|
@@ -4354,7 +4996,7 @@ var InputValidator = class {
|
|
|
4354
4996
|
fields[agg] = import_zod.z.lazy(() => this.makeOrderBySchema(model, true, false).optional());
|
|
4355
4997
|
}
|
|
4356
4998
|
}
|
|
4357
|
-
return import_zod.z.
|
|
4999
|
+
return import_zod.z.strictObject(fields);
|
|
4358
5000
|
}
|
|
4359
5001
|
makeDistinctSchema(model) {
|
|
4360
5002
|
const modelDef = requireModel(this.schema, model);
|
|
@@ -4373,7 +5015,7 @@ var InputValidator = class {
|
|
|
4373
5015
|
select: this.makeSelectSchema(model).optional(),
|
|
4374
5016
|
include: this.makeIncludeSchema(model).optional(),
|
|
4375
5017
|
omit: this.makeOmitSchema(model).optional()
|
|
4376
|
-
})
|
|
5018
|
+
});
|
|
4377
5019
|
return this.refineForSelectIncludeMutuallyExclusive(schema);
|
|
4378
5020
|
}
|
|
4379
5021
|
makeCreateManySchema(model) {
|
|
@@ -4381,15 +5023,15 @@ var InputValidator = class {
|
|
|
4381
5023
|
}
|
|
4382
5024
|
makeCreateManyAndReturnSchema(model) {
|
|
4383
5025
|
const base = this.makeCreateManyDataSchema(model, []);
|
|
4384
|
-
const result = base.merge(import_zod.z.
|
|
5026
|
+
const result = base.merge(import_zod.z.strictObject({
|
|
4385
5027
|
select: this.makeSelectSchema(model).optional(),
|
|
4386
5028
|
omit: this.makeOmitSchema(model).optional()
|
|
4387
5029
|
}));
|
|
4388
5030
|
return this.refineForSelectOmitMutuallyExclusive(result).optional();
|
|
4389
5031
|
}
|
|
4390
5032
|
makeCreateDataSchema(model, canBeArray, withoutFields = [], withoutRelationFields = false) {
|
|
4391
|
-
const
|
|
4392
|
-
const
|
|
5033
|
+
const uncheckedVariantFields = {};
|
|
5034
|
+
const checkedVariantFields = {};
|
|
4393
5035
|
const modelDef = requireModel(this.schema, model);
|
|
4394
5036
|
const hasRelation = !withoutRelationFields && Object.entries(modelDef.fields).some(([f, def]) => !withoutFields.includes(f) && def.relation);
|
|
4395
5037
|
Object.keys(modelDef.fields).forEach((field) => {
|
|
@@ -4400,6 +5042,9 @@ var InputValidator = class {
|
|
|
4400
5042
|
if (fieldDef.computed) {
|
|
4401
5043
|
return;
|
|
4402
5044
|
}
|
|
5045
|
+
if (this.isDelegateDiscriminator(fieldDef)) {
|
|
5046
|
+
return;
|
|
5047
|
+
}
|
|
4403
5048
|
if (fieldDef.relation) {
|
|
4404
5049
|
if (withoutRelationFields) {
|
|
4405
5050
|
return;
|
|
@@ -4431,13 +5076,16 @@ var InputValidator = class {
|
|
|
4431
5076
|
if (fieldDef.optional && !fieldDef.array) {
|
|
4432
5077
|
fieldSchema = fieldSchema.nullable();
|
|
4433
5078
|
}
|
|
4434
|
-
|
|
5079
|
+
checkedVariantFields[field] = fieldSchema;
|
|
5080
|
+
if (fieldDef.array || !fieldDef.relation.references) {
|
|
5081
|
+
uncheckedVariantFields[field] = fieldSchema;
|
|
5082
|
+
}
|
|
4435
5083
|
} else {
|
|
4436
5084
|
let fieldSchema = this.makePrimitiveSchema(fieldDef.type);
|
|
4437
5085
|
if (fieldDef.array) {
|
|
4438
5086
|
fieldSchema = import_zod.z.union([
|
|
4439
5087
|
import_zod.z.array(fieldSchema),
|
|
4440
|
-
import_zod.z.
|
|
5088
|
+
import_zod.z.strictObject({
|
|
4441
5089
|
set: import_zod.z.array(fieldSchema)
|
|
4442
5090
|
})
|
|
4443
5091
|
]).optional();
|
|
@@ -4448,27 +5096,34 @@ var InputValidator = class {
|
|
|
4448
5096
|
if (fieldDef.optional) {
|
|
4449
5097
|
fieldSchema = fieldSchema.nullable();
|
|
4450
5098
|
}
|
|
4451
|
-
|
|
5099
|
+
uncheckedVariantFields[field] = fieldSchema;
|
|
4452
5100
|
if (!fieldDef.foreignKeyFor) {
|
|
4453
|
-
|
|
5101
|
+
checkedVariantFields[field] = fieldSchema;
|
|
4454
5102
|
}
|
|
4455
5103
|
}
|
|
4456
5104
|
});
|
|
4457
5105
|
if (!hasRelation) {
|
|
4458
|
-
return this.orArray(import_zod.z.
|
|
5106
|
+
return this.orArray(import_zod.z.strictObject(uncheckedVariantFields), canBeArray);
|
|
4459
5107
|
} else {
|
|
4460
5108
|
return import_zod.z.union([
|
|
4461
|
-
import_zod.z.
|
|
4462
|
-
import_zod.z.
|
|
5109
|
+
import_zod.z.strictObject(uncheckedVariantFields),
|
|
5110
|
+
import_zod.z.strictObject(checkedVariantFields),
|
|
4463
5111
|
...canBeArray ? [
|
|
4464
|
-
import_zod.z.array(import_zod.z.
|
|
5112
|
+
import_zod.z.array(import_zod.z.strictObject(uncheckedVariantFields))
|
|
4465
5113
|
] : [],
|
|
4466
5114
|
...canBeArray ? [
|
|
4467
|
-
import_zod.z.array(import_zod.z.
|
|
5115
|
+
import_zod.z.array(import_zod.z.strictObject(checkedVariantFields))
|
|
4468
5116
|
] : []
|
|
4469
5117
|
]);
|
|
4470
5118
|
}
|
|
4471
5119
|
}
|
|
5120
|
+
isDelegateDiscriminator(fieldDef) {
|
|
5121
|
+
if (!fieldDef.originModel) {
|
|
5122
|
+
return false;
|
|
5123
|
+
}
|
|
5124
|
+
const discriminatorField = getDiscriminatorField(this.schema, fieldDef.originModel);
|
|
5125
|
+
return discriminatorField === fieldDef.name;
|
|
5126
|
+
}
|
|
4472
5127
|
makeRelationManipulationSchema(fieldDef, withoutFields, mode) {
|
|
4473
5128
|
const fieldType = fieldDef.type;
|
|
4474
5129
|
const array = !!fieldDef.array;
|
|
@@ -4485,31 +5140,31 @@ var InputValidator = class {
|
|
|
4485
5140
|
fields["disconnect"] = this.makeDisconnectDataSchema(fieldType, array).optional();
|
|
4486
5141
|
fields["delete"] = this.makeDeleteRelationDataSchema(fieldType, array, true).optional();
|
|
4487
5142
|
}
|
|
4488
|
-
fields["update"] = array ? this.orArray(import_zod.z.
|
|
5143
|
+
fields["update"] = array ? this.orArray(import_zod.z.strictObject({
|
|
4489
5144
|
where: this.makeWhereSchema(fieldType, true),
|
|
4490
5145
|
data: this.makeUpdateDataSchema(fieldType, withoutFields)
|
|
4491
5146
|
}), true).optional() : import_zod.z.union([
|
|
4492
|
-
import_zod.z.
|
|
5147
|
+
import_zod.z.strictObject({
|
|
4493
5148
|
where: this.makeWhereSchema(fieldType, true),
|
|
4494
5149
|
data: this.makeUpdateDataSchema(fieldType, withoutFields)
|
|
4495
5150
|
}),
|
|
4496
5151
|
this.makeUpdateDataSchema(fieldType, withoutFields)
|
|
4497
5152
|
]).optional();
|
|
4498
|
-
fields["upsert"] = this.orArray(import_zod.z.
|
|
5153
|
+
fields["upsert"] = this.orArray(import_zod.z.strictObject({
|
|
4499
5154
|
where: this.makeWhereSchema(fieldType, true),
|
|
4500
5155
|
create: this.makeCreateDataSchema(fieldType, false, withoutFields),
|
|
4501
5156
|
update: this.makeUpdateDataSchema(fieldType, withoutFields)
|
|
4502
5157
|
}), true).optional();
|
|
4503
5158
|
if (array) {
|
|
4504
5159
|
fields["set"] = this.makeSetDataSchema(fieldType, true).optional();
|
|
4505
|
-
fields["updateMany"] = this.orArray(import_zod.z.
|
|
5160
|
+
fields["updateMany"] = this.orArray(import_zod.z.strictObject({
|
|
4506
5161
|
where: this.makeWhereSchema(fieldType, false, true),
|
|
4507
5162
|
data: this.makeUpdateDataSchema(fieldType, withoutFields)
|
|
4508
5163
|
}), true).optional();
|
|
4509
5164
|
fields["deleteMany"] = this.makeDeleteRelationDataSchema(fieldType, true, false).optional();
|
|
4510
5165
|
}
|
|
4511
5166
|
}
|
|
4512
|
-
return import_zod.z.
|
|
5167
|
+
return import_zod.z.strictObject(fields);
|
|
4513
5168
|
}
|
|
4514
5169
|
makeSetDataSchema(model, canBeArray) {
|
|
4515
5170
|
return this.orArray(this.makeWhereSchema(model, true), canBeArray);
|
|
@@ -4539,13 +5194,13 @@ var InputValidator = class {
|
|
|
4539
5194
|
return this.orArray(import_zod.z.object({
|
|
4540
5195
|
where: whereSchema,
|
|
4541
5196
|
create: createSchema
|
|
4542
|
-
})
|
|
5197
|
+
}), canBeArray);
|
|
4543
5198
|
}
|
|
4544
5199
|
makeCreateManyDataSchema(model, withoutFields) {
|
|
4545
5200
|
return import_zod.z.object({
|
|
4546
5201
|
data: this.makeCreateDataSchema(model, true, withoutFields, true),
|
|
4547
5202
|
skipDuplicates: import_zod.z.boolean().optional()
|
|
4548
|
-
})
|
|
5203
|
+
});
|
|
4549
5204
|
}
|
|
4550
5205
|
// #endregion
|
|
4551
5206
|
// #region Update
|
|
@@ -4556,19 +5211,19 @@ var InputValidator = class {
|
|
|
4556
5211
|
select: this.makeSelectSchema(model).optional(),
|
|
4557
5212
|
include: this.makeIncludeSchema(model).optional(),
|
|
4558
5213
|
omit: this.makeOmitSchema(model).optional()
|
|
4559
|
-
})
|
|
5214
|
+
});
|
|
4560
5215
|
return this.refineForSelectIncludeMutuallyExclusive(schema);
|
|
4561
5216
|
}
|
|
4562
5217
|
makeUpdateManySchema(model) {
|
|
4563
5218
|
return import_zod.z.object({
|
|
4564
5219
|
where: this.makeWhereSchema(model, false).optional(),
|
|
4565
5220
|
data: this.makeUpdateDataSchema(model, [], true),
|
|
4566
|
-
limit: import_zod.z.
|
|
4567
|
-
})
|
|
5221
|
+
limit: import_zod.z.int().nonnegative().optional()
|
|
5222
|
+
});
|
|
4568
5223
|
}
|
|
4569
5224
|
makeUpdateManyAndReturnSchema(model) {
|
|
4570
5225
|
const base = this.makeUpdateManySchema(model);
|
|
4571
|
-
const result = base.merge(import_zod.z.
|
|
5226
|
+
const result = base.merge(import_zod.z.strictObject({
|
|
4572
5227
|
select: this.makeSelectSchema(model).optional(),
|
|
4573
5228
|
omit: this.makeOmitSchema(model).optional()
|
|
4574
5229
|
}));
|
|
@@ -4582,12 +5237,12 @@ var InputValidator = class {
|
|
|
4582
5237
|
select: this.makeSelectSchema(model).optional(),
|
|
4583
5238
|
include: this.makeIncludeSchema(model).optional(),
|
|
4584
5239
|
omit: this.makeOmitSchema(model).optional()
|
|
4585
|
-
})
|
|
5240
|
+
});
|
|
4586
5241
|
return this.refineForSelectIncludeMutuallyExclusive(schema);
|
|
4587
5242
|
}
|
|
4588
5243
|
makeUpdateDataSchema(model, withoutFields = [], withoutRelationFields = false) {
|
|
4589
|
-
const
|
|
4590
|
-
const
|
|
5244
|
+
const uncheckedVariantFields = {};
|
|
5245
|
+
const checkedVariantFields = {};
|
|
4591
5246
|
const modelDef = requireModel(this.schema, model);
|
|
4592
5247
|
const hasRelation = Object.entries(modelDef.fields).some(([key, value]) => value.relation && !withoutFields.includes(key));
|
|
4593
5248
|
Object.keys(modelDef.fields).forEach((field) => {
|
|
@@ -4612,7 +5267,10 @@ var InputValidator = class {
|
|
|
4612
5267
|
if (fieldDef.optional && !fieldDef.array) {
|
|
4613
5268
|
fieldSchema = fieldSchema.nullable();
|
|
4614
5269
|
}
|
|
4615
|
-
|
|
5270
|
+
checkedVariantFields[field] = fieldSchema;
|
|
5271
|
+
if (fieldDef.array || !fieldDef.relation.references) {
|
|
5272
|
+
uncheckedVariantFields[field] = fieldSchema;
|
|
5273
|
+
}
|
|
4616
5274
|
} else {
|
|
4617
5275
|
let fieldSchema = this.makePrimitiveSchema(fieldDef.type).optional();
|
|
4618
5276
|
if (this.isNumericField(fieldDef)) {
|
|
@@ -4639,18 +5297,18 @@ var InputValidator = class {
|
|
|
4639
5297
|
if (fieldDef.optional) {
|
|
4640
5298
|
fieldSchema = fieldSchema.nullable();
|
|
4641
5299
|
}
|
|
4642
|
-
|
|
5300
|
+
uncheckedVariantFields[field] = fieldSchema;
|
|
4643
5301
|
if (!fieldDef.foreignKeyFor) {
|
|
4644
|
-
|
|
5302
|
+
checkedVariantFields[field] = fieldSchema;
|
|
4645
5303
|
}
|
|
4646
5304
|
}
|
|
4647
5305
|
});
|
|
4648
5306
|
if (!hasRelation) {
|
|
4649
|
-
return import_zod.z.
|
|
5307
|
+
return import_zod.z.strictObject(uncheckedVariantFields);
|
|
4650
5308
|
} else {
|
|
4651
5309
|
return import_zod.z.union([
|
|
4652
|
-
import_zod.z.
|
|
4653
|
-
import_zod.z.
|
|
5310
|
+
import_zod.z.strictObject(uncheckedVariantFields),
|
|
5311
|
+
import_zod.z.strictObject(checkedVariantFields)
|
|
4654
5312
|
]);
|
|
4655
5313
|
}
|
|
4656
5314
|
}
|
|
@@ -4661,25 +5319,25 @@ var InputValidator = class {
|
|
|
4661
5319
|
where: this.makeWhereSchema(model, true),
|
|
4662
5320
|
select: this.makeSelectSchema(model).optional(),
|
|
4663
5321
|
include: this.makeIncludeSchema(model).optional()
|
|
4664
|
-
})
|
|
5322
|
+
});
|
|
4665
5323
|
return this.refineForSelectIncludeMutuallyExclusive(schema);
|
|
4666
5324
|
}
|
|
4667
5325
|
makeDeleteManySchema(model) {
|
|
4668
5326
|
return import_zod.z.object({
|
|
4669
5327
|
where: this.makeWhereSchema(model, false).optional(),
|
|
4670
|
-
limit: import_zod.z.
|
|
4671
|
-
}).
|
|
5328
|
+
limit: import_zod.z.int().nonnegative().optional()
|
|
5329
|
+
}).optional();
|
|
4672
5330
|
}
|
|
4673
5331
|
// #endregion
|
|
4674
5332
|
// #region Count
|
|
4675
5333
|
makeCountSchema(model) {
|
|
4676
5334
|
return import_zod.z.object({
|
|
4677
5335
|
where: this.makeWhereSchema(model, false).optional(),
|
|
4678
|
-
skip:
|
|
4679
|
-
take:
|
|
5336
|
+
skip: this.makeSkipSchema().optional(),
|
|
5337
|
+
take: this.makeTakeSchema().optional(),
|
|
4680
5338
|
orderBy: this.orArray(this.makeOrderBySchema(model, true, false), true).optional(),
|
|
4681
5339
|
select: this.makeCountAggregateInputSchema(model).optional()
|
|
4682
|
-
}).
|
|
5340
|
+
}).optional();
|
|
4683
5341
|
}
|
|
4684
5342
|
makeCountAggregateInputSchema(model) {
|
|
4685
5343
|
const modelDef = requireModel(this.schema, model);
|
|
@@ -4691,7 +5349,7 @@ var InputValidator = class {
|
|
|
4691
5349
|
acc[field] = import_zod.z.literal(true).optional();
|
|
4692
5350
|
return acc;
|
|
4693
5351
|
}, {})
|
|
4694
|
-
})
|
|
5352
|
+
})
|
|
4695
5353
|
]);
|
|
4696
5354
|
}
|
|
4697
5355
|
// #endregion
|
|
@@ -4699,19 +5357,19 @@ var InputValidator = class {
|
|
|
4699
5357
|
makeAggregateSchema(model) {
|
|
4700
5358
|
return import_zod.z.object({
|
|
4701
5359
|
where: this.makeWhereSchema(model, false).optional(),
|
|
4702
|
-
skip:
|
|
4703
|
-
take:
|
|
5360
|
+
skip: this.makeSkipSchema().optional(),
|
|
5361
|
+
take: this.makeTakeSchema().optional(),
|
|
4704
5362
|
orderBy: this.orArray(this.makeOrderBySchema(model, true, false), true).optional(),
|
|
4705
5363
|
_count: this.makeCountAggregateInputSchema(model).optional(),
|
|
4706
5364
|
_avg: this.makeSumAvgInputSchema(model).optional(),
|
|
4707
5365
|
_sum: this.makeSumAvgInputSchema(model).optional(),
|
|
4708
5366
|
_min: this.makeMinMaxInputSchema(model).optional(),
|
|
4709
5367
|
_max: this.makeMinMaxInputSchema(model).optional()
|
|
4710
|
-
}).
|
|
5368
|
+
}).optional();
|
|
4711
5369
|
}
|
|
4712
5370
|
makeSumAvgInputSchema(model) {
|
|
4713
5371
|
const modelDef = requireModel(this.schema, model);
|
|
4714
|
-
return import_zod.z.
|
|
5372
|
+
return import_zod.z.strictObject(Object.keys(modelDef.fields).reduce((acc, field) => {
|
|
4715
5373
|
const fieldDef = requireField(this.schema, model, field);
|
|
4716
5374
|
if (this.isNumericField(fieldDef)) {
|
|
4717
5375
|
acc[field] = import_zod.z.literal(true).optional();
|
|
@@ -4721,7 +5379,7 @@ var InputValidator = class {
|
|
|
4721
5379
|
}
|
|
4722
5380
|
makeMinMaxInputSchema(model) {
|
|
4723
5381
|
const modelDef = requireModel(this.schema, model);
|
|
4724
|
-
return import_zod.z.
|
|
5382
|
+
return import_zod.z.strictObject(Object.keys(modelDef.fields).reduce((acc, field) => {
|
|
4725
5383
|
const fieldDef = requireField(this.schema, model, field);
|
|
4726
5384
|
if (!fieldDef.relation && !fieldDef.array) {
|
|
4727
5385
|
acc[field] = import_zod.z.literal(true).optional();
|
|
@@ -4736,30 +5394,42 @@ var InputValidator = class {
|
|
|
4736
5394
|
where: this.makeWhereSchema(model, false).optional(),
|
|
4737
5395
|
orderBy: this.orArray(this.makeOrderBySchema(model, false, true), true).optional(),
|
|
4738
5396
|
by: this.orArray(import_zod.z.enum(nonRelationFields), true),
|
|
4739
|
-
having: this.
|
|
4740
|
-
skip:
|
|
4741
|
-
take:
|
|
5397
|
+
having: this.makeHavingSchema(model).optional(),
|
|
5398
|
+
skip: this.makeSkipSchema().optional(),
|
|
5399
|
+
take: this.makeTakeSchema().optional(),
|
|
4742
5400
|
_count: this.makeCountAggregateInputSchema(model).optional(),
|
|
4743
5401
|
_avg: this.makeSumAvgInputSchema(model).optional(),
|
|
4744
5402
|
_sum: this.makeSumAvgInputSchema(model).optional(),
|
|
4745
5403
|
_min: this.makeMinMaxInputSchema(model).optional(),
|
|
4746
5404
|
_max: this.makeMinMaxInputSchema(model).optional()
|
|
4747
|
-
})
|
|
5405
|
+
});
|
|
4748
5406
|
schema = schema.refine((value) => {
|
|
4749
5407
|
const bys = typeof value.by === "string" ? [
|
|
4750
5408
|
value.by
|
|
4751
5409
|
] : value.by;
|
|
4752
|
-
if (value.having &&
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
5410
|
+
if (value.having && typeof value.having === "object") {
|
|
5411
|
+
for (const [key, val] of Object.entries(value.having)) {
|
|
5412
|
+
if (AGGREGATE_OPERATORS.includes(key)) {
|
|
5413
|
+
continue;
|
|
5414
|
+
}
|
|
5415
|
+
if (bys.includes(key)) {
|
|
5416
|
+
continue;
|
|
5417
|
+
}
|
|
5418
|
+
if (!val || typeof val !== "object") {
|
|
5419
|
+
return false;
|
|
5420
|
+
}
|
|
5421
|
+
if (!this.onlyAggregationFields(val)) {
|
|
5422
|
+
return false;
|
|
5423
|
+
}
|
|
5424
|
+
}
|
|
4756
5425
|
}
|
|
5426
|
+
return true;
|
|
4757
5427
|
}, 'fields in "having" must be in "by"');
|
|
4758
5428
|
schema = schema.refine((value) => {
|
|
4759
5429
|
const bys = typeof value.by === "string" ? [
|
|
4760
5430
|
value.by
|
|
4761
5431
|
] : value.by;
|
|
4762
|
-
if (value.orderBy && Object.keys(value.orderBy).filter((f) => !
|
|
5432
|
+
if (value.orderBy && Object.keys(value.orderBy).filter((f) => !AGGREGATE_OPERATORS.includes(f)).some((key) => !bys.includes(key))) {
|
|
4763
5433
|
return false;
|
|
4764
5434
|
} else {
|
|
4765
5435
|
return true;
|
|
@@ -4767,8 +5437,31 @@ var InputValidator = class {
|
|
|
4767
5437
|
}, 'fields in "orderBy" must be in "by"');
|
|
4768
5438
|
return schema;
|
|
4769
5439
|
}
|
|
5440
|
+
onlyAggregationFields(val) {
|
|
5441
|
+
for (const [key, value] of Object.entries(val)) {
|
|
5442
|
+
if (AGGREGATE_OPERATORS.includes(key)) {
|
|
5443
|
+
continue;
|
|
5444
|
+
}
|
|
5445
|
+
if (LOGICAL_COMBINATORS.includes(key)) {
|
|
5446
|
+
if (enumerate(value).every((v) => this.onlyAggregationFields(v))) {
|
|
5447
|
+
continue;
|
|
5448
|
+
}
|
|
5449
|
+
}
|
|
5450
|
+
return false;
|
|
5451
|
+
}
|
|
5452
|
+
return true;
|
|
5453
|
+
}
|
|
5454
|
+
makeHavingSchema(model) {
|
|
5455
|
+
return this.makeWhereSchema(model, false, true, true);
|
|
5456
|
+
}
|
|
4770
5457
|
// #endregion
|
|
4771
5458
|
// #region Helpers
|
|
5459
|
+
makeSkipSchema() {
|
|
5460
|
+
return import_zod.z.int().nonnegative();
|
|
5461
|
+
}
|
|
5462
|
+
makeTakeSchema() {
|
|
5463
|
+
return import_zod.z.int();
|
|
5464
|
+
}
|
|
4772
5465
|
refineForSelectIncludeMutuallyExclusive(schema) {
|
|
4773
5466
|
return schema.refine((value) => !(value["select"] && value["include"]), '"select" and "include" cannot be used together');
|
|
4774
5467
|
}
|
|
@@ -4787,6 +5480,9 @@ var InputValidator = class {
|
|
|
4787
5480
|
isNumericField(fieldDef) {
|
|
4788
5481
|
return NUMERIC_FIELD_TYPES.includes(fieldDef.type) && !fieldDef.array;
|
|
4789
5482
|
}
|
|
5483
|
+
get providerSupportsCaseSensitivity() {
|
|
5484
|
+
return this.schema.provider.type === "postgresql";
|
|
5485
|
+
}
|
|
4790
5486
|
};
|
|
4791
5487
|
|
|
4792
5488
|
// src/client/executor/zenstack-driver.ts
|
|
@@ -4796,11 +5492,11 @@ var ZenStackDriver = class {
|
|
|
4796
5492
|
}
|
|
4797
5493
|
#driver;
|
|
4798
5494
|
#log;
|
|
4799
|
-
txConnection;
|
|
4800
5495
|
#initPromise;
|
|
4801
5496
|
#initDone;
|
|
4802
5497
|
#destroyPromise;
|
|
4803
5498
|
#connections = /* @__PURE__ */ new WeakSet();
|
|
5499
|
+
#txConnections = /* @__PURE__ */ new WeakMap();
|
|
4804
5500
|
constructor(driver, log) {
|
|
4805
5501
|
this.#initDone = false;
|
|
4806
5502
|
this.#driver = driver;
|
|
@@ -4841,21 +5537,30 @@ var ZenStackDriver = class {
|
|
|
4841
5537
|
}
|
|
4842
5538
|
async beginTransaction(connection, settings) {
|
|
4843
5539
|
const result = await this.#driver.beginTransaction(connection, settings);
|
|
4844
|
-
this.
|
|
5540
|
+
this.#txConnections.set(connection, []);
|
|
4845
5541
|
return result;
|
|
4846
5542
|
}
|
|
4847
|
-
commitTransaction(connection) {
|
|
5543
|
+
async commitTransaction(connection) {
|
|
4848
5544
|
try {
|
|
4849
|
-
|
|
4850
|
-
|
|
4851
|
-
this.
|
|
5545
|
+
const result = await this.#driver.commitTransaction(connection);
|
|
5546
|
+
const callbacks = this.#txConnections.get(connection);
|
|
5547
|
+
this.#txConnections.delete(connection);
|
|
5548
|
+
if (callbacks) {
|
|
5549
|
+
for (const callback of callbacks) {
|
|
5550
|
+
await callback();
|
|
5551
|
+
}
|
|
5552
|
+
}
|
|
5553
|
+
return result;
|
|
5554
|
+
} catch (err) {
|
|
5555
|
+
this.#txConnections.delete(connection);
|
|
5556
|
+
throw err;
|
|
4852
5557
|
}
|
|
4853
5558
|
}
|
|
4854
|
-
rollbackTransaction(connection) {
|
|
5559
|
+
async rollbackTransaction(connection) {
|
|
4855
5560
|
try {
|
|
4856
|
-
return this.#driver.rollbackTransaction(connection);
|
|
5561
|
+
return await this.#driver.rollbackTransaction(connection);
|
|
4857
5562
|
} finally {
|
|
4858
|
-
this.
|
|
5563
|
+
this.#txConnections.delete(connection);
|
|
4859
5564
|
}
|
|
4860
5565
|
}
|
|
4861
5566
|
async destroy() {
|
|
@@ -4933,6 +5638,22 @@ var ZenStackDriver = class {
|
|
|
4933
5638
|
#calculateDurationMillis(startTime) {
|
|
4934
5639
|
return performanceNow() - startTime;
|
|
4935
5640
|
}
|
|
5641
|
+
isTransactionConnection(connection) {
|
|
5642
|
+
return this.#txConnections.has(connection);
|
|
5643
|
+
}
|
|
5644
|
+
registerTransactionCommitCallback(connection, callback) {
|
|
5645
|
+
if (!this.#txConnections.has(connection)) {
|
|
5646
|
+
return;
|
|
5647
|
+
}
|
|
5648
|
+
const callbacks = this.#txConnections.get(connection);
|
|
5649
|
+
if (callbacks) {
|
|
5650
|
+
callbacks.push(callback);
|
|
5651
|
+
} else {
|
|
5652
|
+
this.#txConnections.set(connection, [
|
|
5653
|
+
callback
|
|
5654
|
+
]);
|
|
5655
|
+
}
|
|
5656
|
+
}
|
|
4936
5657
|
};
|
|
4937
5658
|
function performanceNow() {
|
|
4938
5659
|
if (typeof performance !== "undefined" && typeof performance.now === "function") {
|
|
@@ -4946,7 +5667,8 @@ __name(performanceNow, "performanceNow");
|
|
|
4946
5667
|
// src/client/executor/zenstack-query-executor.ts
|
|
4947
5668
|
var import_kysely13 = require("kysely");
|
|
4948
5669
|
var import_nanoid2 = require("nanoid");
|
|
4949
|
-
var
|
|
5670
|
+
var import_node_util2 = require("util");
|
|
5671
|
+
var import_ts_pattern16 = require("ts-pattern");
|
|
4950
5672
|
|
|
4951
5673
|
// src/client/executor/name-mapper.ts
|
|
4952
5674
|
var import_kysely12 = require("kysely");
|
|
@@ -4955,11 +5677,11 @@ var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
|
|
|
4955
5677
|
__name(this, "QueryNameMapper");
|
|
4956
5678
|
}
|
|
4957
5679
|
schema;
|
|
4958
|
-
modelToTableMap;
|
|
4959
|
-
fieldToColumnMap;
|
|
4960
|
-
modelStack;
|
|
5680
|
+
modelToTableMap = /* @__PURE__ */ new Map();
|
|
5681
|
+
fieldToColumnMap = /* @__PURE__ */ new Map();
|
|
5682
|
+
modelStack = [];
|
|
4961
5683
|
constructor(schema) {
|
|
4962
|
-
super(), this.schema = schema
|
|
5684
|
+
super(), this.schema = schema;
|
|
4963
5685
|
for (const [modelName, modelDef] of Object.entries(schema.models)) {
|
|
4964
5686
|
const mappedName = this.getMappedName(modelDef);
|
|
4965
5687
|
if (mappedName) {
|
|
@@ -5148,7 +5870,7 @@ var QueryNameMapper = class extends import_kysely12.OperationNodeTransformer {
|
|
|
5148
5870
|
this.requireCurrentModel(contextNode);
|
|
5149
5871
|
model = model ?? this.currentModel;
|
|
5150
5872
|
const modelDef = requireModel(this.schema, model);
|
|
5151
|
-
const scalarFields = Object.entries(modelDef.fields).filter(([, fieldDef]) => !fieldDef.relation && !fieldDef.computed).map(([fieldName]) => fieldName);
|
|
5873
|
+
const scalarFields = Object.entries(modelDef.fields).filter(([, fieldDef]) => !fieldDef.relation && !fieldDef.computed && !fieldDef.originModel).map(([fieldName]) => fieldName);
|
|
5152
5874
|
return scalarFields;
|
|
5153
5875
|
}
|
|
5154
5876
|
};
|
|
@@ -5173,16 +5895,18 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
|
|
|
5173
5895
|
get options() {
|
|
5174
5896
|
return this.client.$options;
|
|
5175
5897
|
}
|
|
5176
|
-
async executeQuery(compiledQuery,
|
|
5898
|
+
async executeQuery(compiledQuery, _queryId) {
|
|
5177
5899
|
let queryNode = compiledQuery.query;
|
|
5178
5900
|
let mutationInterceptionInfo;
|
|
5179
5901
|
if (this.isMutationNode(queryNode) && this.hasMutationHooks) {
|
|
5180
5902
|
mutationInterceptionInfo = await this.callMutationInterceptionFilters(queryNode);
|
|
5181
5903
|
}
|
|
5182
5904
|
const task = /* @__PURE__ */ __name(async () => {
|
|
5183
|
-
|
|
5905
|
+
if (this.isMutationNode(queryNode)) {
|
|
5906
|
+
await this.callBeforeMutationHooks(queryNode, mutationInterceptionInfo);
|
|
5907
|
+
}
|
|
5184
5908
|
const oldQueryNode = queryNode;
|
|
5185
|
-
if ((import_kysely13.InsertQueryNode.is(queryNode) || import_kysely13.
|
|
5909
|
+
if ((import_kysely13.InsertQueryNode.is(queryNode) || import_kysely13.UpdateQueryNode.is(queryNode)) && mutationInterceptionInfo?.loadAfterMutationEntity) {
|
|
5186
5910
|
queryNode = {
|
|
5187
5911
|
...queryNode,
|
|
5188
5912
|
returning: import_kysely13.ReturningNode.create([
|
|
@@ -5190,42 +5914,73 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
|
|
|
5190
5914
|
])
|
|
5191
5915
|
};
|
|
5192
5916
|
}
|
|
5193
|
-
const
|
|
5194
|
-
await this.
|
|
5917
|
+
const queryParams = compiledQuery.$raw ? compiledQuery.parameters : void 0;
|
|
5918
|
+
const result = await this.proceedQueryWithKyselyInterceptors(queryNode, queryParams);
|
|
5919
|
+
if (this.isMutationNode(queryNode)) {
|
|
5920
|
+
await this.callAfterMutationHooks(result.result, queryNode, mutationInterceptionInfo, result.connection);
|
|
5921
|
+
}
|
|
5195
5922
|
if (oldQueryNode !== queryNode) {
|
|
5196
5923
|
}
|
|
5197
|
-
return result;
|
|
5924
|
+
return result.result;
|
|
5198
5925
|
}, "task");
|
|
5199
|
-
return
|
|
5200
|
-
}
|
|
5201
|
-
proceedQueryWithKyselyInterceptors(queryNode,
|
|
5202
|
-
let proceed = /* @__PURE__ */ __name((q) => this.proceedQuery(q,
|
|
5203
|
-
const
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5926
|
+
return task();
|
|
5927
|
+
}
|
|
5928
|
+
proceedQueryWithKyselyInterceptors(queryNode, parameters) {
|
|
5929
|
+
let proceed = /* @__PURE__ */ __name((q) => this.proceedQuery(q, parameters), "proceed");
|
|
5930
|
+
const hooks = [];
|
|
5931
|
+
for (const plugin of this.client.$options.plugins ?? []) {
|
|
5932
|
+
if (plugin.onKyselyQuery) {
|
|
5933
|
+
hooks.push(plugin.onKyselyQuery.bind(plugin));
|
|
5934
|
+
}
|
|
5935
|
+
}
|
|
5207
5936
|
for (const hook of hooks) {
|
|
5208
5937
|
const _proceed = proceed;
|
|
5209
|
-
proceed = /* @__PURE__ */ __name((query) => {
|
|
5210
|
-
|
|
5938
|
+
proceed = /* @__PURE__ */ __name(async (query) => {
|
|
5939
|
+
let connection;
|
|
5940
|
+
const _p = /* @__PURE__ */ __name(async (q) => {
|
|
5941
|
+
const r = await _proceed(q);
|
|
5942
|
+
connection = r.connection;
|
|
5943
|
+
return r.result;
|
|
5944
|
+
}, "_p");
|
|
5945
|
+
const hookResult = await hook({
|
|
5211
5946
|
client: this.client,
|
|
5212
5947
|
schema: this.client.$schema,
|
|
5213
5948
|
kysely: this.kysely,
|
|
5214
5949
|
query,
|
|
5215
|
-
proceed:
|
|
5216
|
-
transaction: makeTx(_proceed)
|
|
5950
|
+
proceed: _p
|
|
5217
5951
|
});
|
|
5952
|
+
return {
|
|
5953
|
+
result: hookResult,
|
|
5954
|
+
connection
|
|
5955
|
+
};
|
|
5218
5956
|
}, "proceed");
|
|
5219
5957
|
}
|
|
5220
5958
|
return proceed(queryNode);
|
|
5221
5959
|
}
|
|
5222
|
-
async proceedQuery(query,
|
|
5960
|
+
async proceedQuery(query, parameters) {
|
|
5223
5961
|
const finalQuery = this.nameMapper.transformNode(query);
|
|
5224
|
-
|
|
5962
|
+
let compiled = this.compileQuery(finalQuery);
|
|
5963
|
+
if (parameters) {
|
|
5964
|
+
compiled = {
|
|
5965
|
+
...compiled,
|
|
5966
|
+
parameters
|
|
5967
|
+
};
|
|
5968
|
+
}
|
|
5225
5969
|
try {
|
|
5226
|
-
return
|
|
5970
|
+
return await this.provideConnection(async (connection) => {
|
|
5971
|
+
const result = await connection.executeQuery(compiled);
|
|
5972
|
+
return {
|
|
5973
|
+
result,
|
|
5974
|
+
connection
|
|
5975
|
+
};
|
|
5976
|
+
});
|
|
5227
5977
|
} catch (err) {
|
|
5228
|
-
|
|
5978
|
+
let message = `Failed to execute query: ${err}, sql: ${compiled.sql}`;
|
|
5979
|
+
if (this.options.debug) {
|
|
5980
|
+
message += `, parameters:
|
|
5981
|
+
${compiled.parameters.map((p) => (0, import_node_util2.inspect)(p)).join("\n")}`;
|
|
5982
|
+
}
|
|
5983
|
+
throw new QueryError(message, err);
|
|
5229
5984
|
}
|
|
5230
5985
|
}
|
|
5231
5986
|
isMutationNode(queryNode) {
|
|
@@ -5253,30 +6008,15 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
|
|
|
5253
6008
|
return new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, this.connectionProvider, []);
|
|
5254
6009
|
}
|
|
5255
6010
|
withConnectionProvider(connectionProvider) {
|
|
5256
|
-
|
|
5257
|
-
|
|
5258
|
-
|
|
5259
|
-
if (!useTransaction || this.driver.txConnection) {
|
|
5260
|
-
return callback();
|
|
5261
|
-
} else {
|
|
5262
|
-
return this.provideConnection(async (connection) => {
|
|
5263
|
-
try {
|
|
5264
|
-
await this.driver.beginTransaction(connection, {});
|
|
5265
|
-
const result = await callback();
|
|
5266
|
-
await this.driver.commitTransaction(connection);
|
|
5267
|
-
return result;
|
|
5268
|
-
} catch (error) {
|
|
5269
|
-
await this.driver.rollbackTransaction(connection);
|
|
5270
|
-
throw error;
|
|
5271
|
-
}
|
|
5272
|
-
});
|
|
5273
|
-
}
|
|
6011
|
+
const newExecutor = new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, connectionProvider);
|
|
6012
|
+
newExecutor.client = this.client.withExecutor(newExecutor);
|
|
6013
|
+
return newExecutor;
|
|
5274
6014
|
}
|
|
5275
6015
|
get hasMutationHooks() {
|
|
5276
6016
|
return this.client.$options.plugins?.some((plugin) => plugin.beforeEntityMutation || plugin.afterEntityMutation);
|
|
5277
6017
|
}
|
|
5278
6018
|
getMutationModel(queryNode) {
|
|
5279
|
-
return (0,
|
|
6019
|
+
return (0, import_ts_pattern16.match)(queryNode).when(import_kysely13.InsertQueryNode.is, (node) => node.into.table.identifier.name).when(import_kysely13.UpdateQueryNode.is, (node) => node.table.table.identifier.name).when(import_kysely13.DeleteQueryNode.is, (node) => {
|
|
5280
6020
|
if (node.from.froms.length !== 1) {
|
|
5281
6021
|
throw new InternalError(`Delete query must have exactly one from table`);
|
|
5282
6022
|
}
|
|
@@ -5292,7 +6032,7 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
|
|
|
5292
6032
|
const result = {
|
|
5293
6033
|
intercept: false
|
|
5294
6034
|
};
|
|
5295
|
-
const { action, where } = (0,
|
|
6035
|
+
const { action, where } = (0, import_ts_pattern16.match)(queryNode).when(import_kysely13.InsertQueryNode.is, () => ({
|
|
5296
6036
|
action: "create",
|
|
5297
6037
|
where: void 0
|
|
5298
6038
|
})).when(import_kysely13.UpdateQueryNode.is, (node) => ({
|
|
@@ -5312,14 +6052,13 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
|
|
|
5312
6052
|
queryNode
|
|
5313
6053
|
});
|
|
5314
6054
|
result.intercept ||= filterResult.intercept;
|
|
5315
|
-
result.useTransactionForMutation ||= filterResult.useTransactionForMutation;
|
|
5316
6055
|
result.loadBeforeMutationEntity ||= filterResult.loadBeforeMutationEntity;
|
|
5317
6056
|
result.loadAfterMutationEntity ||= filterResult.loadAfterMutationEntity;
|
|
5318
6057
|
}
|
|
5319
6058
|
}
|
|
5320
6059
|
let beforeMutationEntities;
|
|
5321
6060
|
if (result.loadBeforeMutationEntity && (import_kysely13.UpdateQueryNode.is(queryNode) || import_kysely13.DeleteQueryNode.is(queryNode))) {
|
|
5322
|
-
beforeMutationEntities = await this.loadEntities(
|
|
6061
|
+
beforeMutationEntities = await this.loadEntities(mutationModel, where);
|
|
5323
6062
|
}
|
|
5324
6063
|
return {
|
|
5325
6064
|
...result,
|
|
@@ -5332,16 +6071,16 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
|
|
|
5332
6071
|
return void 0;
|
|
5333
6072
|
}
|
|
5334
6073
|
}
|
|
5335
|
-
callBeforeMutationHooks(queryNode, mutationInterceptionInfo) {
|
|
6074
|
+
async callBeforeMutationHooks(queryNode, mutationInterceptionInfo) {
|
|
5336
6075
|
if (!mutationInterceptionInfo?.intercept) {
|
|
5337
6076
|
return;
|
|
5338
6077
|
}
|
|
5339
6078
|
if (this.options.plugins) {
|
|
6079
|
+
const mutationModel = this.getMutationModel(queryNode);
|
|
5340
6080
|
for (const plugin of this.options.plugins) {
|
|
5341
6081
|
if (plugin.beforeEntityMutation) {
|
|
5342
|
-
plugin.beforeEntityMutation({
|
|
5343
|
-
|
|
5344
|
-
model: this.getMutationModel(queryNode),
|
|
6082
|
+
await plugin.beforeEntityMutation({
|
|
6083
|
+
model: mutationModel,
|
|
5345
6084
|
action: mutationInterceptionInfo.action,
|
|
5346
6085
|
queryNode,
|
|
5347
6086
|
entities: mutationInterceptionInfo.beforeMutationEntities
|
|
@@ -5350,44 +6089,59 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
|
|
|
5350
6089
|
}
|
|
5351
6090
|
}
|
|
5352
6091
|
}
|
|
5353
|
-
async
|
|
6092
|
+
async callAfterMutationHooks(queryResult, queryNode, mutationInterceptionInfo, connection) {
|
|
5354
6093
|
if (!mutationInterceptionInfo?.intercept) {
|
|
5355
6094
|
return;
|
|
5356
6095
|
}
|
|
5357
|
-
|
|
5358
|
-
|
|
5359
|
-
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5367
|
-
|
|
5368
|
-
|
|
5369
|
-
|
|
5370
|
-
|
|
6096
|
+
const hooks = [];
|
|
6097
|
+
for (const plugin of this.options.plugins ?? []) {
|
|
6098
|
+
if (plugin.afterEntityMutation) {
|
|
6099
|
+
hooks.push(plugin.afterEntityMutation.bind(plugin));
|
|
6100
|
+
}
|
|
6101
|
+
}
|
|
6102
|
+
if (hooks.length === 0) {
|
|
6103
|
+
return;
|
|
6104
|
+
}
|
|
6105
|
+
const mutationModel = this.getMutationModel(queryNode);
|
|
6106
|
+
const inTransaction = this.driver.isTransactionConnection(connection);
|
|
6107
|
+
for (const hook of hooks) {
|
|
6108
|
+
let afterMutationEntities = void 0;
|
|
6109
|
+
if (mutationInterceptionInfo.loadAfterMutationEntity) {
|
|
6110
|
+
if (import_kysely13.InsertQueryNode.is(queryNode) || import_kysely13.UpdateQueryNode.is(queryNode)) {
|
|
6111
|
+
afterMutationEntities = queryResult.rows;
|
|
6112
|
+
}
|
|
6113
|
+
}
|
|
6114
|
+
const action = /* @__PURE__ */ __name(async () => {
|
|
6115
|
+
try {
|
|
6116
|
+
await hook({
|
|
6117
|
+
model: mutationModel,
|
|
5371
6118
|
action: mutationInterceptionInfo.action,
|
|
5372
6119
|
queryNode,
|
|
5373
6120
|
beforeMutationEntities: mutationInterceptionInfo.beforeMutationEntities,
|
|
5374
6121
|
afterMutationEntities
|
|
5375
6122
|
});
|
|
6123
|
+
} catch (err) {
|
|
6124
|
+
console.error(`Error in afterEntityMutation hook for model "${mutationModel}": ${err}`);
|
|
5376
6125
|
}
|
|
6126
|
+
}, "action");
|
|
6127
|
+
if (inTransaction) {
|
|
6128
|
+
this.driver.registerTransactionCommitCallback(connection, action);
|
|
6129
|
+
} else {
|
|
6130
|
+
await action();
|
|
5377
6131
|
}
|
|
5378
6132
|
}
|
|
5379
6133
|
}
|
|
5380
|
-
async loadEntities(
|
|
5381
|
-
const selectQuery = kysely.selectFrom(model).selectAll();
|
|
6134
|
+
async loadEntities(model, where) {
|
|
6135
|
+
const selectQuery = this.kysely.selectFrom(model).selectAll();
|
|
5382
6136
|
let selectQueryNode = selectQuery.toOperationNode();
|
|
5383
6137
|
selectQueryNode = {
|
|
5384
6138
|
...selectQueryNode,
|
|
5385
6139
|
where: this.andNodes(selectQueryNode.where, where)
|
|
5386
6140
|
};
|
|
5387
|
-
const compiled =
|
|
6141
|
+
const compiled = this.compileQuery(selectQueryNode);
|
|
6142
|
+
const result = await this.executeQuery(compiled, {
|
|
5388
6143
|
queryId: `zenstack-${(0, import_nanoid2.nanoid)()}`
|
|
5389
6144
|
});
|
|
5390
|
-
const result = await kysely.executeQuery(compiled);
|
|
5391
6145
|
return result.rows;
|
|
5392
6146
|
}
|
|
5393
6147
|
andNodes(condition1, condition2) {
|
|
@@ -5416,9 +6170,9 @@ __export(functions_exports, {
|
|
|
5416
6170
|
search: () => search,
|
|
5417
6171
|
startsWith: () => startsWith
|
|
5418
6172
|
});
|
|
6173
|
+
var import_common_helpers10 = require("@zenstackhq/common-helpers");
|
|
5419
6174
|
var import_kysely14 = require("kysely");
|
|
5420
|
-
var
|
|
5421
|
-
var import_ts_pattern16 = require("ts-pattern");
|
|
6175
|
+
var import_ts_pattern17 = require("ts-pattern");
|
|
5422
6176
|
var contains = /* @__PURE__ */ __name((eb, args) => {
|
|
5423
6177
|
const [field, search2, caseInsensitive = false] = args;
|
|
5424
6178
|
if (!field) {
|
|
@@ -5503,7 +6257,7 @@ var isEmpty = /* @__PURE__ */ __name((eb, args, { dialect }) => {
|
|
|
5503
6257
|
return eb(dialect.buildArrayLength(eb, field), "=", import_kysely14.sql.lit(0));
|
|
5504
6258
|
}, "isEmpty");
|
|
5505
6259
|
var now = /* @__PURE__ */ __name((eb, _args, { dialect }) => {
|
|
5506
|
-
return (0,
|
|
6260
|
+
return (0, import_ts_pattern17.match)(dialect.provider).with("postgresql", () => eb.fn("now")).with("sqlite", () => import_kysely14.sql.raw("CURRENT_TIMESTAMP")).exhaustive();
|
|
5507
6261
|
}, "now");
|
|
5508
6262
|
var currentModel = /* @__PURE__ */ __name((_eb, args, { model }) => {
|
|
5509
6263
|
let result = model;
|
|
@@ -5523,8 +6277,8 @@ var currentOperation = /* @__PURE__ */ __name((_eb, args, { operation }) => {
|
|
|
5523
6277
|
}, "currentOperation");
|
|
5524
6278
|
function processCasing(casing, result, model) {
|
|
5525
6279
|
const opNode = casing.toOperationNode();
|
|
5526
|
-
(0,
|
|
5527
|
-
result = (0,
|
|
6280
|
+
(0, import_common_helpers10.invariant)(import_kysely14.ValueNode.is(opNode) && typeof opNode.value === "string", '"casting" parameter must be a string value');
|
|
6281
|
+
result = (0, import_ts_pattern17.match)(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => (0, import_common_helpers10.upperCaseFirst)(result)).with("uncapitalize", () => (0, import_common_helpers10.lowerCaseFirst)(result)).otherwise(() => {
|
|
5528
6282
|
throw new Error(`Invalid casing value: ${opNode.value}. Must be "original", "upper", "lower", "capitalize", or "uncapitalize".`);
|
|
5529
6283
|
});
|
|
5530
6284
|
return result;
|
|
@@ -5532,9 +6286,9 @@ function processCasing(casing, result, model) {
|
|
|
5532
6286
|
__name(processCasing, "processCasing");
|
|
5533
6287
|
|
|
5534
6288
|
// src/client/helpers/schema-db-pusher.ts
|
|
6289
|
+
var import_common_helpers11 = require("@zenstackhq/common-helpers");
|
|
5535
6290
|
var import_kysely15 = require("kysely");
|
|
5536
|
-
var
|
|
5537
|
-
var import_ts_pattern17 = require("ts-pattern");
|
|
6291
|
+
var import_ts_pattern18 = require("ts-pattern");
|
|
5538
6292
|
var SchemaDbPusher = class {
|
|
5539
6293
|
static {
|
|
5540
6294
|
__name(this, "SchemaDbPusher");
|
|
@@ -5565,14 +6319,17 @@ var SchemaDbPusher = class {
|
|
|
5565
6319
|
for (const [fieldName, fieldDef] of Object.entries(modelDef.fields)) {
|
|
5566
6320
|
if (fieldDef.relation) {
|
|
5567
6321
|
table = this.addForeignKeyConstraint(table, model, fieldName, fieldDef);
|
|
5568
|
-
} else {
|
|
6322
|
+
} else if (!this.isComputedField(fieldDef)) {
|
|
5569
6323
|
table = this.createModelField(table, fieldName, fieldDef, modelDef);
|
|
5570
6324
|
}
|
|
5571
6325
|
}
|
|
5572
6326
|
table = this.addPrimaryKeyConstraint(table, model, modelDef);
|
|
5573
|
-
table = this.addUniqueConstraint(table, modelDef);
|
|
6327
|
+
table = this.addUniqueConstraint(table, model, modelDef);
|
|
5574
6328
|
return table;
|
|
5575
6329
|
}
|
|
6330
|
+
isComputedField(fieldDef) {
|
|
6331
|
+
return fieldDef.attributes?.some((a) => a.name === "@computed");
|
|
6332
|
+
}
|
|
5576
6333
|
addPrimaryKeyConstraint(table, model, modelDef) {
|
|
5577
6334
|
if (modelDef.idFields.length === 1) {
|
|
5578
6335
|
if (Object.values(modelDef.fields).some((f) => f.id)) {
|
|
@@ -5584,16 +6341,19 @@ var SchemaDbPusher = class {
|
|
|
5584
6341
|
}
|
|
5585
6342
|
return table;
|
|
5586
6343
|
}
|
|
5587
|
-
addUniqueConstraint(table, modelDef) {
|
|
6344
|
+
addUniqueConstraint(table, model, modelDef) {
|
|
5588
6345
|
for (const [key, value] of Object.entries(modelDef.uniqueFields)) {
|
|
5589
|
-
(0,
|
|
6346
|
+
(0, import_common_helpers11.invariant)(typeof value === "object", "expecting an object");
|
|
5590
6347
|
if ("type" in value) {
|
|
5591
6348
|
const fieldDef = modelDef.fields[key];
|
|
5592
6349
|
if (fieldDef.unique) {
|
|
5593
6350
|
continue;
|
|
5594
6351
|
}
|
|
6352
|
+
table = table.addUniqueConstraint(`unique_${model}_${key}`, [
|
|
6353
|
+
key
|
|
6354
|
+
]);
|
|
5595
6355
|
} else {
|
|
5596
|
-
table = table.addUniqueConstraint(`unique_${key}`, Object.keys(value));
|
|
6356
|
+
table = table.addUniqueConstraint(`unique_${model}_${key}`, Object.keys(value));
|
|
5597
6357
|
}
|
|
5598
6358
|
}
|
|
5599
6359
|
return table;
|
|
@@ -5632,7 +6392,7 @@ var SchemaDbPusher = class {
|
|
|
5632
6392
|
return "serial";
|
|
5633
6393
|
}
|
|
5634
6394
|
const type = fieldDef.type;
|
|
5635
|
-
const result = (0,
|
|
6395
|
+
const result = (0, import_ts_pattern18.match)(type).with("String", () => "text").with("Boolean", () => "boolean").with("Int", () => "integer").with("Float", () => "real").with("BigInt", () => "bigint").with("Decimal", () => "decimal").with("DateTime", () => "timestamp").with("Bytes", () => this.schema.provider.type === "postgresql" ? "bytea" : "blob").with("Json", () => "jsonb").otherwise(() => {
|
|
5636
6396
|
throw new Error(`Unsupported field type: ${type}`);
|
|
5637
6397
|
});
|
|
5638
6398
|
if (fieldDef.array) {
|
|
@@ -5645,7 +6405,7 @@ var SchemaDbPusher = class {
|
|
|
5645
6405
|
return fieldDef.default && ExpressionUtils.isCall(fieldDef.default) && fieldDef.default.function === "autoincrement";
|
|
5646
6406
|
}
|
|
5647
6407
|
addForeignKeyConstraint(table, model, fieldName, fieldDef) {
|
|
5648
|
-
(0,
|
|
6408
|
+
(0, import_common_helpers11.invariant)(fieldDef.relation, "field must be a relation");
|
|
5649
6409
|
if (!fieldDef.relation.fields || !fieldDef.relation.references) {
|
|
5650
6410
|
return table;
|
|
5651
6411
|
}
|
|
@@ -5661,16 +6421,16 @@ var SchemaDbPusher = class {
|
|
|
5661
6421
|
return table;
|
|
5662
6422
|
}
|
|
5663
6423
|
mapCascadeAction(action) {
|
|
5664
|
-
return (0,
|
|
6424
|
+
return (0, import_ts_pattern18.match)(action).with("SetNull", () => "set null").with("Cascade", () => "cascade").with("Restrict", () => "restrict").with("NoAction", () => "no action").with("SetDefault", () => "set default").exhaustive();
|
|
5665
6425
|
}
|
|
5666
6426
|
};
|
|
5667
6427
|
|
|
5668
6428
|
// src/client/promise.ts
|
|
5669
|
-
function
|
|
6429
|
+
function createZenStackPromise(callback) {
|
|
5670
6430
|
let promise;
|
|
5671
|
-
const cb = /* @__PURE__ */ __name(() => {
|
|
6431
|
+
const cb = /* @__PURE__ */ __name((txClient) => {
|
|
5672
6432
|
try {
|
|
5673
|
-
return promise ??= valueToPromise(callback());
|
|
6433
|
+
return promise ??= valueToPromise(callback(txClient));
|
|
5674
6434
|
} catch (err) {
|
|
5675
6435
|
return Promise.reject(err);
|
|
5676
6436
|
}
|
|
@@ -5685,10 +6445,11 @@ function createDeferredPromise(callback) {
|
|
|
5685
6445
|
finally(onFinally) {
|
|
5686
6446
|
return cb().finally(onFinally);
|
|
5687
6447
|
},
|
|
6448
|
+
cb,
|
|
5688
6449
|
[Symbol.toStringTag]: "ZenStackPromise"
|
|
5689
6450
|
};
|
|
5690
6451
|
}
|
|
5691
|
-
__name(
|
|
6452
|
+
__name(createZenStackPromise, "createZenStackPromise");
|
|
5692
6453
|
function valueToPromise(thing) {
|
|
5693
6454
|
if (typeof thing === "object" && typeof thing?.then === "function") {
|
|
5694
6455
|
return thing;
|
|
@@ -5699,9 +6460,9 @@ function valueToPromise(thing) {
|
|
|
5699
6460
|
__name(valueToPromise, "valueToPromise");
|
|
5700
6461
|
|
|
5701
6462
|
// src/client/result-processor.ts
|
|
6463
|
+
var import_common_helpers12 = require("@zenstackhq/common-helpers");
|
|
5702
6464
|
var import_decimal2 = __toESM(require("decimal.js"), 1);
|
|
5703
|
-
var
|
|
5704
|
-
var import_ts_pattern18 = require("ts-pattern");
|
|
6465
|
+
var import_ts_pattern19 = require("ts-pattern");
|
|
5705
6466
|
var ResultProcessor = class {
|
|
5706
6467
|
static {
|
|
5707
6468
|
__name(this, "ResultProcessor");
|
|
@@ -5735,6 +6496,21 @@ var ResultProcessor = class {
|
|
|
5735
6496
|
data[key] = typeof value === "string" ? JSON.parse(value) : value;
|
|
5736
6497
|
continue;
|
|
5737
6498
|
}
|
|
6499
|
+
if (key.startsWith(DELEGATE_JOINED_FIELD_PREFIX)) {
|
|
6500
|
+
if (value) {
|
|
6501
|
+
const subRow = this.transformJson(value);
|
|
6502
|
+
const subModel = key.slice(DELEGATE_JOINED_FIELD_PREFIX.length);
|
|
6503
|
+
const idValues = getIdValues(this.schema, subModel, subRow);
|
|
6504
|
+
if (Object.values(idValues).some((v) => v === null || v === void 0)) {
|
|
6505
|
+
delete data[key];
|
|
6506
|
+
continue;
|
|
6507
|
+
}
|
|
6508
|
+
const processedSubRow = this.processRow(subRow, subModel);
|
|
6509
|
+
Object.assign(data, processedSubRow);
|
|
6510
|
+
}
|
|
6511
|
+
delete data[key];
|
|
6512
|
+
continue;
|
|
6513
|
+
}
|
|
5738
6514
|
const fieldDef = getField(this.schema, model, key);
|
|
5739
6515
|
if (!fieldDef) {
|
|
5740
6516
|
continue;
|
|
@@ -5774,20 +6550,24 @@ var ResultProcessor = class {
|
|
|
5774
6550
|
return this.doProcessResult(relationData, fieldDef.type);
|
|
5775
6551
|
}
|
|
5776
6552
|
transformScalar(value, type) {
|
|
5777
|
-
|
|
6553
|
+
if (this.schema.typeDefs && type in this.schema.typeDefs) {
|
|
6554
|
+
return this.transformJson(value);
|
|
6555
|
+
} else {
|
|
6556
|
+
return (0, import_ts_pattern19.match)(type).with("Boolean", () => this.transformBoolean(value)).with("DateTime", () => this.transformDate(value)).with("Bytes", () => this.transformBytes(value)).with("Decimal", () => this.transformDecimal(value)).with("BigInt", () => this.transformBigInt(value)).with("Json", () => this.transformJson(value)).otherwise(() => value);
|
|
6557
|
+
}
|
|
5778
6558
|
}
|
|
5779
6559
|
transformDecimal(value) {
|
|
5780
6560
|
if (value instanceof import_decimal2.default) {
|
|
5781
6561
|
return value;
|
|
5782
6562
|
}
|
|
5783
|
-
(0,
|
|
6563
|
+
(0, import_common_helpers12.invariant)(typeof value === "string" || typeof value === "number" || value instanceof import_decimal2.default, `Expected string, number or Decimal, got ${typeof value}`);
|
|
5784
6564
|
return new import_decimal2.default(value);
|
|
5785
6565
|
}
|
|
5786
6566
|
transformBigInt(value) {
|
|
5787
6567
|
if (typeof value === "bigint") {
|
|
5788
6568
|
return value;
|
|
5789
6569
|
}
|
|
5790
|
-
(0,
|
|
6570
|
+
(0, import_common_helpers12.invariant)(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
|
|
5791
6571
|
return BigInt(value);
|
|
5792
6572
|
}
|
|
5793
6573
|
transformBoolean(value) {
|
|
@@ -5806,6 +6586,9 @@ var ResultProcessor = class {
|
|
|
5806
6586
|
return Buffer.isBuffer(value) ? Uint8Array.from(value) : value;
|
|
5807
6587
|
}
|
|
5808
6588
|
fixReversedResult(data, model, args) {
|
|
6589
|
+
if (!data) {
|
|
6590
|
+
return;
|
|
6591
|
+
}
|
|
5809
6592
|
if (Array.isArray(data) && typeof args === "object" && args && args.take !== void 0 && args.take < 0) {
|
|
5810
6593
|
data.reverse();
|
|
5811
6594
|
}
|
|
@@ -5819,13 +6602,19 @@ var ResultProcessor = class {
|
|
|
5819
6602
|
continue;
|
|
5820
6603
|
}
|
|
5821
6604
|
const fieldDef = getField(this.schema, model, field);
|
|
5822
|
-
if (!fieldDef
|
|
6605
|
+
if (!fieldDef || !fieldDef.relation || !fieldDef.array) {
|
|
5823
6606
|
continue;
|
|
5824
6607
|
}
|
|
5825
6608
|
this.fixReversedResult(row[field], fieldDef.type, value);
|
|
5826
6609
|
}
|
|
5827
6610
|
}
|
|
5828
6611
|
}
|
|
6612
|
+
transformJson(value) {
|
|
6613
|
+
return (0, import_ts_pattern19.match)(this.schema.provider.type).with("sqlite", () => {
|
|
6614
|
+
(0, import_common_helpers12.invariant)(typeof value === "string", "Expected string, got " + typeof value);
|
|
6615
|
+
return JSON.parse(value);
|
|
6616
|
+
}).otherwise(() => value);
|
|
6617
|
+
}
|
|
5829
6618
|
};
|
|
5830
6619
|
|
|
5831
6620
|
// src/client/client-impl.ts
|
|
@@ -5844,7 +6633,7 @@ var ClientImpl = class _ClientImpl {
|
|
|
5844
6633
|
$schema;
|
|
5845
6634
|
kyselyProps;
|
|
5846
6635
|
auth;
|
|
5847
|
-
constructor(schema, options, baseClient) {
|
|
6636
|
+
constructor(schema, options, baseClient, executor) {
|
|
5848
6637
|
this.schema = schema;
|
|
5849
6638
|
this.options = options;
|
|
5850
6639
|
this.$schema = schema;
|
|
@@ -5856,24 +6645,23 @@ var ClientImpl = class _ClientImpl {
|
|
|
5856
6645
|
if (baseClient) {
|
|
5857
6646
|
this.kyselyProps = {
|
|
5858
6647
|
...baseClient.kyselyProps,
|
|
5859
|
-
executor: new ZenStackQueryExecutor(this, baseClient.kyselyProps.driver, baseClient.kyselyProps.dialect.createQueryCompiler(), baseClient.kyselyProps.dialect.createAdapter(), new import_kysely16.DefaultConnectionProvider(baseClient.kyselyProps.driver))
|
|
6648
|
+
executor: executor ?? new ZenStackQueryExecutor(this, baseClient.kyselyProps.driver, baseClient.kyselyProps.dialect.createQueryCompiler(), baseClient.kyselyProps.dialect.createAdapter(), new import_kysely16.DefaultConnectionProvider(baseClient.kyselyProps.driver))
|
|
5860
6649
|
};
|
|
5861
6650
|
this.kyselyRaw = baseClient.kyselyRaw;
|
|
6651
|
+
this.auth = baseClient.auth;
|
|
5862
6652
|
} else {
|
|
5863
|
-
const
|
|
5864
|
-
const
|
|
5865
|
-
const
|
|
5866
|
-
const adapter = dialect.createAdapter();
|
|
6653
|
+
const driver = new ZenStackDriver(options.dialect.createDriver(), new import_kysely16.Log(this.$options.log ?? []));
|
|
6654
|
+
const compiler = options.dialect.createQueryCompiler();
|
|
6655
|
+
const adapter = options.dialect.createAdapter();
|
|
5867
6656
|
const connectionProvider = new import_kysely16.DefaultConnectionProvider(driver);
|
|
5868
|
-
const executor = new ZenStackQueryExecutor(this, driver, compiler, adapter, connectionProvider);
|
|
5869
6657
|
this.kyselyProps = {
|
|
5870
6658
|
config: {
|
|
5871
|
-
dialect,
|
|
6659
|
+
dialect: options.dialect,
|
|
5872
6660
|
log: this.$options.log
|
|
5873
6661
|
},
|
|
5874
|
-
dialect,
|
|
6662
|
+
dialect: options.dialect,
|
|
5875
6663
|
driver,
|
|
5876
|
-
executor
|
|
6664
|
+
executor: executor ?? new ZenStackQueryExecutor(this, driver, compiler, adapter, connectionProvider)
|
|
5877
6665
|
};
|
|
5878
6666
|
this.kyselyRaw = new import_kysely16.Kysely({
|
|
5879
6667
|
...this.kyselyProps,
|
|
@@ -5889,31 +6677,58 @@ var ClientImpl = class _ClientImpl {
|
|
|
5889
6677
|
get $qbRaw() {
|
|
5890
6678
|
return this.kyselyRaw;
|
|
5891
6679
|
}
|
|
5892
|
-
|
|
5893
|
-
return
|
|
6680
|
+
get isTransaction() {
|
|
6681
|
+
return this.kysely.isTransaction;
|
|
5894
6682
|
}
|
|
5895
|
-
|
|
5896
|
-
|
|
5897
|
-
|
|
5898
|
-
|
|
5899
|
-
|
|
5900
|
-
};
|
|
5901
|
-
return new import_kysely16.PostgresDialect(mergedConfig);
|
|
6683
|
+
/**
|
|
6684
|
+
* Create a new client with a new query executor.
|
|
6685
|
+
*/
|
|
6686
|
+
withExecutor(executor) {
|
|
6687
|
+
return new _ClientImpl(this.schema, this.$options, this, executor);
|
|
5902
6688
|
}
|
|
5903
|
-
|
|
5904
|
-
|
|
5905
|
-
|
|
5906
|
-
|
|
5907
|
-
|
|
5908
|
-
}
|
|
5909
|
-
|
|
6689
|
+
// implementation
|
|
6690
|
+
async $transaction(input, options) {
|
|
6691
|
+
(0, import_common_helpers13.invariant)(typeof input === "function" || Array.isArray(input) && input.every((p) => p.then && p.cb), "Invalid transaction input, expected a function or an array of ZenStackPromise");
|
|
6692
|
+
if (typeof input === "function") {
|
|
6693
|
+
return this.interactiveTransaction(input, options);
|
|
6694
|
+
} else {
|
|
6695
|
+
return this.sequentialTransaction(input, options);
|
|
6696
|
+
}
|
|
6697
|
+
}
|
|
6698
|
+
async interactiveTransaction(callback, options) {
|
|
6699
|
+
if (this.kysely.isTransaction) {
|
|
6700
|
+
return callback(this);
|
|
6701
|
+
} else {
|
|
6702
|
+
let txBuilder = this.kysely.transaction();
|
|
6703
|
+
if (options?.isolationLevel) {
|
|
6704
|
+
txBuilder = txBuilder.setIsolationLevel(options.isolationLevel);
|
|
6705
|
+
}
|
|
6706
|
+
return txBuilder.execute((tx) => {
|
|
6707
|
+
const txClient = new _ClientImpl(this.schema, this.$options, this);
|
|
6708
|
+
txClient.kysely = tx;
|
|
6709
|
+
return callback(txClient);
|
|
6710
|
+
});
|
|
6711
|
+
}
|
|
5910
6712
|
}
|
|
5911
|
-
async
|
|
5912
|
-
|
|
5913
|
-
const txClient = new _ClientImpl(this.schema, this.$options);
|
|
6713
|
+
async sequentialTransaction(arg, options) {
|
|
6714
|
+
const execute = /* @__PURE__ */ __name(async (tx) => {
|
|
6715
|
+
const txClient = new _ClientImpl(this.schema, this.$options, this);
|
|
5914
6716
|
txClient.kysely = tx;
|
|
5915
|
-
|
|
5916
|
-
|
|
6717
|
+
const result = [];
|
|
6718
|
+
for (const promise of arg) {
|
|
6719
|
+
result.push(await promise.cb(txClient));
|
|
6720
|
+
}
|
|
6721
|
+
return result;
|
|
6722
|
+
}, "execute");
|
|
6723
|
+
if (this.kysely.isTransaction) {
|
|
6724
|
+
return execute(this.kysely);
|
|
6725
|
+
} else {
|
|
6726
|
+
let txBuilder = this.kysely.transaction();
|
|
6727
|
+
if (options?.isolationLevel) {
|
|
6728
|
+
txBuilder = txBuilder.setIsolationLevel(options.isolationLevel);
|
|
6729
|
+
}
|
|
6730
|
+
return txBuilder.execute((tx) => execute(tx));
|
|
6731
|
+
}
|
|
5917
6732
|
}
|
|
5918
6733
|
get $procedures() {
|
|
5919
6734
|
return Object.keys(this.$schema.procedures ?? {}).reduce((acc, name) => {
|
|
@@ -5941,12 +6756,26 @@ var ClientImpl = class _ClientImpl {
|
|
|
5941
6756
|
await new SchemaDbPusher(this.schema, this.kysely).push();
|
|
5942
6757
|
}
|
|
5943
6758
|
$use(plugin) {
|
|
6759
|
+
const newPlugins = [
|
|
6760
|
+
...this.$options.plugins ?? [],
|
|
6761
|
+
plugin
|
|
6762
|
+
];
|
|
5944
6763
|
const newOptions = {
|
|
5945
6764
|
...this.options,
|
|
5946
|
-
plugins:
|
|
5947
|
-
|
|
5948
|
-
|
|
5949
|
-
|
|
6765
|
+
plugins: newPlugins
|
|
6766
|
+
};
|
|
6767
|
+
return new _ClientImpl(this.schema, newOptions, this);
|
|
6768
|
+
}
|
|
6769
|
+
$unuse(pluginId) {
|
|
6770
|
+
const newPlugins = [];
|
|
6771
|
+
for (const plugin of this.options.plugins ?? []) {
|
|
6772
|
+
if (plugin.id !== pluginId) {
|
|
6773
|
+
newPlugins.push(plugin);
|
|
6774
|
+
}
|
|
6775
|
+
}
|
|
6776
|
+
const newOptions = {
|
|
6777
|
+
...this.options,
|
|
6778
|
+
plugins: newPlugins
|
|
5950
6779
|
};
|
|
5951
6780
|
return new _ClientImpl(this.schema, newOptions, this);
|
|
5952
6781
|
}
|
|
@@ -5968,6 +6797,39 @@ var ClientImpl = class _ClientImpl {
|
|
|
5968
6797
|
get $auth() {
|
|
5969
6798
|
return this.auth;
|
|
5970
6799
|
}
|
|
6800
|
+
$executeRaw(query, ...values) {
|
|
6801
|
+
return createZenStackPromise(async () => {
|
|
6802
|
+
const result = await (0, import_kysely16.sql)(query, ...values).execute(this.kysely);
|
|
6803
|
+
return Number(result.numAffectedRows ?? 0);
|
|
6804
|
+
});
|
|
6805
|
+
}
|
|
6806
|
+
$executeRawUnsafe(query, ...values) {
|
|
6807
|
+
return createZenStackPromise(async () => {
|
|
6808
|
+
const compiledQuery = this.createRawCompiledQuery(query, values);
|
|
6809
|
+
const result = await this.kysely.executeQuery(compiledQuery);
|
|
6810
|
+
return Number(result.numAffectedRows ?? 0);
|
|
6811
|
+
});
|
|
6812
|
+
}
|
|
6813
|
+
$queryRaw(query, ...values) {
|
|
6814
|
+
return createZenStackPromise(async () => {
|
|
6815
|
+
const result = await (0, import_kysely16.sql)(query, ...values).execute(this.kysely);
|
|
6816
|
+
return result.rows;
|
|
6817
|
+
});
|
|
6818
|
+
}
|
|
6819
|
+
$queryRawUnsafe(query, ...values) {
|
|
6820
|
+
return createZenStackPromise(async () => {
|
|
6821
|
+
const compiledQuery = this.createRawCompiledQuery(query, values);
|
|
6822
|
+
const result = await this.kysely.executeQuery(compiledQuery);
|
|
6823
|
+
return result.rows;
|
|
6824
|
+
});
|
|
6825
|
+
}
|
|
6826
|
+
createRawCompiledQuery(query, values) {
|
|
6827
|
+
const q = import_kysely16.CompiledQuery.raw(query, values);
|
|
6828
|
+
return {
|
|
6829
|
+
...q,
|
|
6830
|
+
$raw: true
|
|
6831
|
+
};
|
|
6832
|
+
}
|
|
5971
6833
|
};
|
|
5972
6834
|
function createClientProxy(client) {
|
|
5973
6835
|
const inputValidator = new InputValidator(client.$schema);
|
|
@@ -5990,9 +6852,9 @@ function createClientProxy(client) {
|
|
|
5990
6852
|
__name(createClientProxy, "createClientProxy");
|
|
5991
6853
|
function createModelCrudHandler(client, model, inputValidator, resultProcessor) {
|
|
5992
6854
|
const createPromise = /* @__PURE__ */ __name((operation, args, handler, postProcess = false, throwIfNoResult = false) => {
|
|
5993
|
-
return
|
|
5994
|
-
let proceed = /* @__PURE__ */ __name(async (_args
|
|
5995
|
-
const _handler =
|
|
6855
|
+
return createZenStackPromise(async (txClient) => {
|
|
6856
|
+
let proceed = /* @__PURE__ */ __name(async (_args) => {
|
|
6857
|
+
const _handler = txClient ? handler.withClient(txClient) : handler;
|
|
5996
6858
|
const r = await _handler.handle(operation, _args ?? args);
|
|
5997
6859
|
if (!r && throwIfNoResult) {
|
|
5998
6860
|
throw new NotFoundError(model);
|
|
@@ -6005,22 +6867,31 @@ function createModelCrudHandler(client, model, inputValidator, resultProcessor)
|
|
|
6005
6867
|
}
|
|
6006
6868
|
return result;
|
|
6007
6869
|
}, "proceed");
|
|
6008
|
-
const context = {
|
|
6009
|
-
client,
|
|
6010
|
-
model,
|
|
6011
|
-
operation,
|
|
6012
|
-
queryArgs: args
|
|
6013
|
-
};
|
|
6014
6870
|
const plugins = [
|
|
6015
6871
|
...client.$options.plugins ?? []
|
|
6016
6872
|
];
|
|
6017
6873
|
for (const plugin of plugins) {
|
|
6018
|
-
if (plugin.onQuery) {
|
|
6019
|
-
const
|
|
6020
|
-
|
|
6021
|
-
|
|
6022
|
-
|
|
6023
|
-
|
|
6874
|
+
if (plugin.onQuery && typeof plugin.onQuery === "object") {
|
|
6875
|
+
for (const [_model, modelHooks] of Object.entries(plugin.onQuery)) {
|
|
6876
|
+
if (_model === (0, import_common_helpers13.lowerCaseFirst)(model) || _model === "$allModels") {
|
|
6877
|
+
if (modelHooks && typeof modelHooks === "object") {
|
|
6878
|
+
for (const [op, opHooks] of Object.entries(modelHooks)) {
|
|
6879
|
+
if (op === operation || op === "$allOperations") {
|
|
6880
|
+
if (typeof opHooks === "function") {
|
|
6881
|
+
const _proceed = proceed;
|
|
6882
|
+
proceed = /* @__PURE__ */ __name(() => opHooks({
|
|
6883
|
+
client,
|
|
6884
|
+
model,
|
|
6885
|
+
operation,
|
|
6886
|
+
args,
|
|
6887
|
+
query: _proceed
|
|
6888
|
+
}), "proceed");
|
|
6889
|
+
}
|
|
6890
|
+
}
|
|
6891
|
+
}
|
|
6892
|
+
}
|
|
6893
|
+
}
|
|
6894
|
+
}
|
|
6024
6895
|
}
|
|
6025
6896
|
}
|
|
6026
6897
|
return proceed(args);
|
|
@@ -6076,13 +6947,24 @@ function createModelCrudHandler(client, model, inputValidator, resultProcessor)
|
|
|
6076
6947
|
return createPromise("aggregate", args, new AggregateOperationHandler(client, model, inputValidator), false);
|
|
6077
6948
|
}, "aggregate"),
|
|
6078
6949
|
groupBy: /* @__PURE__ */ __name((args) => {
|
|
6079
|
-
return createPromise("groupBy", args, new
|
|
6950
|
+
return createPromise("groupBy", args, new GroupByOperationHandler(client, model, inputValidator), true);
|
|
6080
6951
|
}, "groupBy")
|
|
6081
6952
|
};
|
|
6082
6953
|
}
|
|
6083
6954
|
__name(createModelCrudHandler, "createModelCrudHandler");
|
|
6955
|
+
|
|
6956
|
+
// src/client/plugin.ts
|
|
6957
|
+
function definePlugin(plugin) {
|
|
6958
|
+
return plugin;
|
|
6959
|
+
}
|
|
6960
|
+
__name(definePlugin, "definePlugin");
|
|
6084
6961
|
// Annotate the CommonJS export names for ESM import in node:
|
|
6085
6962
|
0 && (module.exports = {
|
|
6086
|
-
|
|
6963
|
+
InputValidationError,
|
|
6964
|
+
InternalError,
|
|
6965
|
+
NotFoundError,
|
|
6966
|
+
QueryError,
|
|
6967
|
+
ZenStackClient,
|
|
6968
|
+
definePlugin
|
|
6087
6969
|
});
|
|
6088
6970
|
//# sourceMappingURL=index.cjs.map
|