@zenstackhq/runtime 3.0.0-alpha.11 → 3.0.0-alpha.13
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-BQGRBbOU.d.cts → contract-CBOBlAuw.d.cts} +82 -51
- package/dist/{contract-BQGRBbOU.d.ts → contract-CBOBlAuw.d.ts} +82 -51
- package/dist/index.cjs +664 -243
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +664 -243
- package/dist/index.js.map +1 -1
- package/dist/plugins/{policy.cjs → policy/index.cjs} +225 -125
- package/dist/plugins/policy/index.cjs.map +1 -0
- package/dist/plugins/{policy.d.ts → policy/index.d.cts} +1 -1
- package/dist/plugins/{policy.d.cts → policy/index.d.ts} +1 -1
- package/dist/plugins/{policy.js → policy/index.js} +225 -125
- package/dist/plugins/policy/index.js.map +1 -0
- package/dist/plugins/policy/plugin.zmodel +33 -0
- package/package.json +12 -12
- package/dist/plugins/policy.cjs.map +0 -1
- package/dist/plugins/policy.js.map +0 -1
|
@@ -26,6 +26,88 @@ import { invariant as invariant2 } from "@zenstackhq/common-helpers";
|
|
|
26
26
|
import { sql as sql2 } from "kysely";
|
|
27
27
|
import { match as match2 } from "ts-pattern";
|
|
28
28
|
|
|
29
|
+
// src/client/constants.ts
|
|
30
|
+
var DELEGATE_JOINED_FIELD_PREFIX = "$delegate$";
|
|
31
|
+
|
|
32
|
+
// src/schema/expression.ts
|
|
33
|
+
var ExpressionUtils = {
|
|
34
|
+
literal: /* @__PURE__ */ __name((value) => {
|
|
35
|
+
return {
|
|
36
|
+
kind: "literal",
|
|
37
|
+
value
|
|
38
|
+
};
|
|
39
|
+
}, "literal"),
|
|
40
|
+
array: /* @__PURE__ */ __name((items) => {
|
|
41
|
+
return {
|
|
42
|
+
kind: "array",
|
|
43
|
+
items
|
|
44
|
+
};
|
|
45
|
+
}, "array"),
|
|
46
|
+
call: /* @__PURE__ */ __name((functionName, args) => {
|
|
47
|
+
return {
|
|
48
|
+
kind: "call",
|
|
49
|
+
function: functionName,
|
|
50
|
+
args
|
|
51
|
+
};
|
|
52
|
+
}, "call"),
|
|
53
|
+
binary: /* @__PURE__ */ __name((left, op, right) => {
|
|
54
|
+
return {
|
|
55
|
+
kind: "binary",
|
|
56
|
+
op,
|
|
57
|
+
left,
|
|
58
|
+
right
|
|
59
|
+
};
|
|
60
|
+
}, "binary"),
|
|
61
|
+
unary: /* @__PURE__ */ __name((op, operand) => {
|
|
62
|
+
return {
|
|
63
|
+
kind: "unary",
|
|
64
|
+
op,
|
|
65
|
+
operand
|
|
66
|
+
};
|
|
67
|
+
}, "unary"),
|
|
68
|
+
field: /* @__PURE__ */ __name((field) => {
|
|
69
|
+
return {
|
|
70
|
+
kind: "field",
|
|
71
|
+
field
|
|
72
|
+
};
|
|
73
|
+
}, "field"),
|
|
74
|
+
member: /* @__PURE__ */ __name((receiver, members) => {
|
|
75
|
+
return {
|
|
76
|
+
kind: "member",
|
|
77
|
+
receiver,
|
|
78
|
+
members
|
|
79
|
+
};
|
|
80
|
+
}, "member"),
|
|
81
|
+
_this: /* @__PURE__ */ __name(() => {
|
|
82
|
+
return {
|
|
83
|
+
kind: "this"
|
|
84
|
+
};
|
|
85
|
+
}, "_this"),
|
|
86
|
+
_null: /* @__PURE__ */ __name(() => {
|
|
87
|
+
return {
|
|
88
|
+
kind: "null"
|
|
89
|
+
};
|
|
90
|
+
}, "_null"),
|
|
91
|
+
and: /* @__PURE__ */ __name((expr2, ...expressions) => {
|
|
92
|
+
return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "&&", exp), expr2);
|
|
93
|
+
}, "and"),
|
|
94
|
+
or: /* @__PURE__ */ __name((expr2, ...expressions) => {
|
|
95
|
+
return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "||", exp), expr2);
|
|
96
|
+
}, "or"),
|
|
97
|
+
is: /* @__PURE__ */ __name((value, kind) => {
|
|
98
|
+
return !!value && typeof value === "object" && "kind" in value && value.kind === kind;
|
|
99
|
+
}, "is"),
|
|
100
|
+
isLiteral: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "literal"), "isLiteral"),
|
|
101
|
+
isArray: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "array"), "isArray"),
|
|
102
|
+
isCall: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "call"), "isCall"),
|
|
103
|
+
isNull: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "null"), "isNull"),
|
|
104
|
+
isThis: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "this"), "isThis"),
|
|
105
|
+
isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
|
|
106
|
+
isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
|
|
107
|
+
isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
|
|
108
|
+
isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
|
|
109
|
+
};
|
|
110
|
+
|
|
29
111
|
// src/client/errors.ts
|
|
30
112
|
var QueryError = class extends Error {
|
|
31
113
|
static {
|
|
@@ -44,10 +126,6 @@ var InternalError = class extends Error {
|
|
|
44
126
|
};
|
|
45
127
|
|
|
46
128
|
// src/client/query-utils.ts
|
|
47
|
-
function getModel(schema, model) {
|
|
48
|
-
return schema.models[model];
|
|
49
|
-
}
|
|
50
|
-
__name(getModel, "getModel");
|
|
51
129
|
function requireModel(schema, model) {
|
|
52
130
|
const matchedName = Object.keys(schema.models).find((k) => k.toLowerCase() === model.toLowerCase());
|
|
53
131
|
if (!matchedName) {
|
|
@@ -56,11 +134,6 @@ function requireModel(schema, model) {
|
|
|
56
134
|
return schema.models[matchedName];
|
|
57
135
|
}
|
|
58
136
|
__name(requireModel, "requireModel");
|
|
59
|
-
function getField(schema, model, field) {
|
|
60
|
-
const modelDef = getModel(schema, model);
|
|
61
|
-
return modelDef?.fields[field];
|
|
62
|
-
}
|
|
63
|
-
__name(getField, "getField");
|
|
64
137
|
function requireField(schema, model, field) {
|
|
65
138
|
const modelDef = requireModel(schema, model);
|
|
66
139
|
if (!modelDef.fields[field]) {
|
|
@@ -119,6 +192,11 @@ function isRelationField(schema, model, field) {
|
|
|
119
192
|
return !!fieldDef.relation;
|
|
120
193
|
}
|
|
121
194
|
__name(isRelationField, "isRelationField");
|
|
195
|
+
function isInheritedField(schema, model, field) {
|
|
196
|
+
const fieldDef = requireField(schema, model, field);
|
|
197
|
+
return !!fieldDef.originModel;
|
|
198
|
+
}
|
|
199
|
+
__name(isInheritedField, "isInheritedField");
|
|
122
200
|
function getUniqueFields(schema, model) {
|
|
123
201
|
const modelDef = requireModel(schema, model);
|
|
124
202
|
const result = [];
|
|
@@ -232,6 +310,19 @@ function flattenCompoundUniqueFilters(schema, model, filter) {
|
|
|
232
310
|
return result;
|
|
233
311
|
}
|
|
234
312
|
__name(flattenCompoundUniqueFilters, "flattenCompoundUniqueFilters");
|
|
313
|
+
function getDelegateDescendantModels(schema, model, collected = /* @__PURE__ */ new Set()) {
|
|
314
|
+
const subModels = Object.values(schema.models).filter((m) => m.baseModel === model);
|
|
315
|
+
subModels.forEach((def) => {
|
|
316
|
+
if (!collected.has(def)) {
|
|
317
|
+
collected.add(def);
|
|
318
|
+
getDelegateDescendantModels(schema, def.name, collected);
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
return [
|
|
322
|
+
...collected
|
|
323
|
+
];
|
|
324
|
+
}
|
|
325
|
+
__name(getDelegateDescendantModels, "getDelegateDescendantModels");
|
|
235
326
|
|
|
236
327
|
// src/client/crud/dialects/base.ts
|
|
237
328
|
import { invariant, isPlainObject } from "@zenstackhq/common-helpers";
|
|
@@ -266,6 +357,17 @@ var BaseCrudDialect = class {
|
|
|
266
357
|
transformPrimitive(value, _type, _forArrayField) {
|
|
267
358
|
return value;
|
|
268
359
|
}
|
|
360
|
+
// #region common query builders
|
|
361
|
+
buildSelectModel(eb, model) {
|
|
362
|
+
const modelDef = requireModel(this.schema, model);
|
|
363
|
+
let result = eb.selectFrom(model);
|
|
364
|
+
let joinBase = modelDef.baseModel;
|
|
365
|
+
while (joinBase) {
|
|
366
|
+
result = this.buildDelegateJoin(model, joinBase, result);
|
|
367
|
+
joinBase = requireModel(this.schema, joinBase).baseModel;
|
|
368
|
+
}
|
|
369
|
+
return result;
|
|
370
|
+
}
|
|
269
371
|
buildFilter(eb, model, modelAlias, where) {
|
|
270
372
|
if (where === true || where === void 0) {
|
|
271
373
|
return this.true(eb);
|
|
@@ -289,10 +391,13 @@ var BaseCrudDialect = class {
|
|
|
289
391
|
const fieldDef = requireField(this.schema, model, key);
|
|
290
392
|
if (fieldDef.relation) {
|
|
291
393
|
result = this.and(eb, result, this.buildRelationFilter(eb, model, modelAlias, key, fieldDef, payload));
|
|
292
|
-
} else if (fieldDef.array) {
|
|
293
|
-
result = this.and(eb, result, this.buildArrayFilter(eb, model, modelAlias, key, fieldDef, payload));
|
|
294
394
|
} else {
|
|
295
|
-
|
|
395
|
+
const fieldRef = buildFieldRef(this.schema, fieldDef.originModel ?? model, key, this.options, eb, fieldDef.originModel ?? modelAlias);
|
|
396
|
+
if (fieldDef.array) {
|
|
397
|
+
result = this.and(eb, result, this.buildArrayFilter(eb, fieldRef, fieldDef, payload));
|
|
398
|
+
} else {
|
|
399
|
+
result = this.and(eb, result, this.buildPrimitiveFilter(eb, fieldRef, fieldDef, payload));
|
|
400
|
+
}
|
|
296
401
|
}
|
|
297
402
|
}
|
|
298
403
|
if ("$expr" in _where && typeof _where["$expr"] === "function") {
|
|
@@ -310,19 +415,26 @@ var BaseCrudDialect = class {
|
|
|
310
415
|
return this.buildToManyRelationFilter(eb, model, modelAlias, field, fieldDef, payload);
|
|
311
416
|
}
|
|
312
417
|
}
|
|
313
|
-
buildToOneRelationFilter(eb, model,
|
|
418
|
+
buildToOneRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
|
|
314
419
|
if (payload === null) {
|
|
315
420
|
const { ownedByModel, keyPairs } = getRelationForeignKeyFieldPairs(this.schema, model, field);
|
|
316
|
-
if (ownedByModel) {
|
|
317
|
-
return this.and(eb, ...keyPairs.map(({ fk }) => eb(sql.ref(`${
|
|
421
|
+
if (ownedByModel && !fieldDef.originModel) {
|
|
422
|
+
return this.and(eb, ...keyPairs.map(({ fk }) => eb(sql.ref(`${modelAlias}.${fk}`), "is", null)));
|
|
318
423
|
} else {
|
|
319
|
-
return this.buildToOneRelationFilter(eb, model,
|
|
424
|
+
return this.buildToOneRelationFilter(eb, model, modelAlias, field, fieldDef, {
|
|
320
425
|
is: null
|
|
321
426
|
});
|
|
322
427
|
}
|
|
323
428
|
}
|
|
324
|
-
const joinAlias = `${
|
|
325
|
-
const joinPairs = buildJoinPairs(
|
|
429
|
+
const joinAlias = `${modelAlias}$${field}`;
|
|
430
|
+
const joinPairs = buildJoinPairs(
|
|
431
|
+
this.schema,
|
|
432
|
+
model,
|
|
433
|
+
// if field is from a base, use the base model to join
|
|
434
|
+
fieldDef.originModel ?? modelAlias,
|
|
435
|
+
field,
|
|
436
|
+
joinAlias
|
|
437
|
+
);
|
|
326
438
|
const filterResultField = `${field}$filter`;
|
|
327
439
|
const joinSelect = eb.selectFrom(`${fieldDef.type} as ${joinAlias}`).where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(sql.ref(left), "=", sql.ref(right))))).select(() => eb.fn.count(eb.lit(1)).as(filterResultField));
|
|
328
440
|
const conditions = [];
|
|
@@ -383,25 +495,24 @@ var BaseCrudDialect = class {
|
|
|
383
495
|
}
|
|
384
496
|
switch (key) {
|
|
385
497
|
case "some": {
|
|
386
|
-
result = this.and(eb, result, eb(
|
|
498
|
+
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));
|
|
387
499
|
break;
|
|
388
500
|
}
|
|
389
501
|
case "every": {
|
|
390
|
-
result = this.and(eb, result, eb(
|
|
502
|
+
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));
|
|
391
503
|
break;
|
|
392
504
|
}
|
|
393
505
|
case "none": {
|
|
394
|
-
result = this.and(eb, result, eb(
|
|
506
|
+
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));
|
|
395
507
|
break;
|
|
396
508
|
}
|
|
397
509
|
}
|
|
398
510
|
}
|
|
399
511
|
return result;
|
|
400
512
|
}
|
|
401
|
-
buildArrayFilter(eb,
|
|
513
|
+
buildArrayFilter(eb, fieldRef, fieldDef, payload) {
|
|
402
514
|
const clauses = [];
|
|
403
515
|
const fieldType = fieldDef.type;
|
|
404
|
-
const fieldRef = buildFieldRef(this.schema, model, field, this.options, eb, modelAlias);
|
|
405
516
|
for (const [key, _value] of Object.entries(payload)) {
|
|
406
517
|
if (_value === void 0) {
|
|
407
518
|
continue;
|
|
@@ -437,14 +548,14 @@ var BaseCrudDialect = class {
|
|
|
437
548
|
}
|
|
438
549
|
return this.and(eb, ...clauses);
|
|
439
550
|
}
|
|
440
|
-
buildPrimitiveFilter(eb,
|
|
551
|
+
buildPrimitiveFilter(eb, fieldRef, fieldDef, payload) {
|
|
441
552
|
if (payload === null) {
|
|
442
|
-
return eb(
|
|
553
|
+
return eb(fieldRef, "is", null);
|
|
443
554
|
}
|
|
444
555
|
if (isEnum(this.schema, fieldDef.type)) {
|
|
445
|
-
return this.buildEnumFilter(eb,
|
|
556
|
+
return this.buildEnumFilter(eb, fieldRef, fieldDef, payload);
|
|
446
557
|
}
|
|
447
|
-
return match(fieldDef.type).with("String", () => this.buildStringFilter(eb,
|
|
558
|
+
return match(fieldDef.type).with("String", () => this.buildStringFilter(eb, fieldRef, payload)).with(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", () => {
|
|
448
559
|
throw new InternalError("JSON filters are not supported yet");
|
|
449
560
|
}).with("Unsupported", () => {
|
|
450
561
|
throw new QueryError(`Unsupported field cannot be used in filters`);
|
|
@@ -500,9 +611,7 @@ var BaseCrudDialect = class {
|
|
|
500
611
|
consumedKeys
|
|
501
612
|
};
|
|
502
613
|
}
|
|
503
|
-
buildStringFilter(eb,
|
|
504
|
-
const fieldDef = getField(this.schema, table, field);
|
|
505
|
-
let fieldRef = fieldDef?.computed ? sql.ref(field) : sql.ref(`${table}.${field}`);
|
|
614
|
+
buildStringFilter(eb, fieldRef, payload) {
|
|
506
615
|
let insensitive = false;
|
|
507
616
|
if (payload && typeof payload === "object" && "mode" in payload && payload.mode === "insensitive") {
|
|
508
617
|
insensitive = true;
|
|
@@ -510,7 +619,7 @@ var BaseCrudDialect = class {
|
|
|
510
619
|
fieldRef
|
|
511
620
|
]);
|
|
512
621
|
}
|
|
513
|
-
const { conditions, consumedKeys } = this.buildStandardFilter(eb, "String", payload, fieldRef, (value) => this.prepStringCasing(eb, value, insensitive), (value) => this.buildStringFilter(eb,
|
|
622
|
+
const { conditions, consumedKeys } = this.buildStandardFilter(eb, "String", payload, fieldRef, (value) => this.prepStringCasing(eb, value, insensitive), (value) => this.buildStringFilter(eb, fieldRef, value));
|
|
514
623
|
if (payload && typeof payload === "object") {
|
|
515
624
|
for (const [key, value] of Object.entries(payload)) {
|
|
516
625
|
if (key === "mode" || consumedKeys.includes(key)) {
|
|
@@ -537,23 +646,23 @@ var BaseCrudDialect = class {
|
|
|
537
646
|
return value === null ? null : sql.lit(value);
|
|
538
647
|
}
|
|
539
648
|
}
|
|
540
|
-
buildNumberFilter(eb,
|
|
541
|
-
const { conditions } = this.buildStandardFilter(eb, type, payload,
|
|
649
|
+
buildNumberFilter(eb, fieldRef, type, payload) {
|
|
650
|
+
const { conditions } = this.buildStandardFilter(eb, type, payload, fieldRef, (value) => this.transformPrimitive(value, type, false), (value) => this.buildNumberFilter(eb, fieldRef, type, value));
|
|
542
651
|
return this.and(eb, ...conditions);
|
|
543
652
|
}
|
|
544
|
-
buildBooleanFilter(eb,
|
|
545
|
-
const { conditions } = this.buildStandardFilter(eb, "Boolean", payload,
|
|
653
|
+
buildBooleanFilter(eb, fieldRef, payload) {
|
|
654
|
+
const { conditions } = this.buildStandardFilter(eb, "Boolean", payload, fieldRef, (value) => this.transformPrimitive(value, "Boolean", false), (value) => this.buildBooleanFilter(eb, fieldRef, value), true, [
|
|
546
655
|
"equals",
|
|
547
656
|
"not"
|
|
548
657
|
]);
|
|
549
658
|
return this.and(eb, ...conditions);
|
|
550
659
|
}
|
|
551
|
-
buildDateTimeFilter(eb,
|
|
552
|
-
const { conditions } = this.buildStandardFilter(eb, "DateTime", payload,
|
|
660
|
+
buildDateTimeFilter(eb, fieldRef, payload) {
|
|
661
|
+
const { conditions } = this.buildStandardFilter(eb, "DateTime", payload, fieldRef, (value) => this.transformPrimitive(value, "DateTime", false), (value) => this.buildDateTimeFilter(eb, fieldRef, value), true);
|
|
553
662
|
return this.and(eb, ...conditions);
|
|
554
663
|
}
|
|
555
|
-
buildBytesFilter(eb,
|
|
556
|
-
const conditions = this.buildStandardFilter(eb, "Bytes", payload,
|
|
664
|
+
buildBytesFilter(eb, fieldRef, payload) {
|
|
665
|
+
const conditions = this.buildStandardFilter(eb, "Bytes", payload, fieldRef, (value) => this.transformPrimitive(value, "Bytes", false), (value) => this.buildBytesFilter(eb, fieldRef, value), true, [
|
|
557
666
|
"equals",
|
|
558
667
|
"in",
|
|
559
668
|
"notIn",
|
|
@@ -561,8 +670,8 @@ var BaseCrudDialect = class {
|
|
|
561
670
|
]);
|
|
562
671
|
return this.and(eb, ...conditions.conditions);
|
|
563
672
|
}
|
|
564
|
-
buildEnumFilter(eb,
|
|
565
|
-
const conditions = this.buildStandardFilter(eb, "String", payload,
|
|
673
|
+
buildEnumFilter(eb, fieldRef, fieldDef, payload) {
|
|
674
|
+
const conditions = this.buildStandardFilter(eb, "String", payload, fieldRef, (value) => value, (value) => this.buildEnumFilter(eb, fieldRef, fieldDef, value), true, [
|
|
566
675
|
"equals",
|
|
567
676
|
"in",
|
|
568
677
|
"notIn",
|
|
@@ -629,7 +738,7 @@ var BaseCrudDialect = class {
|
|
|
629
738
|
invariant(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
|
|
630
739
|
const sort = this.negateSort(value._count, negated);
|
|
631
740
|
result = result.orderBy((eb) => {
|
|
632
|
-
let subQuery =
|
|
741
|
+
let subQuery = this.buildSelectModel(eb, relationModel);
|
|
633
742
|
const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, relationModel);
|
|
634
743
|
subQuery = subQuery.where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(sql.ref(left), "=", sql.ref(right)))));
|
|
635
744
|
subQuery = subQuery.select(() => eb.fn.count(eb.lit(1)).as("_count"));
|
|
@@ -648,6 +757,56 @@ var BaseCrudDialect = class {
|
|
|
648
757
|
});
|
|
649
758
|
return result;
|
|
650
759
|
}
|
|
760
|
+
buildSelectAllFields(model, query, omit) {
|
|
761
|
+
const modelDef = requireModel(this.schema, model);
|
|
762
|
+
let result = query;
|
|
763
|
+
for (const field of Object.keys(modelDef.fields)) {
|
|
764
|
+
if (isRelationField(this.schema, model, field)) {
|
|
765
|
+
continue;
|
|
766
|
+
}
|
|
767
|
+
if (omit?.[field] === true) {
|
|
768
|
+
continue;
|
|
769
|
+
}
|
|
770
|
+
result = this.buildSelectField(result, model, model, field);
|
|
771
|
+
}
|
|
772
|
+
const descendants = getDelegateDescendantModels(this.schema, model);
|
|
773
|
+
for (const subModel of descendants) {
|
|
774
|
+
result = this.buildDelegateJoin(model, subModel.name, result);
|
|
775
|
+
result = result.select((eb) => {
|
|
776
|
+
const jsonObject = {};
|
|
777
|
+
for (const field of Object.keys(subModel.fields)) {
|
|
778
|
+
if (isRelationField(this.schema, subModel.name, field) || isInheritedField(this.schema, subModel.name, field)) {
|
|
779
|
+
continue;
|
|
780
|
+
}
|
|
781
|
+
jsonObject[field] = eb.ref(`${subModel.name}.${field}`);
|
|
782
|
+
}
|
|
783
|
+
return this.buildJsonObject(eb, jsonObject).as(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`);
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
return result;
|
|
787
|
+
}
|
|
788
|
+
buildSelectField(query, model, modelAlias, field) {
|
|
789
|
+
const fieldDef = requireField(this.schema, model, field);
|
|
790
|
+
if (fieldDef.computed) {
|
|
791
|
+
return query.select((eb) => buildFieldRef(this.schema, model, field, this.options, eb).as(field));
|
|
792
|
+
} else if (!fieldDef.originModel) {
|
|
793
|
+
return query.select(sql.ref(`${modelAlias}.${field}`).as(field));
|
|
794
|
+
} else {
|
|
795
|
+
return this.buildSelectField(query, fieldDef.originModel, fieldDef.originModel, field);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
buildDelegateJoin(thisModel, otherModel, query) {
|
|
799
|
+
const idFields = getIdFields(this.schema, thisModel);
|
|
800
|
+
query = query.leftJoin(otherModel, (qb) => {
|
|
801
|
+
for (const idField of idFields) {
|
|
802
|
+
qb = qb.onRef(`${thisModel}.${idField}`, "=", `${otherModel}.${idField}`);
|
|
803
|
+
}
|
|
804
|
+
return qb;
|
|
805
|
+
});
|
|
806
|
+
return query;
|
|
807
|
+
}
|
|
808
|
+
// #endregion
|
|
809
|
+
// #region utils
|
|
651
810
|
negateSort(sort, negated) {
|
|
652
811
|
return negated ? sort === "asc" ? "desc" : "asc" : sort;
|
|
653
812
|
}
|
|
@@ -729,7 +888,8 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
729
888
|
const joinTableName = `${parentName}$${relationField}`;
|
|
730
889
|
let result = eb.selectFrom(`${relationModel} as ${joinTableName}`);
|
|
731
890
|
result = eb.selectFrom(() => {
|
|
732
|
-
let subQuery =
|
|
891
|
+
let subQuery = this.buildSelectModel(eb, relationModel);
|
|
892
|
+
subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
|
|
733
893
|
if (payload && typeof payload === "object") {
|
|
734
894
|
if (payload.where) {
|
|
735
895
|
subQuery = subQuery.where((eb2) => this.buildFilter(eb2, relationModel, relationModel, payload.where));
|
|
@@ -776,6 +936,13 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
776
936
|
buildRelationObjectArgs(relationModel, relationField, eb, payload, parentName) {
|
|
777
937
|
const relationModelDef = requireModel(this.schema, relationModel);
|
|
778
938
|
const objArgs = [];
|
|
939
|
+
const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
|
|
940
|
+
if (descendantModels.length > 0) {
|
|
941
|
+
objArgs.push(...descendantModels.map((subModel) => [
|
|
942
|
+
sql2.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
|
|
943
|
+
eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
|
|
944
|
+
]).flatMap((v) => v));
|
|
945
|
+
}
|
|
779
946
|
if (payload === true || !payload.select) {
|
|
780
947
|
objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
|
|
781
948
|
sql2.lit(field),
|
|
@@ -868,7 +1035,11 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
868
1035
|
if (Array.isArray(value)) {
|
|
869
1036
|
return value.map((v) => this.transformPrimitive(v, type, false));
|
|
870
1037
|
} else {
|
|
871
|
-
|
|
1038
|
+
if (this.schema.typeDefs && type in this.schema.typeDefs) {
|
|
1039
|
+
return JSON.stringify(value);
|
|
1040
|
+
} else {
|
|
1041
|
+
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);
|
|
1042
|
+
}
|
|
872
1043
|
}
|
|
873
1044
|
}
|
|
874
1045
|
buildRelationSelection(query, model, relationField, parentAlias, payload) {
|
|
@@ -880,7 +1051,8 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
880
1051
|
const relationModelDef = requireModel(this.schema, relationModel);
|
|
881
1052
|
const subQueryName = `${parentName}$${relationField}`;
|
|
882
1053
|
let tbl = eb.selectFrom(() => {
|
|
883
|
-
let subQuery =
|
|
1054
|
+
let subQuery = this.buildSelectModel(eb, relationModel);
|
|
1055
|
+
subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
|
|
884
1056
|
if (payload && typeof payload === "object") {
|
|
885
1057
|
if (payload.where) {
|
|
886
1058
|
subQuery = subQuery.where((eb2) => this.buildFilter(eb2, relationModel, relationModel, payload.where));
|
|
@@ -916,6 +1088,13 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
916
1088
|
});
|
|
917
1089
|
tbl = tbl.select(() => {
|
|
918
1090
|
const objArgs = [];
|
|
1091
|
+
const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
|
|
1092
|
+
if (descendantModels.length > 0) {
|
|
1093
|
+
objArgs.push(...descendantModels.map((subModel) => [
|
|
1094
|
+
sql3.lit(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`),
|
|
1095
|
+
eb.ref(`${DELEGATE_JOINED_FIELD_PREFIX}${subModel.name}`)
|
|
1096
|
+
]).flatMap((v) => v));
|
|
1097
|
+
}
|
|
919
1098
|
if (payload === true || !payload.select) {
|
|
920
1099
|
objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
|
|
921
1100
|
sql3.lit(field),
|
|
@@ -998,85 +1177,6 @@ function getCrudDialect(schema, options) {
|
|
|
998
1177
|
}
|
|
999
1178
|
__name(getCrudDialect, "getCrudDialect");
|
|
1000
1179
|
|
|
1001
|
-
// src/schema/expression.ts
|
|
1002
|
-
var ExpressionUtils = {
|
|
1003
|
-
literal: /* @__PURE__ */ __name((value) => {
|
|
1004
|
-
return {
|
|
1005
|
-
kind: "literal",
|
|
1006
|
-
value
|
|
1007
|
-
};
|
|
1008
|
-
}, "literal"),
|
|
1009
|
-
array: /* @__PURE__ */ __name((items) => {
|
|
1010
|
-
return {
|
|
1011
|
-
kind: "array",
|
|
1012
|
-
items
|
|
1013
|
-
};
|
|
1014
|
-
}, "array"),
|
|
1015
|
-
call: /* @__PURE__ */ __name((functionName, args) => {
|
|
1016
|
-
return {
|
|
1017
|
-
kind: "call",
|
|
1018
|
-
function: functionName,
|
|
1019
|
-
args
|
|
1020
|
-
};
|
|
1021
|
-
}, "call"),
|
|
1022
|
-
binary: /* @__PURE__ */ __name((left, op, right) => {
|
|
1023
|
-
return {
|
|
1024
|
-
kind: "binary",
|
|
1025
|
-
op,
|
|
1026
|
-
left,
|
|
1027
|
-
right
|
|
1028
|
-
};
|
|
1029
|
-
}, "binary"),
|
|
1030
|
-
unary: /* @__PURE__ */ __name((op, operand) => {
|
|
1031
|
-
return {
|
|
1032
|
-
kind: "unary",
|
|
1033
|
-
op,
|
|
1034
|
-
operand
|
|
1035
|
-
};
|
|
1036
|
-
}, "unary"),
|
|
1037
|
-
field: /* @__PURE__ */ __name((field) => {
|
|
1038
|
-
return {
|
|
1039
|
-
kind: "field",
|
|
1040
|
-
field
|
|
1041
|
-
};
|
|
1042
|
-
}, "field"),
|
|
1043
|
-
member: /* @__PURE__ */ __name((receiver, members) => {
|
|
1044
|
-
return {
|
|
1045
|
-
kind: "member",
|
|
1046
|
-
receiver,
|
|
1047
|
-
members
|
|
1048
|
-
};
|
|
1049
|
-
}, "member"),
|
|
1050
|
-
_this: /* @__PURE__ */ __name(() => {
|
|
1051
|
-
return {
|
|
1052
|
-
kind: "this"
|
|
1053
|
-
};
|
|
1054
|
-
}, "_this"),
|
|
1055
|
-
_null: /* @__PURE__ */ __name(() => {
|
|
1056
|
-
return {
|
|
1057
|
-
kind: "null"
|
|
1058
|
-
};
|
|
1059
|
-
}, "_null"),
|
|
1060
|
-
and: /* @__PURE__ */ __name((expr2, ...expressions) => {
|
|
1061
|
-
return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "&&", exp), expr2);
|
|
1062
|
-
}, "and"),
|
|
1063
|
-
or: /* @__PURE__ */ __name((expr2, ...expressions) => {
|
|
1064
|
-
return expressions.reduce((acc, exp) => ExpressionUtils.binary(acc, "||", exp), expr2);
|
|
1065
|
-
}, "or"),
|
|
1066
|
-
is: /* @__PURE__ */ __name((value, kind) => {
|
|
1067
|
-
return !!value && typeof value === "object" && "kind" in value && value.kind === kind;
|
|
1068
|
-
}, "is"),
|
|
1069
|
-
isLiteral: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "literal"), "isLiteral"),
|
|
1070
|
-
isArray: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "array"), "isArray"),
|
|
1071
|
-
isCall: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "call"), "isCall"),
|
|
1072
|
-
isNull: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "null"), "isNull"),
|
|
1073
|
-
isThis: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "this"), "isThis"),
|
|
1074
|
-
isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
|
|
1075
|
-
isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
|
|
1076
|
-
isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
|
|
1077
|
-
isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
|
|
1078
|
-
};
|
|
1079
|
-
|
|
1080
1180
|
// src/utils/default-operation-node-visitor.ts
|
|
1081
1181
|
import { OperationNodeVisitor } from "kysely";
|
|
1082
1182
|
var DefaultOperationNodeVisitor = class extends OperationNodeVisitor {
|
|
@@ -2325,4 +2425,4 @@ export {
|
|
|
2325
2425
|
PolicyPlugin,
|
|
2326
2426
|
RejectedByPolicyError
|
|
2327
2427
|
};
|
|
2328
|
-
//# sourceMappingURL=
|
|
2428
|
+
//# sourceMappingURL=index.js.map
|