@zenstackhq/runtime 3.0.0-alpha.0 → 3.0.0-alpha.10
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-BiU0iYAh.d.cts} +813 -709
- package/dist/{contract-DguafRNB.d.ts → contract-BiU0iYAh.d.ts} +813 -709
- 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 +517 -328
- 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 +466 -282
- package/dist/index.js.map +1 -1
- package/dist/plugins/policy.cjs +115 -104
- package/dist/plugins/policy.cjs.map +1 -1
- package/dist/plugins/policy.d.cts +2 -4
- package/dist/plugins/policy.d.ts +2 -4
- package/dist/plugins/policy.js +87 -66
- package/dist/plugins/policy.js.map +1 -1
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.js.map +1 -1
- package/package.json +23 -46
- 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/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.js
CHANGED
|
@@ -6,7 +6,8 @@ var __export = (target, all) => {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// src/client/client-impl.ts
|
|
9
|
-
import {
|
|
9
|
+
import { invariant as invariant12, lowerCaseFirst as lowerCaseFirst2 } from "@zenstackhq/common-helpers";
|
|
10
|
+
import { CompiledQuery, DefaultConnectionProvider, DefaultQueryExecutor as DefaultQueryExecutor2, Kysely, Log, PostgresDialect, sql as sql10, SqliteDialect } from "kysely";
|
|
10
11
|
import { match as match19 } from "ts-pattern";
|
|
11
12
|
|
|
12
13
|
// src/client/crud/operations/aggregate.ts
|
|
@@ -14,21 +15,30 @@ import { sql as sql5 } from "kysely";
|
|
|
14
15
|
import { match as match9 } from "ts-pattern";
|
|
15
16
|
|
|
16
17
|
// src/client/errors.ts
|
|
18
|
+
var InputValidationError = class extends Error {
|
|
19
|
+
static {
|
|
20
|
+
__name(this, "InputValidationError");
|
|
21
|
+
}
|
|
22
|
+
constructor(message, cause) {
|
|
23
|
+
super(message, {
|
|
24
|
+
cause
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
};
|
|
17
28
|
var QueryError = class extends Error {
|
|
18
29
|
static {
|
|
19
30
|
__name(this, "QueryError");
|
|
20
31
|
}
|
|
21
|
-
constructor(message) {
|
|
22
|
-
super(message
|
|
32
|
+
constructor(message, cause) {
|
|
33
|
+
super(message, {
|
|
34
|
+
cause
|
|
35
|
+
});
|
|
23
36
|
}
|
|
24
37
|
};
|
|
25
38
|
var InternalError = class extends Error {
|
|
26
39
|
static {
|
|
27
40
|
__name(this, "InternalError");
|
|
28
41
|
}
|
|
29
|
-
constructor(message) {
|
|
30
|
-
super(message);
|
|
31
|
-
}
|
|
32
42
|
};
|
|
33
43
|
var NotFoundError = class extends Error {
|
|
34
44
|
static {
|
|
@@ -47,7 +57,7 @@ __name(getModel, "getModel");
|
|
|
47
57
|
function requireModel(schema, model) {
|
|
48
58
|
const matchedName = Object.keys(schema.models).find((k) => k.toLowerCase() === model.toLowerCase());
|
|
49
59
|
if (!matchedName) {
|
|
50
|
-
throw new QueryError(`Model "${model}" not found`);
|
|
60
|
+
throw new QueryError(`Model "${model}" not found in schema`);
|
|
51
61
|
}
|
|
52
62
|
return schema.models[matchedName];
|
|
53
63
|
}
|
|
@@ -172,7 +182,7 @@ function buildFieldRef(schema, model, field, options, eb, modelAlias) {
|
|
|
172
182
|
computer = computedFields?.[model]?.[field];
|
|
173
183
|
}
|
|
174
184
|
if (!computer) {
|
|
175
|
-
throw new QueryError(`Computed field "${field}" implementation not provided`);
|
|
185
|
+
throw new QueryError(`Computed field "${field}" implementation not provided for model "${model}"`);
|
|
176
186
|
}
|
|
177
187
|
return computer(eb);
|
|
178
188
|
}
|
|
@@ -280,9 +290,10 @@ __name(safeJSONStringify, "safeJSONStringify");
|
|
|
280
290
|
|
|
281
291
|
// src/client/crud/operations/base.ts
|
|
282
292
|
import { createId } from "@paralleldrive/cuid2";
|
|
293
|
+
import { invariant as invariant7, isPlainObject as isPlainObject3 } from "@zenstackhq/common-helpers";
|
|
283
294
|
import { expressionBuilder as expressionBuilder2, sql as sql4 } from "kysely";
|
|
284
295
|
import { nanoid } from "nanoid";
|
|
285
|
-
import
|
|
296
|
+
import { inspect } from "util";
|
|
286
297
|
import { match as match8 } from "ts-pattern";
|
|
287
298
|
import { ulid } from "ulid";
|
|
288
299
|
import * as uuid from "uuid";
|
|
@@ -300,21 +311,21 @@ var RejectedByPolicyError = class extends Error {
|
|
|
300
311
|
};
|
|
301
312
|
|
|
302
313
|
// src/plugins/policy/policy-handler.ts
|
|
314
|
+
import { invariant as invariant6 } from "@zenstackhq/common-helpers";
|
|
303
315
|
import { AliasNode as AliasNode3, BinaryOperationNode as BinaryOperationNode3, ColumnNode as ColumnNode2, DeleteQueryNode, FromNode as FromNode2, IdentifierNode as IdentifierNode2, InsertQueryNode, OperationNodeTransformer, OperatorNode as OperatorNode3, PrimitiveValueListNode, RawNode, ReturningNode, SelectionNode as SelectionNode2, SelectQueryNode as SelectQueryNode2, TableNode as TableNode3, UpdateQueryNode, ValueNode as ValueNode3, ValuesNode, WhereNode as WhereNode2 } from "kysely";
|
|
304
|
-
import invariant6 from "tiny-invariant";
|
|
305
316
|
import { match as match7 } from "ts-pattern";
|
|
306
317
|
|
|
307
318
|
// src/client/crud/dialects/index.ts
|
|
308
319
|
import { match as match4 } from "ts-pattern";
|
|
309
320
|
|
|
310
321
|
// src/client/crud/dialects/postgresql.ts
|
|
322
|
+
import { invariant as invariant2 } from "@zenstackhq/common-helpers";
|
|
311
323
|
import { sql as sql2 } from "kysely";
|
|
312
|
-
import invariant2 from "tiny-invariant";
|
|
313
324
|
import { match as match2 } from "ts-pattern";
|
|
314
325
|
|
|
315
326
|
// src/client/crud/dialects/base.ts
|
|
327
|
+
import { invariant, isPlainObject } from "@zenstackhq/common-helpers";
|
|
316
328
|
import { sql } from "kysely";
|
|
317
|
-
import invariant from "tiny-invariant";
|
|
318
329
|
import { match, P } from "ts-pattern";
|
|
319
330
|
|
|
320
331
|
// src/utils/enumerate.ts
|
|
@@ -332,7 +343,6 @@ function enumerate(x) {
|
|
|
332
343
|
__name(enumerate, "enumerate");
|
|
333
344
|
|
|
334
345
|
// src/client/crud/dialects/base.ts
|
|
335
|
-
import { isPlainObject } from "is-plain-object";
|
|
336
346
|
var BaseCrudDialect = class {
|
|
337
347
|
static {
|
|
338
348
|
__name(this, "BaseCrudDialect");
|
|
@@ -343,7 +353,7 @@ var BaseCrudDialect = class {
|
|
|
343
353
|
this.schema = schema;
|
|
344
354
|
this.options = options;
|
|
345
355
|
}
|
|
346
|
-
transformPrimitive(value, _type) {
|
|
356
|
+
transformPrimitive(value, _type, _forArrayField) {
|
|
347
357
|
return value;
|
|
348
358
|
}
|
|
349
359
|
buildFilter(eb, model, modelAlias, where) {
|
|
@@ -486,7 +496,7 @@ var BaseCrudDialect = class {
|
|
|
486
496
|
if (_value === void 0) {
|
|
487
497
|
continue;
|
|
488
498
|
}
|
|
489
|
-
const value = this.transformPrimitive(_value, fieldType);
|
|
499
|
+
const value = this.transformPrimitive(_value, fieldType, !!fieldDef.array);
|
|
490
500
|
switch (key) {
|
|
491
501
|
case "equals": {
|
|
492
502
|
clauses.push(this.buildLiteralFilter(eb, fieldRef, fieldType, eb.val(value)));
|
|
@@ -524,10 +534,14 @@ var BaseCrudDialect = class {
|
|
|
524
534
|
if (isEnum(this.schema, fieldDef.type)) {
|
|
525
535
|
return this.buildEnumFilter(eb, modelAlias, field, fieldDef, payload);
|
|
526
536
|
}
|
|
527
|
-
return match(fieldDef.type).with("String", () => this.buildStringFilter(eb, modelAlias, field, payload)).with(P.union("Int", "Float", "Decimal", "BigInt"), (type) => this.buildNumberFilter(eb, model, modelAlias, field, type, payload)).with("Boolean", () => this.buildBooleanFilter(eb, modelAlias, field, payload)).with("DateTime", () => this.buildDateTimeFilter(eb, modelAlias, field, payload)).with("Bytes", () => this.buildBytesFilter(eb, modelAlias, field, payload)).
|
|
537
|
+
return match(fieldDef.type).with("String", () => this.buildStringFilter(eb, modelAlias, field, payload)).with(P.union("Int", "Float", "Decimal", "BigInt"), (type) => this.buildNumberFilter(eb, model, modelAlias, field, type, payload)).with("Boolean", () => this.buildBooleanFilter(eb, modelAlias, field, payload)).with("DateTime", () => this.buildDateTimeFilter(eb, modelAlias, field, payload)).with("Bytes", () => this.buildBytesFilter(eb, modelAlias, field, payload)).with("Json", () => {
|
|
538
|
+
throw new InternalError("JSON filters are not supported yet");
|
|
539
|
+
}).with("Unsupported", () => {
|
|
540
|
+
throw new QueryError(`Unsupported field cannot be used in filters`);
|
|
541
|
+
}).exhaustive();
|
|
528
542
|
}
|
|
529
543
|
buildLiteralFilter(eb, lhs, type, rhs) {
|
|
530
|
-
return eb(lhs, "=", rhs !== null && rhs !== void 0 ? this.transformPrimitive(rhs, type) : rhs);
|
|
544
|
+
return eb(lhs, "=", rhs !== null && rhs !== void 0 ? this.transformPrimitive(rhs, type, false) : rhs);
|
|
531
545
|
}
|
|
532
546
|
buildStandardFilter(eb, type, payload, lhs, getRhs, recurse, throwIfInvalid = false, onlyForKeys = void 0) {
|
|
533
547
|
if (payload === null || !isPlainObject(payload)) {
|
|
@@ -614,22 +628,22 @@ var BaseCrudDialect = class {
|
|
|
614
628
|
}
|
|
615
629
|
}
|
|
616
630
|
buildNumberFilter(eb, model, table, field, type, payload) {
|
|
617
|
-
const { conditions } = this.buildStandardFilter(eb, type, payload, buildFieldRef(this.schema, model, field, this.options, eb), (value) => this.transformPrimitive(value, type), (value) => this.buildNumberFilter(eb, model, table, field, type, value));
|
|
631
|
+
const { conditions } = this.buildStandardFilter(eb, type, payload, buildFieldRef(this.schema, model, field, this.options, eb), (value) => this.transformPrimitive(value, type, false), (value) => this.buildNumberFilter(eb, model, table, field, type, value));
|
|
618
632
|
return this.and(eb, ...conditions);
|
|
619
633
|
}
|
|
620
634
|
buildBooleanFilter(eb, table, field, payload) {
|
|
621
|
-
const { conditions } = this.buildStandardFilter(eb, "Boolean", payload, sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "Boolean"), (value) => this.buildBooleanFilter(eb, table, field, value), true, [
|
|
635
|
+
const { conditions } = this.buildStandardFilter(eb, "Boolean", payload, sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "Boolean", false), (value) => this.buildBooleanFilter(eb, table, field, value), true, [
|
|
622
636
|
"equals",
|
|
623
637
|
"not"
|
|
624
638
|
]);
|
|
625
639
|
return this.and(eb, ...conditions);
|
|
626
640
|
}
|
|
627
641
|
buildDateTimeFilter(eb, table, field, payload) {
|
|
628
|
-
const { conditions } = this.buildStandardFilter(eb, "DateTime", payload, sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "DateTime"), (value) => this.buildDateTimeFilter(eb, table, field, value), true);
|
|
642
|
+
const { conditions } = this.buildStandardFilter(eb, "DateTime", payload, sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "DateTime", false), (value) => this.buildDateTimeFilter(eb, table, field, value), true);
|
|
629
643
|
return this.and(eb, ...conditions);
|
|
630
644
|
}
|
|
631
645
|
buildBytesFilter(eb, table, field, payload) {
|
|
632
|
-
const conditions = this.buildStandardFilter(eb, "Bytes", payload, sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "Bytes"), (value) => this.buildBytesFilter(eb, table, field, value), true, [
|
|
646
|
+
const conditions = this.buildStandardFilter(eb, "Bytes", payload, sql.ref(`${table}.${field}`), (value) => this.transformPrimitive(value, "Bytes", false), (value) => this.buildBytesFilter(eb, table, field, value), true, [
|
|
633
647
|
"equals",
|
|
634
648
|
"in",
|
|
635
649
|
"notIn",
|
|
@@ -728,10 +742,10 @@ var BaseCrudDialect = class {
|
|
|
728
742
|
return negated ? sort === "asc" ? "desc" : "asc" : sort;
|
|
729
743
|
}
|
|
730
744
|
true(eb) {
|
|
731
|
-
return eb.lit(this.transformPrimitive(true, "Boolean"));
|
|
745
|
+
return eb.lit(this.transformPrimitive(true, "Boolean", false));
|
|
732
746
|
}
|
|
733
747
|
false(eb) {
|
|
734
|
-
return eb.lit(this.transformPrimitive(false, "Boolean"));
|
|
748
|
+
return eb.lit(this.transformPrimitive(false, "Boolean", false));
|
|
735
749
|
}
|
|
736
750
|
isTrue(expression) {
|
|
737
751
|
const node = expression.toOperationNode();
|
|
@@ -780,14 +794,18 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
780
794
|
get provider() {
|
|
781
795
|
return "postgresql";
|
|
782
796
|
}
|
|
783
|
-
transformPrimitive(value, type) {
|
|
797
|
+
transformPrimitive(value, type, forArrayField) {
|
|
784
798
|
if (value === void 0) {
|
|
785
799
|
return value;
|
|
786
800
|
}
|
|
787
801
|
if (Array.isArray(value)) {
|
|
788
|
-
|
|
802
|
+
if (type === "Json" && !forArrayField) {
|
|
803
|
+
return JSON.stringify(value);
|
|
804
|
+
} else {
|
|
805
|
+
return value.map((v) => this.transformPrimitive(v, type, false));
|
|
806
|
+
}
|
|
789
807
|
} else {
|
|
790
|
-
return match2(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).otherwise(() => value);
|
|
808
|
+
return match2(type).with("DateTime", () => value instanceof Date ? value : typeof value === "string" ? new Date(value) : value).with("Decimal", () => value !== null ? value.toString() : value).otherwise(() => value);
|
|
791
809
|
}
|
|
792
810
|
}
|
|
793
811
|
buildRelationSelection(query, model, relationField, parentAlias, payload) {
|
|
@@ -854,25 +872,33 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
854
872
|
buildFieldRef(this.schema, relationModel, field, this.options, eb)
|
|
855
873
|
]).flatMap((v) => v));
|
|
856
874
|
} else if (payload.select) {
|
|
857
|
-
objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field]) =>
|
|
858
|
-
|
|
859
|
-
buildFieldRef(this.schema, relationModel, field, this.options, eb)
|
|
860
|
-
|
|
875
|
+
objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field]) => {
|
|
876
|
+
const fieldDef = requireField(this.schema, relationModel, field);
|
|
877
|
+
const fieldValue = fieldDef.relation ? eb.ref(`${parentName}$${relationField}$${field}.$j`) : buildFieldRef(this.schema, relationModel, field, this.options, eb);
|
|
878
|
+
return [
|
|
879
|
+
sql2.lit(field),
|
|
880
|
+
fieldValue
|
|
881
|
+
];
|
|
882
|
+
}).flatMap((v) => v));
|
|
861
883
|
}
|
|
862
884
|
if (typeof payload === "object" && payload.include && typeof payload.include === "object") {
|
|
863
885
|
objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field]) => [
|
|
864
886
|
sql2.lit(field),
|
|
887
|
+
// reference the synthesized JSON field
|
|
865
888
|
eb.ref(`${parentName}$${relationField}$${field}.$j`)
|
|
866
889
|
]).flatMap((v) => v));
|
|
867
890
|
}
|
|
868
891
|
return objArgs;
|
|
869
892
|
}
|
|
870
|
-
buildRelationJoins(
|
|
893
|
+
buildRelationJoins(relationModel, relationField, qb, payload, parentName) {
|
|
871
894
|
let result = qb;
|
|
872
|
-
if (typeof payload === "object"
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
895
|
+
if (typeof payload === "object") {
|
|
896
|
+
const selectInclude = payload.include ?? payload.select;
|
|
897
|
+
if (selectInclude && typeof selectInclude === "object") {
|
|
898
|
+
Object.entries(selectInclude).filter(([, value]) => value).filter(([field]) => isRelationField(this.schema, relationModel, field)).forEach(([field, value]) => {
|
|
899
|
+
result = this.buildRelationJSON(relationModel, result, field, `${parentName}$${relationField}`, value);
|
|
900
|
+
});
|
|
901
|
+
}
|
|
876
902
|
}
|
|
877
903
|
return result;
|
|
878
904
|
}
|
|
@@ -915,8 +941,8 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
915
941
|
};
|
|
916
942
|
|
|
917
943
|
// src/client/crud/dialects/sqlite.ts
|
|
944
|
+
import { invariant as invariant3 } from "@zenstackhq/common-helpers";
|
|
918
945
|
import { sql as sql3 } from "kysely";
|
|
919
|
-
import invariant3 from "tiny-invariant";
|
|
920
946
|
import { match as match3 } from "ts-pattern";
|
|
921
947
|
var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
922
948
|
static {
|
|
@@ -925,14 +951,14 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
925
951
|
get provider() {
|
|
926
952
|
return "sqlite";
|
|
927
953
|
}
|
|
928
|
-
transformPrimitive(value, type) {
|
|
954
|
+
transformPrimitive(value, type, _forArrayField) {
|
|
929
955
|
if (value === void 0) {
|
|
930
956
|
return value;
|
|
931
957
|
}
|
|
932
958
|
if (Array.isArray(value)) {
|
|
933
|
-
return value.map((v) => this.transformPrimitive(v, type));
|
|
959
|
+
return value.map((v) => this.transformPrimitive(v, type, false));
|
|
934
960
|
} else {
|
|
935
|
-
return match3(type).with("Boolean", () => value ? 1 : 0).with("DateTime", () => value instanceof Date ? value.toISOString() : value).with("Decimal", () => value.toString()).with("Bytes", () => Buffer.from(value)).otherwise(() => value);
|
|
961
|
+
return match3(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);
|
|
936
962
|
}
|
|
937
963
|
}
|
|
938
964
|
buildRelationSelection(query, model, relationField, parentAlias, payload) {
|
|
@@ -1460,12 +1486,12 @@ var ColumnCollector = class extends DefaultOperationNodeVisitor {
|
|
|
1460
1486
|
};
|
|
1461
1487
|
|
|
1462
1488
|
// src/plugins/policy/expression-transformer.ts
|
|
1489
|
+
import { invariant as invariant5 } from "@zenstackhq/common-helpers";
|
|
1463
1490
|
import { AliasNode as AliasNode2, BinaryOperationNode as BinaryOperationNode2, ColumnNode, expressionBuilder, FromNode, FunctionNode as FunctionNode2, IdentifierNode, OperatorNode as OperatorNode2, ReferenceNode as ReferenceNode2, SelectionNode, SelectQueryNode, TableNode as TableNode2, ValueListNode, ValueNode as ValueNode2, WhereNode } from "kysely";
|
|
1464
|
-
import invariant5 from "tiny-invariant";
|
|
1465
1491
|
import { match as match6 } from "ts-pattern";
|
|
1466
1492
|
|
|
1467
1493
|
// src/plugins/policy/expression-evaluator.ts
|
|
1468
|
-
import invariant4 from "
|
|
1494
|
+
import { invariant as invariant4 } from "@zenstackhq/common-helpers";
|
|
1469
1495
|
import { match as match5 } from "ts-pattern";
|
|
1470
1496
|
var ExpressionEvaluator = class {
|
|
1471
1497
|
static {
|
|
@@ -1537,11 +1563,11 @@ var ExpressionEvaluator = class {
|
|
|
1537
1563
|
// src/plugins/policy/utils.ts
|
|
1538
1564
|
import { AliasNode, AndNode, BinaryOperationNode, FunctionNode, OperatorNode, OrNode, ParensNode, ReferenceNode, TableNode, UnaryOperationNode, ValueNode } from "kysely";
|
|
1539
1565
|
function trueNode(dialect) {
|
|
1540
|
-
return ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean"));
|
|
1566
|
+
return ValueNode.createImmediate(dialect.transformPrimitive(true, "Boolean", false));
|
|
1541
1567
|
}
|
|
1542
1568
|
__name(trueNode, "trueNode");
|
|
1543
1569
|
function falseNode(dialect) {
|
|
1544
|
-
return ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean"));
|
|
1570
|
+
return ValueNode.createImmediate(dialect.transformPrimitive(false, "Boolean", false));
|
|
1545
1571
|
}
|
|
1546
1572
|
__name(falseNode, "falseNode");
|
|
1547
1573
|
function isTrueNode(node) {
|
|
@@ -1799,7 +1825,7 @@ var ExpressionTransformer = class {
|
|
|
1799
1825
|
}
|
|
1800
1826
|
}
|
|
1801
1827
|
transformValue(value, type) {
|
|
1802
|
-
return ValueNode2.create(this.dialect.transformPrimitive(value, type) ?? null);
|
|
1828
|
+
return ValueNode2.create(this.dialect.transformPrimitive(value, type, false) ?? null);
|
|
1803
1829
|
}
|
|
1804
1830
|
_unary(expr2, context) {
|
|
1805
1831
|
invariant5(expr2.op === "!", 'only "!" operator is supported');
|
|
@@ -2042,7 +2068,7 @@ var PolicyHandler = class extends OperationNodeTransformer {
|
|
|
2042
2068
|
get kysely() {
|
|
2043
2069
|
return this.client.$qb;
|
|
2044
2070
|
}
|
|
2045
|
-
async handle(node, proceed
|
|
2071
|
+
async handle(node, proceed) {
|
|
2046
2072
|
if (!this.isCrudQueryNode(node)) {
|
|
2047
2073
|
throw new RejectedByPolicyError(void 0, "non-CRUD queries are not allowed");
|
|
2048
2074
|
}
|
|
@@ -2062,27 +2088,20 @@ var PolicyHandler = class extends OperationNodeTransformer {
|
|
|
2062
2088
|
if (!mutationRequiresTransaction && !node.returning) {
|
|
2063
2089
|
return proceed(this.transformNode(node));
|
|
2064
2090
|
}
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
const
|
|
2072
|
-
if (
|
|
2073
|
-
|
|
2074
|
-
if (readBackResult.rows.length !== result2.rows.length) {
|
|
2075
|
-
readBackError = true;
|
|
2076
|
-
}
|
|
2077
|
-
return readBackResult;
|
|
2078
|
-
} else {
|
|
2079
|
-
return result2;
|
|
2091
|
+
if (InsertQueryNode.is(node)) {
|
|
2092
|
+
await this.enforcePreCreatePolicy(node, proceed);
|
|
2093
|
+
}
|
|
2094
|
+
const transformedNode = this.transformNode(node);
|
|
2095
|
+
const result = await proceed(transformedNode);
|
|
2096
|
+
if (!this.onlyReturningId(node)) {
|
|
2097
|
+
const readBackResult = await this.processReadBack(node, result, proceed);
|
|
2098
|
+
if (readBackResult.rows.length !== result.rows.length) {
|
|
2099
|
+
throw new RejectedByPolicyError(mutationModel, "result is not allowed to be read back");
|
|
2080
2100
|
}
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2101
|
+
return readBackResult;
|
|
2102
|
+
} else {
|
|
2103
|
+
return result;
|
|
2084
2104
|
}
|
|
2085
|
-
return result;
|
|
2086
2105
|
}
|
|
2087
2106
|
onlyReturningId(node) {
|
|
2088
2107
|
if (!node.returning) {
|
|
@@ -2143,11 +2162,11 @@ var PolicyHandler = class extends OperationNodeTransformer {
|
|
|
2143
2162
|
if (typeof item === "object" && item && "kind" in item) {
|
|
2144
2163
|
invariant6(item.kind === "ValueNode", "expecting a ValueNode");
|
|
2145
2164
|
result.push({
|
|
2146
|
-
node: ValueNode3.create(this.dialect.transformPrimitive(item.value, fieldDef.type)),
|
|
2165
|
+
node: ValueNode3.create(this.dialect.transformPrimitive(item.value, fieldDef.type, !!fieldDef.array)),
|
|
2147
2166
|
raw: item.value
|
|
2148
2167
|
});
|
|
2149
2168
|
} else {
|
|
2150
|
-
const value = this.dialect.transformPrimitive(item, fieldDef.type);
|
|
2169
|
+
const value = this.dialect.transformPrimitive(item, fieldDef.type, !!fieldDef.array);
|
|
2151
2170
|
if (Array.isArray(value)) {
|
|
2152
2171
|
result.push({
|
|
2153
2172
|
node: RawNode.createWithSql(this.dialect.buildArrayLiteralSQL(value)),
|
|
@@ -2378,14 +2397,23 @@ var PolicyPlugin = class {
|
|
|
2378
2397
|
get description() {
|
|
2379
2398
|
return "Enforces access policies defined in the schema.";
|
|
2380
2399
|
}
|
|
2381
|
-
onKyselyQuery({
|
|
2400
|
+
onKyselyQuery({
|
|
2401
|
+
query,
|
|
2402
|
+
client,
|
|
2403
|
+
proceed
|
|
2404
|
+
/*, transaction*/
|
|
2405
|
+
}) {
|
|
2382
2406
|
const handler = new PolicyHandler(client);
|
|
2383
|
-
return handler.handle(
|
|
2407
|
+
return handler.handle(
|
|
2408
|
+
query,
|
|
2409
|
+
proceed
|
|
2410
|
+
/*, transaction*/
|
|
2411
|
+
);
|
|
2384
2412
|
}
|
|
2385
2413
|
};
|
|
2386
2414
|
|
|
2387
2415
|
// src/utils/clone.ts
|
|
2388
|
-
import { isPlainObject as isPlainObject2 } from "
|
|
2416
|
+
import { isPlainObject as isPlainObject2 } from "@zenstackhq/common-helpers";
|
|
2389
2417
|
function clone(value) {
|
|
2390
2418
|
if (Array.isArray(value)) {
|
|
2391
2419
|
return value.map((v) => clone(v));
|
|
@@ -2520,8 +2548,13 @@ var BaseOperationHandler = class {
|
|
|
2520
2548
|
try {
|
|
2521
2549
|
result = await query.execute();
|
|
2522
2550
|
} catch (err) {
|
|
2523
|
-
const { sql:
|
|
2524
|
-
|
|
2551
|
+
const { sql: sql11, parameters } = query.compile();
|
|
2552
|
+
let message = `Failed to execute query: ${err}, sql: ${sql11}`;
|
|
2553
|
+
if (this.options.debug) {
|
|
2554
|
+
message += `, parameters:
|
|
2555
|
+
${parameters.map((p) => inspect(p)).join("\n")}`;
|
|
2556
|
+
}
|
|
2557
|
+
throw new QueryError(message, err);
|
|
2525
2558
|
}
|
|
2526
2559
|
if (inMemoryDistinct) {
|
|
2527
2560
|
const distinctResult = [];
|
|
@@ -2580,30 +2613,20 @@ var BaseOperationHandler = class {
|
|
|
2580
2613
|
for (const [field, value] of Object.entries(selections.select)) {
|
|
2581
2614
|
const fieldDef = requireField(this.schema, model, field);
|
|
2582
2615
|
const fieldModel = fieldDef.type;
|
|
2583
|
-
const
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
for (const [left, right] of joinPairs) {
|
|
2594
|
-
join = join.onRef(left, "=", right);
|
|
2595
|
-
}
|
|
2596
|
-
return join;
|
|
2597
|
-
});
|
|
2598
|
-
jsonObject[field] = this.countIdDistinct(eb, fieldDef.type, jointTable);
|
|
2616
|
+
const joinPairs = buildJoinPairs(this.schema, model, parentAlias, field, fieldModel);
|
|
2617
|
+
let fieldCountQuery = eb.selectFrom(fieldModel).select(eb.fn.countAll().as(`_count$${field}`));
|
|
2618
|
+
for (const [left, right] of joinPairs) {
|
|
2619
|
+
fieldCountQuery = fieldCountQuery.whereRef(left, "=", right);
|
|
2620
|
+
}
|
|
2621
|
+
if (value && typeof value === "object" && "where" in value && value.where && typeof value.where === "object") {
|
|
2622
|
+
const filter = this.dialect.buildFilter(eb, fieldModel, fieldModel, value.where);
|
|
2623
|
+
fieldCountQuery = fieldCountQuery.where(filter);
|
|
2624
|
+
}
|
|
2625
|
+
jsonObject[field] = fieldCountQuery;
|
|
2599
2626
|
}
|
|
2600
2627
|
query = query.select((eb2) => this.dialect.buildJsonObject(eb2, jsonObject).as("_count"));
|
|
2601
2628
|
return query;
|
|
2602
2629
|
}
|
|
2603
|
-
countIdDistinct(eb, model, table) {
|
|
2604
|
-
const idFields = getIdFields(this.schema, model);
|
|
2605
|
-
return eb.fn.count(sql4.join(idFields.map((f) => sql4.ref(`${table}.${f}`)))).distinct();
|
|
2606
|
-
}
|
|
2607
2630
|
buildSelectAllScalarFields(model, query, omit) {
|
|
2608
2631
|
const modelDef = this.requireModel(model);
|
|
2609
2632
|
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);
|
|
@@ -2669,14 +2692,14 @@ var BaseOperationHandler = class {
|
|
|
2669
2692
|
const fieldDef = this.requireField(model, field);
|
|
2670
2693
|
if (isScalarField(this.schema, model, field) || isForeignKeyField(this.schema, model, field)) {
|
|
2671
2694
|
if (fieldDef.array && value && typeof value === "object" && "set" in value && Array.isArray(value.set)) {
|
|
2672
|
-
createFields[field] = this.dialect.transformPrimitive(value.set, fieldDef.type);
|
|
2695
|
+
createFields[field] = this.dialect.transformPrimitive(value.set, fieldDef.type, true);
|
|
2673
2696
|
} else {
|
|
2674
|
-
createFields[field] = this.dialect.transformPrimitive(value, fieldDef.type);
|
|
2697
|
+
createFields[field] = this.dialect.transformPrimitive(value, fieldDef.type, !!fieldDef.array);
|
|
2675
2698
|
}
|
|
2676
2699
|
} else {
|
|
2677
2700
|
const subM2M = getManyToManyRelation(this.schema, model, field);
|
|
2678
2701
|
if (!subM2M && fieldDef.relation?.fields && fieldDef.relation?.references) {
|
|
2679
|
-
const fkValues = await this.
|
|
2702
|
+
const fkValues = await this.processOwnedRelationForCreate(kysely, fieldDef, value);
|
|
2680
2703
|
for (let i = 0; i < fieldDef.relation.fields.length; i++) {
|
|
2681
2704
|
createFields[fieldDef.relation.fields[i]] = fkValues[fieldDef.relation.references[i]];
|
|
2682
2705
|
}
|
|
@@ -2697,7 +2720,7 @@ var BaseOperationHandler = class {
|
|
|
2697
2720
|
const createdEntity = await query.executeTakeFirst();
|
|
2698
2721
|
if (Object.keys(postCreateRelations).length > 0) {
|
|
2699
2722
|
const relationPromises = Object.entries(postCreateRelations).map(([field, subPayload]) => {
|
|
2700
|
-
return this.
|
|
2723
|
+
return this.processNoneOwnedRelationForCreate(kysely, model, field, subPayload, createdEntity);
|
|
2701
2724
|
});
|
|
2702
2725
|
await Promise.all(relationPromises);
|
|
2703
2726
|
}
|
|
@@ -2764,7 +2787,7 @@ var BaseOperationHandler = class {
|
|
|
2764
2787
|
const eb = expressionBuilder2();
|
|
2765
2788
|
return kysely.deleteFrom(m2m.joinTable).where(eb(`${m2m.joinTable}.${m2m.parentFkName}`, "=", parentId)).execute();
|
|
2766
2789
|
}
|
|
2767
|
-
async
|
|
2790
|
+
async processOwnedRelationForCreate(kysely, relationField, payload) {
|
|
2768
2791
|
if (!payload) {
|
|
2769
2792
|
return;
|
|
2770
2793
|
}
|
|
@@ -2814,21 +2837,27 @@ var BaseOperationHandler = class {
|
|
|
2814
2837
|
}
|
|
2815
2838
|
return result;
|
|
2816
2839
|
}
|
|
2817
|
-
|
|
2840
|
+
processNoneOwnedRelationForCreate(kysely, contextModel, relationFieldName, payload, parentEntity) {
|
|
2818
2841
|
const relationFieldDef = this.requireField(contextModel, relationFieldName);
|
|
2819
2842
|
const relationModel = relationFieldDef.type;
|
|
2820
2843
|
const tasks = [];
|
|
2844
|
+
const fromRelationContext = {
|
|
2845
|
+
model: contextModel,
|
|
2846
|
+
field: relationFieldName,
|
|
2847
|
+
ids: parentEntity
|
|
2848
|
+
};
|
|
2821
2849
|
for (const [action, subPayload] of Object.entries(payload)) {
|
|
2822
2850
|
if (!subPayload) {
|
|
2823
2851
|
continue;
|
|
2824
2852
|
}
|
|
2825
2853
|
switch (action) {
|
|
2826
2854
|
case "create": {
|
|
2827
|
-
tasks.push(...enumerate(subPayload).map((item) => this.create(kysely, relationModel, item,
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2855
|
+
tasks.push(...enumerate(subPayload).map((item) => this.create(kysely, relationModel, item, fromRelationContext)));
|
|
2856
|
+
break;
|
|
2857
|
+
}
|
|
2858
|
+
case "createMany": {
|
|
2859
|
+
invariant7(relationFieldDef.array, "relation must be an array for createMany");
|
|
2860
|
+
tasks.push(this.createMany(kysely, relationModel, subPayload, false, fromRelationContext));
|
|
2832
2861
|
break;
|
|
2833
2862
|
}
|
|
2834
2863
|
case "connect": {
|
|
@@ -2858,6 +2887,11 @@ var BaseOperationHandler = class {
|
|
|
2858
2887
|
return Promise.all(tasks);
|
|
2859
2888
|
}
|
|
2860
2889
|
async createMany(kysely, model, input, returnData, fromRelation) {
|
|
2890
|
+
if (!input.data || Array.isArray(input.data) && input.data.length === 0) {
|
|
2891
|
+
return returnData ? [] : {
|
|
2892
|
+
count: 0
|
|
2893
|
+
};
|
|
2894
|
+
}
|
|
2861
2895
|
const modelDef = this.requireModel(model);
|
|
2862
2896
|
let relationKeyPairs = [];
|
|
2863
2897
|
if (fromRelation) {
|
|
@@ -2872,7 +2906,7 @@ var BaseOperationHandler = class {
|
|
|
2872
2906
|
for (const [name, value] of Object.entries(item)) {
|
|
2873
2907
|
const fieldDef = this.requireField(model, name);
|
|
2874
2908
|
invariant7(!fieldDef.relation, "createMany does not support relations");
|
|
2875
|
-
newItem[name] = this.dialect.transformPrimitive(value, fieldDef.type);
|
|
2909
|
+
newItem[name] = this.dialect.transformPrimitive(value, fieldDef.type, !!fieldDef.array);
|
|
2876
2910
|
}
|
|
2877
2911
|
if (fromRelation) {
|
|
2878
2912
|
for (const { fk, pk } of relationKeyPairs) {
|
|
@@ -2907,7 +2941,7 @@ var BaseOperationHandler = class {
|
|
|
2907
2941
|
values[field] = generated;
|
|
2908
2942
|
}
|
|
2909
2943
|
} else if (fields[field]?.updatedAt) {
|
|
2910
|
-
values[field] = this.dialect.transformPrimitive(/* @__PURE__ */ new Date(), "DateTime");
|
|
2944
|
+
values[field] = this.dialect.transformPrimitive(/* @__PURE__ */ new Date(), "DateTime", false);
|
|
2911
2945
|
}
|
|
2912
2946
|
}
|
|
2913
2947
|
}
|
|
@@ -2972,7 +3006,7 @@ var BaseOperationHandler = class {
|
|
|
2972
3006
|
if (finalData === data) {
|
|
2973
3007
|
finalData = clone(data);
|
|
2974
3008
|
}
|
|
2975
|
-
finalData[fieldName] = this.dialect.transformPrimitive(/* @__PURE__ */ new Date(), "DateTime");
|
|
3009
|
+
finalData[fieldName] = this.dialect.transformPrimitive(/* @__PURE__ */ new Date(), "DateTime", false);
|
|
2976
3010
|
}
|
|
2977
3011
|
}
|
|
2978
3012
|
if (Object.keys(finalData).length === 0) {
|
|
@@ -2997,7 +3031,7 @@ var BaseOperationHandler = class {
|
|
|
2997
3031
|
updateFields[field] = this.transformScalarListUpdate(model, field, fieldDef, finalData[field]);
|
|
2998
3032
|
continue;
|
|
2999
3033
|
}
|
|
3000
|
-
updateFields[field] = this.dialect.transformPrimitive(finalData[field], fieldDef.type);
|
|
3034
|
+
updateFields[field] = this.dialect.transformPrimitive(finalData[field], fieldDef.type, !!fieldDef.array);
|
|
3001
3035
|
} else {
|
|
3002
3036
|
if (!allowRelationUpdate) {
|
|
3003
3037
|
throw new QueryError(`Relation update not allowed for field "${field}"`);
|
|
@@ -3042,7 +3076,7 @@ var BaseOperationHandler = class {
|
|
|
3042
3076
|
transformIncrementalUpdate(model, field, fieldDef, payload) {
|
|
3043
3077
|
invariant7(Object.keys(payload).length === 1, 'Only one of "set", "increment", "decrement", "multiply", or "divide" can be provided');
|
|
3044
3078
|
const key = Object.keys(payload)[0];
|
|
3045
|
-
const value = this.dialect.transformPrimitive(payload[key], fieldDef.type);
|
|
3079
|
+
const value = this.dialect.transformPrimitive(payload[key], fieldDef.type, false);
|
|
3046
3080
|
const eb = expressionBuilder2();
|
|
3047
3081
|
const fieldRef = buildFieldRef(this.schema, model, field, this.options, eb);
|
|
3048
3082
|
return match8(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(() => {
|
|
@@ -3052,7 +3086,7 @@ var BaseOperationHandler = class {
|
|
|
3052
3086
|
transformScalarListUpdate(model, field, fieldDef, payload) {
|
|
3053
3087
|
invariant7(Object.keys(payload).length === 1, 'Only one of "set", "push" can be provided');
|
|
3054
3088
|
const key = Object.keys(payload)[0];
|
|
3055
|
-
const value = this.dialect.transformPrimitive(payload[key], fieldDef.type);
|
|
3089
|
+
const value = this.dialect.transformPrimitive(payload[key], fieldDef.type, true);
|
|
3056
3090
|
const eb = expressionBuilder2();
|
|
3057
3091
|
const fieldRef = buildFieldRef(this.schema, model, field, this.options, eb);
|
|
3058
3092
|
return match8(key).with("set", () => value).with("push", () => {
|
|
@@ -3082,7 +3116,7 @@ var BaseOperationHandler = class {
|
|
|
3082
3116
|
if (isRelationField(this.schema, model, field)) {
|
|
3083
3117
|
continue;
|
|
3084
3118
|
}
|
|
3085
|
-
updateFields[field] = this.dialect.transformPrimitive(data[field], fieldDef.type);
|
|
3119
|
+
updateFields[field] = this.dialect.transformPrimitive(data[field], fieldDef.type, !!fieldDef.array);
|
|
3086
3120
|
}
|
|
3087
3121
|
let query = kysely.updateTable(model).set(updateFields);
|
|
3088
3122
|
if (limit === void 0) {
|
|
@@ -3100,20 +3134,15 @@ var BaseOperationHandler = class {
|
|
|
3100
3134
|
model,
|
|
3101
3135
|
operation: "update"
|
|
3102
3136
|
}));
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
return result;
|
|
3113
|
-
}
|
|
3114
|
-
} catch (err) {
|
|
3115
|
-
const { sql: sql10, parameters } = query.compile();
|
|
3116
|
-
throw new QueryError(`Error during updateMany: ${err}, sql: ${sql10}, parameters: ${parameters}`);
|
|
3137
|
+
if (!returnData) {
|
|
3138
|
+
const result = await query.executeTakeFirstOrThrow();
|
|
3139
|
+
return {
|
|
3140
|
+
count: Number(result.numUpdatedRows)
|
|
3141
|
+
};
|
|
3142
|
+
} else {
|
|
3143
|
+
const idFields = getIdFields(this.schema, model);
|
|
3144
|
+
const result = await query.returning(idFields).execute();
|
|
3145
|
+
return result;
|
|
3117
3146
|
}
|
|
3118
3147
|
}
|
|
3119
3148
|
buildIdFieldRefs(kysely, model) {
|
|
@@ -3533,11 +3562,15 @@ var BaseOperationHandler = class {
|
|
|
3533
3562
|
}
|
|
3534
3563
|
return returnRelation;
|
|
3535
3564
|
}
|
|
3536
|
-
async safeTransaction(callback) {
|
|
3565
|
+
async safeTransaction(callback, isolationLevel) {
|
|
3537
3566
|
if (this.kysely.isTransaction) {
|
|
3538
3567
|
return callback(this.kysely);
|
|
3539
3568
|
} else {
|
|
3540
|
-
|
|
3569
|
+
let txBuilder = this.kysely.transaction();
|
|
3570
|
+
if (isolationLevel) {
|
|
3571
|
+
txBuilder = txBuilder.setIsolationLevel(isolationLevel);
|
|
3572
|
+
}
|
|
3573
|
+
return txBuilder.execute(callback);
|
|
3541
3574
|
}
|
|
3542
3575
|
}
|
|
3543
3576
|
// Given a unique filter of a model, return the entity ids by trying to
|
|
@@ -3556,6 +3589,28 @@ var BaseOperationHandler = class {
|
|
|
3556
3589
|
where: uniqueFilter
|
|
3557
3590
|
});
|
|
3558
3591
|
}
|
|
3592
|
+
/**
|
|
3593
|
+
* Normalize input args to strip `undefined` fields
|
|
3594
|
+
*/
|
|
3595
|
+
normalizeArgs(args) {
|
|
3596
|
+
if (!args) {
|
|
3597
|
+
return;
|
|
3598
|
+
}
|
|
3599
|
+
const newArgs = clone(args);
|
|
3600
|
+
this.doNormalizeArgs(newArgs);
|
|
3601
|
+
return newArgs;
|
|
3602
|
+
}
|
|
3603
|
+
doNormalizeArgs(args) {
|
|
3604
|
+
if (args && typeof args === "object") {
|
|
3605
|
+
for (const [key, value] of Object.entries(args)) {
|
|
3606
|
+
if (value === void 0) {
|
|
3607
|
+
delete args[key];
|
|
3608
|
+
} else if (value && isPlainObject3(value)) {
|
|
3609
|
+
this.doNormalizeArgs(value);
|
|
3610
|
+
}
|
|
3611
|
+
}
|
|
3612
|
+
}
|
|
3613
|
+
}
|
|
3559
3614
|
};
|
|
3560
3615
|
|
|
3561
3616
|
// src/client/crud/operations/aggregate.ts
|
|
@@ -3564,21 +3619,22 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
|
|
|
3564
3619
|
__name(this, "AggregateOperationHandler");
|
|
3565
3620
|
}
|
|
3566
3621
|
async handle(_operation, args) {
|
|
3567
|
-
const
|
|
3622
|
+
const normalizedArgs = this.normalizeArgs(args);
|
|
3623
|
+
const parsedArgs = this.inputValidator.validateAggregateArgs(this.model, normalizedArgs);
|
|
3568
3624
|
let query = this.kysely.selectFrom((eb) => {
|
|
3569
|
-
let subQuery = eb.selectFrom(this.model).selectAll(this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model,
|
|
3570
|
-
const skip =
|
|
3571
|
-
let take =
|
|
3625
|
+
let subQuery = eb.selectFrom(this.model).selectAll(this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
|
|
3626
|
+
const skip = parsedArgs?.skip;
|
|
3627
|
+
let take = parsedArgs?.take;
|
|
3572
3628
|
let negateOrderBy = false;
|
|
3573
3629
|
if (take !== void 0 && take < 0) {
|
|
3574
3630
|
negateOrderBy = true;
|
|
3575
3631
|
take = -take;
|
|
3576
3632
|
}
|
|
3577
3633
|
subQuery = this.dialect.buildSkipTake(subQuery, skip, take);
|
|
3578
|
-
subQuery = this.dialect.buildOrderBy(subQuery, this.model, this.model,
|
|
3634
|
+
subQuery = this.dialect.buildOrderBy(subQuery, this.model, this.model, parsedArgs.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
|
|
3579
3635
|
return subQuery.as("$sub");
|
|
3580
3636
|
});
|
|
3581
|
-
for (const [key, value] of Object.entries(
|
|
3637
|
+
for (const [key, value] of Object.entries(parsedArgs)) {
|
|
3582
3638
|
switch (key) {
|
|
3583
3639
|
case "_count": {
|
|
3584
3640
|
if (value === true) {
|
|
@@ -3657,14 +3713,15 @@ var CountOperationHandler = class extends BaseOperationHandler {
|
|
|
3657
3713
|
__name(this, "CountOperationHandler");
|
|
3658
3714
|
}
|
|
3659
3715
|
async handle(_operation, args) {
|
|
3660
|
-
const
|
|
3716
|
+
const normalizedArgs = this.normalizeArgs(args);
|
|
3717
|
+
const parsedArgs = this.inputValidator.validateCountArgs(this.model, normalizedArgs);
|
|
3661
3718
|
let query = this.kysely.selectFrom((eb) => {
|
|
3662
|
-
let subQuery = eb.selectFrom(this.model).selectAll().where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model,
|
|
3663
|
-
subQuery = this.dialect.buildSkipTake(subQuery,
|
|
3719
|
+
let subQuery = eb.selectFrom(this.model).selectAll().where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
|
|
3720
|
+
subQuery = this.dialect.buildSkipTake(subQuery, parsedArgs?.skip, parsedArgs?.take);
|
|
3664
3721
|
return subQuery.as("$sub");
|
|
3665
3722
|
});
|
|
3666
|
-
if (
|
|
3667
|
-
query = query.select((eb) => Object.keys(
|
|
3723
|
+
if (parsedArgs?.select && typeof parsedArgs.select === "object") {
|
|
3724
|
+
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(sql6.ref(`$sub.${key}`)), "integer").as(key)));
|
|
3668
3725
|
return query.executeTakeFirstOrThrow();
|
|
3669
3726
|
} else {
|
|
3670
3727
|
query = query.select((eb) => eb.cast(eb.fn.countAll(), "integer").as("count"));
|
|
@@ -3681,10 +3738,11 @@ var CreateOperationHandler = class extends BaseOperationHandler {
|
|
|
3681
3738
|
__name(this, "CreateOperationHandler");
|
|
3682
3739
|
}
|
|
3683
3740
|
async handle(operation, args) {
|
|
3684
|
-
|
|
3685
|
-
|
|
3741
|
+
const normalizedArgs = this.normalizeArgs(args);
|
|
3742
|
+
return match10(operation).with("create", () => this.runCreate(this.inputValidator.validateCreateArgs(this.model, normalizedArgs))).with("createMany", () => {
|
|
3743
|
+
return this.runCreateMany(this.inputValidator.validateCreateManyArgs(this.model, normalizedArgs));
|
|
3686
3744
|
}).with("createManyAndReturn", () => {
|
|
3687
|
-
return this.runCreateManyAndReturn(this.inputValidator.validateCreateManyAndReturnArgs(this.model,
|
|
3745
|
+
return this.runCreateManyAndReturn(this.inputValidator.validateCreateManyAndReturnArgs(this.model, normalizedArgs));
|
|
3688
3746
|
}).exhaustive();
|
|
3689
3747
|
}
|
|
3690
3748
|
async runCreate(args) {
|
|
@@ -3734,7 +3792,8 @@ var DeleteOperationHandler = class extends BaseOperationHandler {
|
|
|
3734
3792
|
__name(this, "DeleteOperationHandler");
|
|
3735
3793
|
}
|
|
3736
3794
|
async handle(operation, args) {
|
|
3737
|
-
|
|
3795
|
+
const normalizedArgs = this.normalizeArgs(args);
|
|
3796
|
+
return match11(operation).with("delete", () => this.runDelete(this.inputValidator.validateDeleteArgs(this.model, normalizedArgs))).with("deleteMany", () => this.runDeleteMany(this.inputValidator.validateDeleteManyArgs(this.model, normalizedArgs))).exhaustive();
|
|
3738
3797
|
}
|
|
3739
3798
|
async runDelete(args) {
|
|
3740
3799
|
const existing = await this.readUnique(this.kysely, this.model, {
|
|
@@ -3764,7 +3823,8 @@ var FindOperationHandler = class extends BaseOperationHandler {
|
|
|
3764
3823
|
__name(this, "FindOperationHandler");
|
|
3765
3824
|
}
|
|
3766
3825
|
async handle(operation, args, validateArgs = true) {
|
|
3767
|
-
const
|
|
3826
|
+
const normalizeArgs = this.normalizeArgs(args);
|
|
3827
|
+
const parsedArgs = validateArgs ? this.inputValidator.validateFindArgs(this.model, operation === "findUnique", normalizeArgs) : normalizeArgs;
|
|
3768
3828
|
const result = await this.read(this.client.$qb, this.model, parsedArgs);
|
|
3769
3829
|
const finalResult = operation === "findMany" ? result : result[0] ?? null;
|
|
3770
3830
|
return finalResult;
|
|
@@ -3774,16 +3834,17 @@ var FindOperationHandler = class extends BaseOperationHandler {
|
|
|
3774
3834
|
// src/client/crud/operations/group-by.ts
|
|
3775
3835
|
import { sql as sql7 } from "kysely";
|
|
3776
3836
|
import { match as match12 } from "ts-pattern";
|
|
3777
|
-
var
|
|
3837
|
+
var GroupByOperationHandler = class extends BaseOperationHandler {
|
|
3778
3838
|
static {
|
|
3779
|
-
__name(this, "
|
|
3839
|
+
__name(this, "GroupByOperationHandler");
|
|
3780
3840
|
}
|
|
3781
3841
|
async handle(_operation, args) {
|
|
3782
|
-
const
|
|
3842
|
+
const normalizedArgs = this.normalizeArgs(args);
|
|
3843
|
+
const parsedArgs = this.inputValidator.validateGroupByArgs(this.model, normalizedArgs);
|
|
3783
3844
|
let query = this.kysely.selectFrom((eb) => {
|
|
3784
|
-
let subQuery = eb.selectFrom(this.model).selectAll().where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model,
|
|
3785
|
-
const skip =
|
|
3786
|
-
let take =
|
|
3845
|
+
let subQuery = eb.selectFrom(this.model).selectAll().where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
|
|
3846
|
+
const skip = parsedArgs?.skip;
|
|
3847
|
+
let take = parsedArgs?.take;
|
|
3787
3848
|
let negateOrderBy = false;
|
|
3788
3849
|
if (take !== void 0 && take < 0) {
|
|
3789
3850
|
negateOrderBy = true;
|
|
@@ -3793,20 +3854,20 @@ var GroupByeOperationHandler = class extends BaseOperationHandler {
|
|
|
3793
3854
|
subQuery = this.dialect.buildOrderBy(subQuery, this.model, this.model, void 0, skip !== void 0 || take !== void 0, negateOrderBy);
|
|
3794
3855
|
return subQuery.as("$sub");
|
|
3795
3856
|
});
|
|
3796
|
-
const bys = typeof
|
|
3797
|
-
|
|
3798
|
-
] :
|
|
3857
|
+
const bys = typeof parsedArgs.by === "string" ? [
|
|
3858
|
+
parsedArgs.by
|
|
3859
|
+
] : parsedArgs.by;
|
|
3799
3860
|
query = query.groupBy(bys);
|
|
3800
|
-
if (
|
|
3801
|
-
query = this.dialect.buildOrderBy(query, this.model, "$sub",
|
|
3861
|
+
if (parsedArgs.orderBy) {
|
|
3862
|
+
query = this.dialect.buildOrderBy(query, this.model, "$sub", parsedArgs.orderBy, false, false);
|
|
3802
3863
|
}
|
|
3803
|
-
if (
|
|
3804
|
-
query = query.having((eb1) => this.dialect.buildFilter(eb1, this.model, "$sub",
|
|
3864
|
+
if (parsedArgs.having) {
|
|
3865
|
+
query = query.having((eb1) => this.dialect.buildFilter(eb1, this.model, "$sub", parsedArgs.having));
|
|
3805
3866
|
}
|
|
3806
3867
|
for (const by of bys) {
|
|
3807
3868
|
query = query.select(() => sql7.ref(`$sub.${by}`).as(by));
|
|
3808
3869
|
}
|
|
3809
|
-
for (const [key, value] of Object.entries(
|
|
3870
|
+
for (const [key, value] of Object.entries(parsedArgs)) {
|
|
3810
3871
|
switch (key) {
|
|
3811
3872
|
case "_count": {
|
|
3812
3873
|
if (value === true) {
|
|
@@ -3889,7 +3950,8 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
|
|
|
3889
3950
|
__name(this, "UpdateOperationHandler");
|
|
3890
3951
|
}
|
|
3891
3952
|
async handle(operation, args) {
|
|
3892
|
-
|
|
3953
|
+
const normalizedArgs = this.normalizeArgs(args);
|
|
3954
|
+
return match13(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();
|
|
3893
3955
|
}
|
|
3894
3956
|
async runUpdate(args) {
|
|
3895
3957
|
const result = await this.safeTransaction(async (tx) => {
|
|
@@ -3945,6 +4007,7 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
|
|
|
3945
4007
|
};
|
|
3946
4008
|
|
|
3947
4009
|
// src/client/crud/validator.ts
|
|
4010
|
+
import { invariant as invariant8 } from "@zenstackhq/common-helpers";
|
|
3948
4011
|
import Decimal from "decimal.js";
|
|
3949
4012
|
import stableStringify from "json-stable-stringify";
|
|
3950
4013
|
import { match as match14, P as P2 } from "ts-pattern";
|
|
@@ -3954,10 +4017,9 @@ var InputValidator = class {
|
|
|
3954
4017
|
__name(this, "InputValidator");
|
|
3955
4018
|
}
|
|
3956
4019
|
schema;
|
|
3957
|
-
schemaCache;
|
|
4020
|
+
schemaCache = /* @__PURE__ */ new Map();
|
|
3958
4021
|
constructor(schema) {
|
|
3959
4022
|
this.schema = schema;
|
|
3960
|
-
this.schemaCache = /* @__PURE__ */ new Map();
|
|
3961
4023
|
}
|
|
3962
4024
|
validateFindArgs(model, unique, args) {
|
|
3963
4025
|
return this.validate(model, "find", {
|
|
@@ -4014,7 +4076,7 @@ var InputValidator = class {
|
|
|
4014
4076
|
}
|
|
4015
4077
|
const { error } = schema.safeParse(args);
|
|
4016
4078
|
if (error) {
|
|
4017
|
-
throw new
|
|
4079
|
+
throw new InputValidationError(`Invalid ${operation} args: ${error.message}`, error);
|
|
4018
4080
|
}
|
|
4019
4081
|
return args;
|
|
4020
4082
|
}
|
|
@@ -4061,7 +4123,7 @@ var InputValidator = class {
|
|
|
4061
4123
|
makeWhereSchema(model, unique, withoutRelationFields = false) {
|
|
4062
4124
|
const modelDef = getModel(this.schema, model);
|
|
4063
4125
|
if (!modelDef) {
|
|
4064
|
-
throw new QueryError(`Model "${model}" not found`);
|
|
4126
|
+
throw new QueryError(`Model "${model}" not found in schema`);
|
|
4065
4127
|
}
|
|
4066
4128
|
const fields = {};
|
|
4067
4129
|
for (const field of Object.keys(modelDef.fields)) {
|
|
@@ -4111,14 +4173,28 @@ var InputValidator = class {
|
|
|
4111
4173
|
const uniqueFields = getUniqueFields(this.schema, model);
|
|
4112
4174
|
for (const uniqueField of uniqueFields) {
|
|
4113
4175
|
if ("defs" in uniqueField) {
|
|
4114
|
-
fields[uniqueField.name] = z.object(Object.fromEntries(Object.entries(uniqueField.defs).map(([key, def]) =>
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
|
|
4176
|
+
fields[uniqueField.name] = z.object(Object.fromEntries(Object.entries(uniqueField.defs).map(([key, def]) => {
|
|
4177
|
+
invariant8(!def.relation, "unique field cannot be a relation");
|
|
4178
|
+
let fieldSchema;
|
|
4179
|
+
const enumDef = getEnum(this.schema, def.type);
|
|
4180
|
+
if (enumDef) {
|
|
4181
|
+
if (Object.keys(enumDef).length > 0) {
|
|
4182
|
+
fieldSchema = this.makeEnumFilterSchema(enumDef, !!def.optional);
|
|
4183
|
+
} else {
|
|
4184
|
+
fieldSchema = z.never();
|
|
4185
|
+
}
|
|
4186
|
+
} else {
|
|
4187
|
+
fieldSchema = this.makePrimitiveFilterSchema(def.type, !!def.optional);
|
|
4188
|
+
}
|
|
4189
|
+
return [
|
|
4190
|
+
key,
|
|
4191
|
+
fieldSchema
|
|
4192
|
+
];
|
|
4193
|
+
}))).optional();
|
|
4118
4194
|
}
|
|
4119
4195
|
}
|
|
4120
4196
|
}
|
|
4121
|
-
fields["$expr"] = z.
|
|
4197
|
+
fields["$expr"] = z.custom((v) => typeof v === "function").optional();
|
|
4122
4198
|
fields["AND"] = this.orArray(z.lazy(() => this.makeWhereSchema(model, false, withoutRelationFields)), true).optional();
|
|
4123
4199
|
fields["OR"] = z.lazy(() => this.makeWhereSchema(model, false, withoutRelationFields)).array().optional();
|
|
4124
4200
|
fields["NOT"] = this.orArray(z.lazy(() => this.makeWhereSchema(model, false, withoutRelationFields)), true).optional();
|
|
@@ -4164,7 +4240,7 @@ var InputValidator = class {
|
|
|
4164
4240
|
});
|
|
4165
4241
|
}
|
|
4166
4242
|
makePrimitiveFilterSchema(type, optional) {
|
|
4167
|
-
return match14(type).with("String", () => this.makeStringFilterSchema(optional)).with(P2.union("Int", "Float", "Decimal", "BigInt"), (type2) => this.makeNumberFilterSchema(this.makePrimitiveSchema(type2), optional)).with("Boolean", () => this.makeBooleanFilterSchema(optional)).with("DateTime", () => this.makeDateTimeFilterSchema(optional)).with("Bytes", () => this.makeBytesFilterSchema(optional)).exhaustive();
|
|
4243
|
+
return match14(type).with("String", () => this.makeStringFilterSchema(optional)).with(P2.union("Int", "Float", "Decimal", "BigInt"), (type2) => this.makeNumberFilterSchema(this.makePrimitiveSchema(type2), optional)).with("Boolean", () => this.makeBooleanFilterSchema(optional)).with("DateTime", () => this.makeDateTimeFilterSchema(optional)).with("Bytes", () => this.makeBytesFilterSchema(optional)).with("Json", () => z.any()).with("Unsupported", () => z.never()).exhaustive();
|
|
4168
4244
|
}
|
|
4169
4245
|
makeDateTimeFilterSchema(optional) {
|
|
4170
4246
|
return this.makeCommonPrimitiveFilterSchema(z.union([
|
|
@@ -4358,8 +4434,8 @@ var InputValidator = class {
|
|
|
4358
4434
|
return this.refineForSelectOmitMutuallyExclusive(result).optional();
|
|
4359
4435
|
}
|
|
4360
4436
|
makeCreateDataSchema(model, canBeArray, withoutFields = [], withoutRelationFields = false) {
|
|
4361
|
-
const
|
|
4362
|
-
const
|
|
4437
|
+
const uncheckedVariantFields = {};
|
|
4438
|
+
const checkedVariantFields = {};
|
|
4363
4439
|
const modelDef = requireModel(this.schema, model);
|
|
4364
4440
|
const hasRelation = !withoutRelationFields && Object.entries(modelDef.fields).some(([f, def]) => !withoutFields.includes(f) && def.relation);
|
|
4365
4441
|
Object.keys(modelDef.fields).forEach((field) => {
|
|
@@ -4401,7 +4477,10 @@ var InputValidator = class {
|
|
|
4401
4477
|
if (fieldDef.optional && !fieldDef.array) {
|
|
4402
4478
|
fieldSchema = fieldSchema.nullable();
|
|
4403
4479
|
}
|
|
4404
|
-
|
|
4480
|
+
checkedVariantFields[field] = fieldSchema;
|
|
4481
|
+
if (fieldDef.array || !fieldDef.relation.references) {
|
|
4482
|
+
uncheckedVariantFields[field] = fieldSchema;
|
|
4483
|
+
}
|
|
4405
4484
|
} else {
|
|
4406
4485
|
let fieldSchema = this.makePrimitiveSchema(fieldDef.type);
|
|
4407
4486
|
if (fieldDef.array) {
|
|
@@ -4418,23 +4497,23 @@ var InputValidator = class {
|
|
|
4418
4497
|
if (fieldDef.optional) {
|
|
4419
4498
|
fieldSchema = fieldSchema.nullable();
|
|
4420
4499
|
}
|
|
4421
|
-
|
|
4500
|
+
uncheckedVariantFields[field] = fieldSchema;
|
|
4422
4501
|
if (!fieldDef.foreignKeyFor) {
|
|
4423
|
-
|
|
4502
|
+
checkedVariantFields[field] = fieldSchema;
|
|
4424
4503
|
}
|
|
4425
4504
|
}
|
|
4426
4505
|
});
|
|
4427
4506
|
if (!hasRelation) {
|
|
4428
|
-
return this.orArray(z.object(
|
|
4507
|
+
return this.orArray(z.object(uncheckedVariantFields).strict(), canBeArray);
|
|
4429
4508
|
} else {
|
|
4430
4509
|
return z.union([
|
|
4431
|
-
z.object(
|
|
4432
|
-
z.object(
|
|
4510
|
+
z.object(uncheckedVariantFields).strict(),
|
|
4511
|
+
z.object(checkedVariantFields).strict(),
|
|
4433
4512
|
...canBeArray ? [
|
|
4434
|
-
z.array(z.object(
|
|
4513
|
+
z.array(z.object(uncheckedVariantFields).strict())
|
|
4435
4514
|
] : [],
|
|
4436
4515
|
...canBeArray ? [
|
|
4437
|
-
z.array(z.object(
|
|
4516
|
+
z.array(z.object(checkedVariantFields).strict())
|
|
4438
4517
|
] : []
|
|
4439
4518
|
]);
|
|
4440
4519
|
}
|
|
@@ -4479,7 +4558,7 @@ var InputValidator = class {
|
|
|
4479
4558
|
fields["deleteMany"] = this.makeDeleteRelationDataSchema(fieldType, true, false).optional();
|
|
4480
4559
|
}
|
|
4481
4560
|
}
|
|
4482
|
-
return z.object(fields).strict()
|
|
4561
|
+
return z.object(fields).strict();
|
|
4483
4562
|
}
|
|
4484
4563
|
makeSetDataSchema(model, canBeArray) {
|
|
4485
4564
|
return this.orArray(this.makeWhereSchema(model, true), canBeArray);
|
|
@@ -4914,8 +4993,9 @@ function performanceNow() {
|
|
|
4914
4993
|
__name(performanceNow, "performanceNow");
|
|
4915
4994
|
|
|
4916
4995
|
// src/client/executor/zenstack-query-executor.ts
|
|
4917
|
-
import { AndNode as AndNode2, DefaultQueryExecutor, DeleteQueryNode as DeleteQueryNode2, InsertQueryNode as InsertQueryNode2, ReturningNode as ReturningNode3, SelectionNode as SelectionNode4,
|
|
4996
|
+
import { AndNode as AndNode2, DefaultQueryExecutor, DeleteQueryNode as DeleteQueryNode2, InsertQueryNode as InsertQueryNode2, ReturningNode as ReturningNode3, SelectionNode as SelectionNode4, UpdateQueryNode as UpdateQueryNode2, WhereNode as WhereNode3 } from "kysely";
|
|
4918
4997
|
import { nanoid as nanoid2 } from "nanoid";
|
|
4998
|
+
import { inspect as inspect2 } from "util";
|
|
4919
4999
|
import { match as match15 } from "ts-pattern";
|
|
4920
5000
|
|
|
4921
5001
|
// src/client/executor/name-mapper.ts
|
|
@@ -4925,11 +5005,11 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
|
|
|
4925
5005
|
__name(this, "QueryNameMapper");
|
|
4926
5006
|
}
|
|
4927
5007
|
schema;
|
|
4928
|
-
modelToTableMap;
|
|
4929
|
-
fieldToColumnMap;
|
|
4930
|
-
modelStack;
|
|
5008
|
+
modelToTableMap = /* @__PURE__ */ new Map();
|
|
5009
|
+
fieldToColumnMap = /* @__PURE__ */ new Map();
|
|
5010
|
+
modelStack = [];
|
|
4931
5011
|
constructor(schema) {
|
|
4932
|
-
super(), this.schema = schema
|
|
5012
|
+
super(), this.schema = schema;
|
|
4933
5013
|
for (const [modelName, modelDef] of Object.entries(schema.models)) {
|
|
4934
5014
|
const mappedName = this.getMappedName(modelDef);
|
|
4935
5015
|
if (mappedName) {
|
|
@@ -5150,7 +5230,9 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends DefaultQueryExe
|
|
|
5150
5230
|
mutationInterceptionInfo = await this.callMutationInterceptionFilters(queryNode);
|
|
5151
5231
|
}
|
|
5152
5232
|
const task = /* @__PURE__ */ __name(async () => {
|
|
5153
|
-
|
|
5233
|
+
if (this.isMutationNode(queryNode)) {
|
|
5234
|
+
await this.callBeforeMutationHooks(queryNode, mutationInterceptionInfo);
|
|
5235
|
+
}
|
|
5154
5236
|
const oldQueryNode = queryNode;
|
|
5155
5237
|
if ((InsertQueryNode2.is(queryNode) || DeleteQueryNode2.is(queryNode)) && mutationInterceptionInfo?.loadAfterMutationEntity) {
|
|
5156
5238
|
queryNode = {
|
|
@@ -5160,19 +5242,19 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends DefaultQueryExe
|
|
|
5160
5242
|
])
|
|
5161
5243
|
};
|
|
5162
5244
|
}
|
|
5163
|
-
const
|
|
5164
|
-
await this.
|
|
5245
|
+
const queryParams = compiledQuery.$raw ? compiledQuery.parameters : void 0;
|
|
5246
|
+
const result = await this.proceedQueryWithKyselyInterceptors(queryNode, queryParams, queryId);
|
|
5247
|
+
if (this.isMutationNode(queryNode)) {
|
|
5248
|
+
await this.callAfterQueryInterceptionFilters(result, queryNode, mutationInterceptionInfo);
|
|
5249
|
+
}
|
|
5165
5250
|
if (oldQueryNode !== queryNode) {
|
|
5166
5251
|
}
|
|
5167
5252
|
return result;
|
|
5168
5253
|
}, "task");
|
|
5169
|
-
return
|
|
5254
|
+
return task();
|
|
5170
5255
|
}
|
|
5171
|
-
proceedQueryWithKyselyInterceptors(queryNode, queryId) {
|
|
5172
|
-
let proceed = /* @__PURE__ */ __name((q) => this.proceedQuery(q, queryId), "proceed");
|
|
5173
|
-
const makeTx = /* @__PURE__ */ __name((p) => (callback) => {
|
|
5174
|
-
return this.executeWithTransaction(() => callback(p));
|
|
5175
|
-
}, "makeTx");
|
|
5256
|
+
proceedQueryWithKyselyInterceptors(queryNode, parameters, queryId) {
|
|
5257
|
+
let proceed = /* @__PURE__ */ __name((q) => this.proceedQuery(q, parameters, queryId), "proceed");
|
|
5176
5258
|
const hooks = this.options.plugins?.filter((plugin) => typeof plugin.onKyselyQuery === "function").map((plugin) => plugin.onKyselyQuery.bind(plugin)) ?? [];
|
|
5177
5259
|
for (const hook of hooks) {
|
|
5178
5260
|
const _proceed = proceed;
|
|
@@ -5182,20 +5264,30 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends DefaultQueryExe
|
|
|
5182
5264
|
schema: this.client.$schema,
|
|
5183
5265
|
kysely: this.kysely,
|
|
5184
5266
|
query,
|
|
5185
|
-
proceed: _proceed
|
|
5186
|
-
transaction: makeTx(_proceed)
|
|
5267
|
+
proceed: _proceed
|
|
5187
5268
|
});
|
|
5188
5269
|
}, "proceed");
|
|
5189
5270
|
}
|
|
5190
5271
|
return proceed(queryNode);
|
|
5191
5272
|
}
|
|
5192
|
-
async proceedQuery(query, queryId) {
|
|
5273
|
+
async proceedQuery(query, parameters, queryId) {
|
|
5193
5274
|
const finalQuery = this.nameMapper.transformNode(query);
|
|
5194
|
-
|
|
5275
|
+
let compiled = this.compileQuery(finalQuery);
|
|
5276
|
+
if (parameters) {
|
|
5277
|
+
compiled = {
|
|
5278
|
+
...compiled,
|
|
5279
|
+
parameters
|
|
5280
|
+
};
|
|
5281
|
+
}
|
|
5195
5282
|
try {
|
|
5196
|
-
return
|
|
5283
|
+
return await super.executeQuery(compiled, queryId);
|
|
5197
5284
|
} catch (err) {
|
|
5198
|
-
|
|
5285
|
+
let message = `Failed to execute query: ${err}, sql: ${compiled.sql}`;
|
|
5286
|
+
if (this.options.debug) {
|
|
5287
|
+
message += `, parameters:
|
|
5288
|
+
${compiled.parameters.map((p) => inspect2(p)).join("\n")}`;
|
|
5289
|
+
}
|
|
5290
|
+
throw new QueryError(message, err);
|
|
5199
5291
|
}
|
|
5200
5292
|
}
|
|
5201
5293
|
isMutationNode(queryNode) {
|
|
@@ -5223,24 +5315,9 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends DefaultQueryExe
|
|
|
5223
5315
|
return new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, this.connectionProvider, []);
|
|
5224
5316
|
}
|
|
5225
5317
|
withConnectionProvider(connectionProvider) {
|
|
5226
|
-
|
|
5227
|
-
|
|
5228
|
-
|
|
5229
|
-
if (!useTransaction || this.driver.txConnection) {
|
|
5230
|
-
return callback();
|
|
5231
|
-
} else {
|
|
5232
|
-
return this.provideConnection(async (connection) => {
|
|
5233
|
-
try {
|
|
5234
|
-
await this.driver.beginTransaction(connection, {});
|
|
5235
|
-
const result = await callback();
|
|
5236
|
-
await this.driver.commitTransaction(connection);
|
|
5237
|
-
return result;
|
|
5238
|
-
} catch (error) {
|
|
5239
|
-
await this.driver.rollbackTransaction(connection);
|
|
5240
|
-
throw error;
|
|
5241
|
-
}
|
|
5242
|
-
});
|
|
5243
|
-
}
|
|
5318
|
+
const newExecutor = new _ZenStackQueryExecutor(this.client, this.driver, this.compiler, this.adapter, connectionProvider);
|
|
5319
|
+
newExecutor.client = this.client.withExecutor(newExecutor);
|
|
5320
|
+
return newExecutor;
|
|
5244
5321
|
}
|
|
5245
5322
|
get hasMutationHooks() {
|
|
5246
5323
|
return this.client.$options.plugins?.some((plugin) => plugin.beforeEntityMutation || plugin.afterEntityMutation);
|
|
@@ -5282,14 +5359,13 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends DefaultQueryExe
|
|
|
5282
5359
|
queryNode
|
|
5283
5360
|
});
|
|
5284
5361
|
result.intercept ||= filterResult.intercept;
|
|
5285
|
-
result.useTransactionForMutation ||= filterResult.useTransactionForMutation;
|
|
5286
5362
|
result.loadBeforeMutationEntity ||= filterResult.loadBeforeMutationEntity;
|
|
5287
5363
|
result.loadAfterMutationEntity ||= filterResult.loadAfterMutationEntity;
|
|
5288
5364
|
}
|
|
5289
5365
|
}
|
|
5290
5366
|
let beforeMutationEntities;
|
|
5291
5367
|
if (result.loadBeforeMutationEntity && (UpdateQueryNode2.is(queryNode) || DeleteQueryNode2.is(queryNode))) {
|
|
5292
|
-
beforeMutationEntities = await this.loadEntities(
|
|
5368
|
+
beforeMutationEntities = await this.loadEntities(mutationModel, where);
|
|
5293
5369
|
}
|
|
5294
5370
|
return {
|
|
5295
5371
|
...result,
|
|
@@ -5302,15 +5378,14 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends DefaultQueryExe
|
|
|
5302
5378
|
return void 0;
|
|
5303
5379
|
}
|
|
5304
5380
|
}
|
|
5305
|
-
callBeforeMutationHooks(queryNode, mutationInterceptionInfo) {
|
|
5381
|
+
async callBeforeMutationHooks(queryNode, mutationInterceptionInfo) {
|
|
5306
5382
|
if (!mutationInterceptionInfo?.intercept) {
|
|
5307
5383
|
return;
|
|
5308
5384
|
}
|
|
5309
5385
|
if (this.options.plugins) {
|
|
5310
5386
|
for (const plugin of this.options.plugins) {
|
|
5311
5387
|
if (plugin.beforeEntityMutation) {
|
|
5312
|
-
plugin.beforeEntityMutation({
|
|
5313
|
-
// context: this.queryContext,
|
|
5388
|
+
await plugin.beforeEntityMutation({
|
|
5314
5389
|
model: this.getMutationModel(queryNode),
|
|
5315
5390
|
action: mutationInterceptionInfo.action,
|
|
5316
5391
|
queryNode,
|
|
@@ -5331,12 +5406,12 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends DefaultQueryExe
|
|
|
5331
5406
|
let afterMutationEntities = void 0;
|
|
5332
5407
|
if (mutationInterceptionInfo.loadAfterMutationEntity) {
|
|
5333
5408
|
if (UpdateQueryNode2.is(queryNode)) {
|
|
5334
|
-
afterMutationEntities = await this.loadEntities(
|
|
5409
|
+
afterMutationEntities = await this.loadEntities(mutationModel, mutationInterceptionInfo.where);
|
|
5335
5410
|
} else {
|
|
5336
5411
|
afterMutationEntities = queryResult.rows;
|
|
5337
5412
|
}
|
|
5338
5413
|
}
|
|
5339
|
-
plugin.afterEntityMutation({
|
|
5414
|
+
await plugin.afterEntityMutation({
|
|
5340
5415
|
model: this.getMutationModel(queryNode),
|
|
5341
5416
|
action: mutationInterceptionInfo.action,
|
|
5342
5417
|
queryNode,
|
|
@@ -5347,17 +5422,17 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends DefaultQueryExe
|
|
|
5347
5422
|
}
|
|
5348
5423
|
}
|
|
5349
5424
|
}
|
|
5350
|
-
async loadEntities(
|
|
5351
|
-
const selectQuery = kysely.selectFrom(model).selectAll();
|
|
5425
|
+
async loadEntities(model, where) {
|
|
5426
|
+
const selectQuery = this.kysely.selectFrom(model).selectAll();
|
|
5352
5427
|
let selectQueryNode = selectQuery.toOperationNode();
|
|
5353
5428
|
selectQueryNode = {
|
|
5354
5429
|
...selectQueryNode,
|
|
5355
5430
|
where: this.andNodes(selectQueryNode.where, where)
|
|
5356
5431
|
};
|
|
5357
|
-
const compiled =
|
|
5432
|
+
const compiled = this.compileQuery(selectQueryNode);
|
|
5433
|
+
const result = await this.executeQuery(compiled, {
|
|
5358
5434
|
queryId: `zenstack-${nanoid2()}`
|
|
5359
5435
|
});
|
|
5360
|
-
const result = await kysely.executeQuery(compiled);
|
|
5361
5436
|
return result.rows;
|
|
5362
5437
|
}
|
|
5363
5438
|
andNodes(condition1, condition2) {
|
|
@@ -5386,8 +5461,8 @@ __export(functions_exports, {
|
|
|
5386
5461
|
search: () => search,
|
|
5387
5462
|
startsWith: () => startsWith
|
|
5388
5463
|
});
|
|
5464
|
+
import { invariant as invariant9, lowerCaseFirst, upperCaseFirst } from "@zenstackhq/common-helpers";
|
|
5389
5465
|
import { sql as sql8, ValueNode as ValueNode4 } from "kysely";
|
|
5390
|
-
import invariant8 from "tiny-invariant";
|
|
5391
5466
|
import { match as match16 } from "ts-pattern";
|
|
5392
5467
|
var contains = /* @__PURE__ */ __name((eb, args) => {
|
|
5393
5468
|
const [field, search2, caseInsensitive = false] = args;
|
|
@@ -5493,8 +5568,8 @@ var currentOperation = /* @__PURE__ */ __name((_eb, args, { operation }) => {
|
|
|
5493
5568
|
}, "currentOperation");
|
|
5494
5569
|
function processCasing(casing, result, model) {
|
|
5495
5570
|
const opNode = casing.toOperationNode();
|
|
5496
|
-
|
|
5497
|
-
result = match16(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () =>
|
|
5571
|
+
invariant9(ValueNode4.is(opNode) && typeof opNode.value === "string", '"casting" parameter must be a string value');
|
|
5572
|
+
result = match16(opNode.value).with("original", () => model).with("upper", () => result.toUpperCase()).with("lower", () => result.toLowerCase()).with("capitalize", () => upperCaseFirst(result)).with("uncapitalize", () => lowerCaseFirst(result)).otherwise(() => {
|
|
5498
5573
|
throw new Error(`Invalid casing value: ${opNode.value}. Must be "original", "upper", "lower", "capitalize", or "uncapitalize".`);
|
|
5499
5574
|
});
|
|
5500
5575
|
return result;
|
|
@@ -5502,8 +5577,8 @@ function processCasing(casing, result, model) {
|
|
|
5502
5577
|
__name(processCasing, "processCasing");
|
|
5503
5578
|
|
|
5504
5579
|
// src/client/helpers/schema-db-pusher.ts
|
|
5580
|
+
import { invariant as invariant10 } from "@zenstackhq/common-helpers";
|
|
5505
5581
|
import { sql as sql9 } from "kysely";
|
|
5506
|
-
import invariant9 from "tiny-invariant";
|
|
5507
5582
|
import { match as match17 } from "ts-pattern";
|
|
5508
5583
|
var SchemaDbPusher = class {
|
|
5509
5584
|
static {
|
|
@@ -5535,7 +5610,7 @@ var SchemaDbPusher = class {
|
|
|
5535
5610
|
for (const [fieldName, fieldDef] of Object.entries(modelDef.fields)) {
|
|
5536
5611
|
if (fieldDef.relation) {
|
|
5537
5612
|
table = this.addForeignKeyConstraint(table, model, fieldName, fieldDef);
|
|
5538
|
-
} else {
|
|
5613
|
+
} else if (!this.isComputedField(fieldDef)) {
|
|
5539
5614
|
table = this.createModelField(table, fieldName, fieldDef, modelDef);
|
|
5540
5615
|
}
|
|
5541
5616
|
}
|
|
@@ -5543,6 +5618,9 @@ var SchemaDbPusher = class {
|
|
|
5543
5618
|
table = this.addUniqueConstraint(table, modelDef);
|
|
5544
5619
|
return table;
|
|
5545
5620
|
}
|
|
5621
|
+
isComputedField(fieldDef) {
|
|
5622
|
+
return fieldDef.attributes?.some((a) => a.name === "@computed");
|
|
5623
|
+
}
|
|
5546
5624
|
addPrimaryKeyConstraint(table, model, modelDef) {
|
|
5547
5625
|
if (modelDef.idFields.length === 1) {
|
|
5548
5626
|
if (Object.values(modelDef.fields).some((f) => f.id)) {
|
|
@@ -5556,7 +5634,7 @@ var SchemaDbPusher = class {
|
|
|
5556
5634
|
}
|
|
5557
5635
|
addUniqueConstraint(table, modelDef) {
|
|
5558
5636
|
for (const [key, value] of Object.entries(modelDef.uniqueFields)) {
|
|
5559
|
-
|
|
5637
|
+
invariant10(typeof value === "object", "expecting an object");
|
|
5560
5638
|
if ("type" in value) {
|
|
5561
5639
|
const fieldDef = modelDef.fields[key];
|
|
5562
5640
|
if (fieldDef.unique) {
|
|
@@ -5602,7 +5680,7 @@ var SchemaDbPusher = class {
|
|
|
5602
5680
|
return "serial";
|
|
5603
5681
|
}
|
|
5604
5682
|
const type = fieldDef.type;
|
|
5605
|
-
const result = match17(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").otherwise(() => {
|
|
5683
|
+
const result = match17(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(() => {
|
|
5606
5684
|
throw new Error(`Unsupported field type: ${type}`);
|
|
5607
5685
|
});
|
|
5608
5686
|
if (fieldDef.array) {
|
|
@@ -5615,7 +5693,7 @@ var SchemaDbPusher = class {
|
|
|
5615
5693
|
return fieldDef.default && ExpressionUtils.isCall(fieldDef.default) && fieldDef.default.function === "autoincrement";
|
|
5616
5694
|
}
|
|
5617
5695
|
addForeignKeyConstraint(table, model, fieldName, fieldDef) {
|
|
5618
|
-
|
|
5696
|
+
invariant10(fieldDef.relation, "field must be a relation");
|
|
5619
5697
|
if (!fieldDef.relation.fields || !fieldDef.relation.references) {
|
|
5620
5698
|
return table;
|
|
5621
5699
|
}
|
|
@@ -5636,11 +5714,11 @@ var SchemaDbPusher = class {
|
|
|
5636
5714
|
};
|
|
5637
5715
|
|
|
5638
5716
|
// src/client/promise.ts
|
|
5639
|
-
function
|
|
5717
|
+
function createZenStackPromise(callback) {
|
|
5640
5718
|
let promise;
|
|
5641
|
-
const cb = /* @__PURE__ */ __name(() => {
|
|
5719
|
+
const cb = /* @__PURE__ */ __name((txClient) => {
|
|
5642
5720
|
try {
|
|
5643
|
-
return promise ??= valueToPromise(callback());
|
|
5721
|
+
return promise ??= valueToPromise(callback(txClient));
|
|
5644
5722
|
} catch (err) {
|
|
5645
5723
|
return Promise.reject(err);
|
|
5646
5724
|
}
|
|
@@ -5655,10 +5733,11 @@ function createDeferredPromise(callback) {
|
|
|
5655
5733
|
finally(onFinally) {
|
|
5656
5734
|
return cb().finally(onFinally);
|
|
5657
5735
|
},
|
|
5736
|
+
cb,
|
|
5658
5737
|
[Symbol.toStringTag]: "ZenStackPromise"
|
|
5659
5738
|
};
|
|
5660
5739
|
}
|
|
5661
|
-
__name(
|
|
5740
|
+
__name(createZenStackPromise, "createZenStackPromise");
|
|
5662
5741
|
function valueToPromise(thing) {
|
|
5663
5742
|
if (typeof thing === "object" && typeof thing?.then === "function") {
|
|
5664
5743
|
return thing;
|
|
@@ -5669,8 +5748,8 @@ function valueToPromise(thing) {
|
|
|
5669
5748
|
__name(valueToPromise, "valueToPromise");
|
|
5670
5749
|
|
|
5671
5750
|
// src/client/result-processor.ts
|
|
5751
|
+
import { invariant as invariant11 } from "@zenstackhq/common-helpers";
|
|
5672
5752
|
import Decimal2 from "decimal.js";
|
|
5673
|
-
import invariant10 from "tiny-invariant";
|
|
5674
5753
|
import { match as match18 } from "ts-pattern";
|
|
5675
5754
|
var ResultProcessor = class {
|
|
5676
5755
|
static {
|
|
@@ -5744,20 +5823,20 @@ var ResultProcessor = class {
|
|
|
5744
5823
|
return this.doProcessResult(relationData, fieldDef.type);
|
|
5745
5824
|
}
|
|
5746
5825
|
transformScalar(value, type) {
|
|
5747
|
-
return match18(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)).otherwise(() => value);
|
|
5826
|
+
return match18(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);
|
|
5748
5827
|
}
|
|
5749
5828
|
transformDecimal(value) {
|
|
5750
5829
|
if (value instanceof Decimal2) {
|
|
5751
5830
|
return value;
|
|
5752
5831
|
}
|
|
5753
|
-
|
|
5832
|
+
invariant11(typeof value === "string" || typeof value === "number" || value instanceof Decimal2, `Expected string, number or Decimal, got ${typeof value}`);
|
|
5754
5833
|
return new Decimal2(value);
|
|
5755
5834
|
}
|
|
5756
5835
|
transformBigInt(value) {
|
|
5757
5836
|
if (typeof value === "bigint") {
|
|
5758
5837
|
return value;
|
|
5759
5838
|
}
|
|
5760
|
-
|
|
5839
|
+
invariant11(typeof value === "string" || typeof value === "number", `Expected string or number, got ${typeof value}`);
|
|
5761
5840
|
return BigInt(value);
|
|
5762
5841
|
}
|
|
5763
5842
|
transformBoolean(value) {
|
|
@@ -5776,6 +5855,9 @@ var ResultProcessor = class {
|
|
|
5776
5855
|
return Buffer.isBuffer(value) ? Uint8Array.from(value) : value;
|
|
5777
5856
|
}
|
|
5778
5857
|
fixReversedResult(data, model, args) {
|
|
5858
|
+
if (!data) {
|
|
5859
|
+
return;
|
|
5860
|
+
}
|
|
5779
5861
|
if (Array.isArray(data) && typeof args === "object" && args && args.take !== void 0 && args.take < 0) {
|
|
5780
5862
|
data.reverse();
|
|
5781
5863
|
}
|
|
@@ -5789,13 +5871,19 @@ var ResultProcessor = class {
|
|
|
5789
5871
|
continue;
|
|
5790
5872
|
}
|
|
5791
5873
|
const fieldDef = getField(this.schema, model, field);
|
|
5792
|
-
if (!fieldDef
|
|
5874
|
+
if (!fieldDef || !fieldDef.relation || !fieldDef.array) {
|
|
5793
5875
|
continue;
|
|
5794
5876
|
}
|
|
5795
5877
|
this.fixReversedResult(row[field], fieldDef.type, value);
|
|
5796
5878
|
}
|
|
5797
5879
|
}
|
|
5798
5880
|
}
|
|
5881
|
+
transformJson(value) {
|
|
5882
|
+
return match18(this.schema.provider.type).with("sqlite", () => {
|
|
5883
|
+
invariant11(typeof value === "string", "Expected string, got " + typeof value);
|
|
5884
|
+
return JSON.parse(value);
|
|
5885
|
+
}).otherwise(() => value);
|
|
5886
|
+
}
|
|
5799
5887
|
};
|
|
5800
5888
|
|
|
5801
5889
|
// src/client/client-impl.ts
|
|
@@ -5814,7 +5902,7 @@ var ClientImpl = class _ClientImpl {
|
|
|
5814
5902
|
$schema;
|
|
5815
5903
|
kyselyProps;
|
|
5816
5904
|
auth;
|
|
5817
|
-
constructor(schema, options, baseClient) {
|
|
5905
|
+
constructor(schema, options, baseClient, executor) {
|
|
5818
5906
|
this.schema = schema;
|
|
5819
5907
|
this.options = options;
|
|
5820
5908
|
this.$schema = schema;
|
|
@@ -5826,16 +5914,16 @@ var ClientImpl = class _ClientImpl {
|
|
|
5826
5914
|
if (baseClient) {
|
|
5827
5915
|
this.kyselyProps = {
|
|
5828
5916
|
...baseClient.kyselyProps,
|
|
5829
|
-
executor: new ZenStackQueryExecutor(this, baseClient.kyselyProps.driver, baseClient.kyselyProps.dialect.createQueryCompiler(), baseClient.kyselyProps.dialect.createAdapter(), new DefaultConnectionProvider(baseClient.kyselyProps.driver))
|
|
5917
|
+
executor: executor ?? new ZenStackQueryExecutor(this, baseClient.kyselyProps.driver, baseClient.kyselyProps.dialect.createQueryCompiler(), baseClient.kyselyProps.dialect.createAdapter(), new DefaultConnectionProvider(baseClient.kyselyProps.driver))
|
|
5830
5918
|
};
|
|
5831
5919
|
this.kyselyRaw = baseClient.kyselyRaw;
|
|
5920
|
+
this.auth = baseClient.auth;
|
|
5832
5921
|
} else {
|
|
5833
5922
|
const dialect = this.getKyselyDialect();
|
|
5834
5923
|
const driver = new ZenStackDriver(dialect.createDriver(), new Log(this.$options.log ?? []));
|
|
5835
5924
|
const compiler = dialect.createQueryCompiler();
|
|
5836
5925
|
const adapter = dialect.createAdapter();
|
|
5837
5926
|
const connectionProvider = new DefaultConnectionProvider(driver);
|
|
5838
|
-
const executor = new ZenStackQueryExecutor(this, driver, compiler, adapter, connectionProvider);
|
|
5839
5927
|
this.kyselyProps = {
|
|
5840
5928
|
config: {
|
|
5841
5929
|
dialect,
|
|
@@ -5843,7 +5931,7 @@ var ClientImpl = class _ClientImpl {
|
|
|
5843
5931
|
},
|
|
5844
5932
|
dialect,
|
|
5845
5933
|
driver,
|
|
5846
|
-
executor
|
|
5934
|
+
executor: executor ?? new ZenStackQueryExecutor(this, driver, compiler, adapter, connectionProvider)
|
|
5847
5935
|
};
|
|
5848
5936
|
this.kyselyRaw = new Kysely({
|
|
5849
5937
|
...this.kyselyProps,
|
|
@@ -5859,31 +5947,67 @@ var ClientImpl = class _ClientImpl {
|
|
|
5859
5947
|
get $qbRaw() {
|
|
5860
5948
|
return this.kyselyRaw;
|
|
5861
5949
|
}
|
|
5950
|
+
get isTransaction() {
|
|
5951
|
+
return this.kysely.isTransaction;
|
|
5952
|
+
}
|
|
5953
|
+
/**
|
|
5954
|
+
* Create a new client with a new query executor.
|
|
5955
|
+
*/
|
|
5956
|
+
withExecutor(executor) {
|
|
5957
|
+
return new _ClientImpl(this.schema, this.$options, this, executor);
|
|
5958
|
+
}
|
|
5862
5959
|
getKyselyDialect() {
|
|
5863
5960
|
return match19(this.schema.provider.type).with("sqlite", () => this.makeSqliteKyselyDialect()).with("postgresql", () => this.makePostgresKyselyDialect()).exhaustive();
|
|
5864
5961
|
}
|
|
5865
5962
|
makePostgresKyselyDialect() {
|
|
5866
|
-
|
|
5867
|
-
const mergedConfig = {
|
|
5868
|
-
...dialectConfigProvider(),
|
|
5869
|
-
...this.options?.dialectConfig
|
|
5870
|
-
};
|
|
5871
|
-
return new PostgresDialect(mergedConfig);
|
|
5963
|
+
return new PostgresDialect(this.options.dialectConfig);
|
|
5872
5964
|
}
|
|
5873
5965
|
makeSqliteKyselyDialect() {
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
|
|
5966
|
+
return new SqliteDialect(this.options.dialectConfig);
|
|
5967
|
+
}
|
|
5968
|
+
// implementation
|
|
5969
|
+
async $transaction(input, options) {
|
|
5970
|
+
invariant12(typeof input === "function" || Array.isArray(input) && input.every((p) => p.then && p.cb), "Invalid transaction input, expected a function or an array of ZenStackPromise");
|
|
5971
|
+
if (typeof input === "function") {
|
|
5972
|
+
return this.interactiveTransaction(input, options);
|
|
5973
|
+
} else {
|
|
5974
|
+
return this.sequentialTransaction(input, options);
|
|
5975
|
+
}
|
|
5976
|
+
}
|
|
5977
|
+
async interactiveTransaction(callback, options) {
|
|
5978
|
+
if (this.kysely.isTransaction) {
|
|
5979
|
+
return callback(this);
|
|
5980
|
+
} else {
|
|
5981
|
+
let txBuilder = this.kysely.transaction();
|
|
5982
|
+
if (options?.isolationLevel) {
|
|
5983
|
+
txBuilder = txBuilder.setIsolationLevel(options.isolationLevel);
|
|
5984
|
+
}
|
|
5985
|
+
return txBuilder.execute((tx) => {
|
|
5986
|
+
const txClient = new _ClientImpl(this.schema, this.$options, this);
|
|
5987
|
+
txClient.kysely = tx;
|
|
5988
|
+
return callback(txClient);
|
|
5989
|
+
});
|
|
5990
|
+
}
|
|
5880
5991
|
}
|
|
5881
|
-
async
|
|
5882
|
-
|
|
5883
|
-
const txClient = new _ClientImpl(this.schema, this.$options);
|
|
5992
|
+
async sequentialTransaction(arg, options) {
|
|
5993
|
+
const execute = /* @__PURE__ */ __name(async (tx) => {
|
|
5994
|
+
const txClient = new _ClientImpl(this.schema, this.$options, this);
|
|
5884
5995
|
txClient.kysely = tx;
|
|
5885
|
-
|
|
5886
|
-
|
|
5996
|
+
const result = [];
|
|
5997
|
+
for (const promise of arg) {
|
|
5998
|
+
result.push(await promise.cb(txClient));
|
|
5999
|
+
}
|
|
6000
|
+
return result;
|
|
6001
|
+
}, "execute");
|
|
6002
|
+
if (this.kysely.isTransaction) {
|
|
6003
|
+
return execute(this.kysely);
|
|
6004
|
+
} else {
|
|
6005
|
+
let txBuilder = this.kysely.transaction();
|
|
6006
|
+
if (options?.isolationLevel) {
|
|
6007
|
+
txBuilder = txBuilder.setIsolationLevel(options.isolationLevel);
|
|
6008
|
+
}
|
|
6009
|
+
return txBuilder.execute((tx) => execute(tx));
|
|
6010
|
+
}
|
|
5887
6011
|
}
|
|
5888
6012
|
get $procedures() {
|
|
5889
6013
|
return Object.keys(this.$schema.procedures ?? {}).reduce((acc, name) => {
|
|
@@ -5914,12 +6038,19 @@ var ClientImpl = class _ClientImpl {
|
|
|
5914
6038
|
const newOptions = {
|
|
5915
6039
|
...this.options,
|
|
5916
6040
|
plugins: [
|
|
5917
|
-
...this.options
|
|
6041
|
+
...this.options.plugins ?? [],
|
|
5918
6042
|
plugin
|
|
5919
6043
|
]
|
|
5920
6044
|
};
|
|
5921
6045
|
return new _ClientImpl(this.schema, newOptions, this);
|
|
5922
6046
|
}
|
|
6047
|
+
$unuse(pluginId) {
|
|
6048
|
+
const newOptions = {
|
|
6049
|
+
...this.options,
|
|
6050
|
+
plugins: this.options.plugins?.filter((p) => p.id !== pluginId)
|
|
6051
|
+
};
|
|
6052
|
+
return new _ClientImpl(this.schema, newOptions, this);
|
|
6053
|
+
}
|
|
5923
6054
|
$unuseAll() {
|
|
5924
6055
|
const newOptions = {
|
|
5925
6056
|
...this.options,
|
|
@@ -5938,6 +6069,39 @@ var ClientImpl = class _ClientImpl {
|
|
|
5938
6069
|
get $auth() {
|
|
5939
6070
|
return this.auth;
|
|
5940
6071
|
}
|
|
6072
|
+
$executeRaw(query, ...values) {
|
|
6073
|
+
return createZenStackPromise(async () => {
|
|
6074
|
+
const result = await sql10(query, ...values).execute(this.kysely);
|
|
6075
|
+
return Number(result.numAffectedRows ?? 0);
|
|
6076
|
+
});
|
|
6077
|
+
}
|
|
6078
|
+
$executeRawUnsafe(query, ...values) {
|
|
6079
|
+
return createZenStackPromise(async () => {
|
|
6080
|
+
const compiledQuery = this.createRawCompiledQuery(query, values);
|
|
6081
|
+
const result = await this.kysely.executeQuery(compiledQuery);
|
|
6082
|
+
return Number(result.numAffectedRows ?? 0);
|
|
6083
|
+
});
|
|
6084
|
+
}
|
|
6085
|
+
$queryRaw(query, ...values) {
|
|
6086
|
+
return createZenStackPromise(async () => {
|
|
6087
|
+
const result = await sql10(query, ...values).execute(this.kysely);
|
|
6088
|
+
return result.rows;
|
|
6089
|
+
});
|
|
6090
|
+
}
|
|
6091
|
+
$queryRawUnsafe(query, ...values) {
|
|
6092
|
+
return createZenStackPromise(async () => {
|
|
6093
|
+
const compiledQuery = this.createRawCompiledQuery(query, values);
|
|
6094
|
+
const result = await this.kysely.executeQuery(compiledQuery);
|
|
6095
|
+
return result.rows;
|
|
6096
|
+
});
|
|
6097
|
+
}
|
|
6098
|
+
createRawCompiledQuery(query, values) {
|
|
6099
|
+
const q = CompiledQuery.raw(query, values);
|
|
6100
|
+
return {
|
|
6101
|
+
...q,
|
|
6102
|
+
$raw: true
|
|
6103
|
+
};
|
|
6104
|
+
}
|
|
5941
6105
|
};
|
|
5942
6106
|
function createClientProxy(client) {
|
|
5943
6107
|
const inputValidator = new InputValidator(client.$schema);
|
|
@@ -5960,9 +6124,9 @@ function createClientProxy(client) {
|
|
|
5960
6124
|
__name(createClientProxy, "createClientProxy");
|
|
5961
6125
|
function createModelCrudHandler(client, model, inputValidator, resultProcessor) {
|
|
5962
6126
|
const createPromise = /* @__PURE__ */ __name((operation, args, handler, postProcess = false, throwIfNoResult = false) => {
|
|
5963
|
-
return
|
|
5964
|
-
let proceed = /* @__PURE__ */ __name(async (_args
|
|
5965
|
-
const _handler =
|
|
6127
|
+
return createZenStackPromise(async (txClient) => {
|
|
6128
|
+
let proceed = /* @__PURE__ */ __name(async (_args) => {
|
|
6129
|
+
const _handler = txClient ? handler.withClient(txClient) : handler;
|
|
5966
6130
|
const r = await _handler.handle(operation, _args ?? args);
|
|
5967
6131
|
if (!r && throwIfNoResult) {
|
|
5968
6132
|
throw new NotFoundError(model);
|
|
@@ -5975,22 +6139,31 @@ function createModelCrudHandler(client, model, inputValidator, resultProcessor)
|
|
|
5975
6139
|
}
|
|
5976
6140
|
return result;
|
|
5977
6141
|
}, "proceed");
|
|
5978
|
-
const context = {
|
|
5979
|
-
client,
|
|
5980
|
-
model,
|
|
5981
|
-
operation,
|
|
5982
|
-
queryArgs: args
|
|
5983
|
-
};
|
|
5984
6142
|
const plugins = [
|
|
5985
6143
|
...client.$options.plugins ?? []
|
|
5986
6144
|
];
|
|
5987
6145
|
for (const plugin of plugins) {
|
|
5988
|
-
if (plugin.onQuery) {
|
|
5989
|
-
const
|
|
5990
|
-
|
|
5991
|
-
|
|
5992
|
-
|
|
5993
|
-
|
|
6146
|
+
if (plugin.onQuery && typeof plugin.onQuery === "object") {
|
|
6147
|
+
for (const [_model, modelHooks] of Object.entries(plugin.onQuery)) {
|
|
6148
|
+
if (_model === lowerCaseFirst2(model) || _model === "$allModels") {
|
|
6149
|
+
if (modelHooks && typeof modelHooks === "object") {
|
|
6150
|
+
for (const [op, opHooks] of Object.entries(modelHooks)) {
|
|
6151
|
+
if (op === operation || op === "$allOperations") {
|
|
6152
|
+
if (typeof opHooks === "function") {
|
|
6153
|
+
const _proceed = proceed;
|
|
6154
|
+
proceed = /* @__PURE__ */ __name(() => opHooks({
|
|
6155
|
+
client,
|
|
6156
|
+
model,
|
|
6157
|
+
operation,
|
|
6158
|
+
args,
|
|
6159
|
+
query: _proceed
|
|
6160
|
+
}), "proceed");
|
|
6161
|
+
}
|
|
6162
|
+
}
|
|
6163
|
+
}
|
|
6164
|
+
}
|
|
6165
|
+
}
|
|
6166
|
+
}
|
|
5994
6167
|
}
|
|
5995
6168
|
}
|
|
5996
6169
|
return proceed(args);
|
|
@@ -6046,12 +6219,23 @@ function createModelCrudHandler(client, model, inputValidator, resultProcessor)
|
|
|
6046
6219
|
return createPromise("aggregate", args, new AggregateOperationHandler(client, model, inputValidator), false);
|
|
6047
6220
|
}, "aggregate"),
|
|
6048
6221
|
groupBy: /* @__PURE__ */ __name((args) => {
|
|
6049
|
-
return createPromise("groupBy", args, new
|
|
6222
|
+
return createPromise("groupBy", args, new GroupByOperationHandler(client, model, inputValidator));
|
|
6050
6223
|
}, "groupBy")
|
|
6051
6224
|
};
|
|
6052
6225
|
}
|
|
6053
6226
|
__name(createModelCrudHandler, "createModelCrudHandler");
|
|
6227
|
+
|
|
6228
|
+
// src/client/plugin.ts
|
|
6229
|
+
function definePlugin(plugin) {
|
|
6230
|
+
return plugin;
|
|
6231
|
+
}
|
|
6232
|
+
__name(definePlugin, "definePlugin");
|
|
6054
6233
|
export {
|
|
6055
|
-
|
|
6234
|
+
InputValidationError,
|
|
6235
|
+
InternalError,
|
|
6236
|
+
NotFoundError,
|
|
6237
|
+
QueryError,
|
|
6238
|
+
ZenStackClient,
|
|
6239
|
+
definePlugin
|
|
6056
6240
|
};
|
|
6057
6241
|
//# sourceMappingURL=index.js.map
|