@zenstackhq/runtime 3.0.0-alpha.27 → 3.0.0-alpha.29
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-c8GpEAl3.d.cts → contract-B8DJmviN.d.cts} +4 -8
- package/dist/{contract-c8GpEAl3.d.ts → contract-B8DJmviN.d.ts} +4 -8
- package/dist/index.cjs +90 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +90 -66
- package/dist/index.js.map +1 -1
- package/dist/plugins/policy/index.cjs +75 -46
- package/dist/plugins/policy/index.cjs.map +1 -1
- package/dist/plugins/policy/index.d.cts +1 -1
- package/dist/plugins/policy/index.d.ts +1 -1
- package/dist/plugins/policy/index.js +75 -46
- package/dist/plugins/policy/index.js.map +1 -1
- package/package.json +8 -8
|
@@ -531,8 +531,8 @@ declare abstract class BaseCrudDialect<Schema extends SchemaDef> {
|
|
|
531
531
|
protected readonly options: ClientOptions<Schema>;
|
|
532
532
|
constructor(schema: Schema, options: ClientOptions<Schema>);
|
|
533
533
|
transformPrimitive(value: unknown, _type: BuiltinType, _forArrayField: boolean): unknown;
|
|
534
|
-
buildSelectModel(eb: ExpressionBuilder<any, any>, model: string): SelectQueryBuilder<any, any, {}>;
|
|
535
|
-
buildFilterSortTake(model: GetModels<Schema>, args: FindArgs<Schema, GetModels<Schema>, true>, query: SelectQueryBuilder<any, any, {}
|
|
534
|
+
buildSelectModel(eb: ExpressionBuilder<any, any>, model: string, modelAlias: string): SelectQueryBuilder<any, any, {}>;
|
|
535
|
+
buildFilterSortTake(model: GetModels<Schema>, args: FindArgs<Schema, GetModels<Schema>, true>, query: SelectQueryBuilder<any, any, {}>, modelAlias: string): SelectQueryBuilder<any, any, {}>;
|
|
536
536
|
buildFilter(eb: ExpressionBuilder<any, any>, model: string, modelAlias: string, where: boolean | object | undefined): Expression<SqlBool>;
|
|
537
537
|
private buildCursorFilter;
|
|
538
538
|
private isLogicalCombinator;
|
|
@@ -552,9 +552,9 @@ declare abstract class BaseCrudDialect<Schema extends SchemaDef> {
|
|
|
552
552
|
private buildBytesFilter;
|
|
553
553
|
private buildEnumFilter;
|
|
554
554
|
buildOrderBy(query: SelectQueryBuilder<any, any, any>, model: string, modelAlias: string, orderBy: OrArray<OrderBy<Schema, GetModels<Schema>, boolean, boolean>> | undefined, useDefaultIfEmpty: boolean, negated: boolean): SelectQueryBuilder<any, any, any>;
|
|
555
|
-
buildSelectAllFields(model: string, query: SelectQueryBuilder<any, any, any>, omit
|
|
555
|
+
buildSelectAllFields(model: string, query: SelectQueryBuilder<any, any, any>, omit: Record<string, boolean | undefined> | undefined, modelAlias: string): SelectQueryBuilder<any, any, any>;
|
|
556
556
|
buildSelectField(query: SelectQueryBuilder<any, any, any>, model: string, modelAlias: string, field: string): SelectQueryBuilder<any, any, any>;
|
|
557
|
-
buildDelegateJoin(thisModel: string,
|
|
557
|
+
buildDelegateJoin(thisModel: string, thisModelAlias: string, otherModelAlias: string, query: SelectQueryBuilder<any, any, any>): SelectQueryBuilder<any, any, any>;
|
|
558
558
|
buildCountJson(model: string, eb: ExpressionBuilder<any, any>, parentAlias: string, payload: any): ExpressionWrapper<any, any, unknown>;
|
|
559
559
|
private negateSort;
|
|
560
560
|
true(eb: ExpressionBuilder<any, any>): Expression<SqlBool>;
|
|
@@ -777,10 +777,6 @@ type ClientOptions<Schema extends SchemaDef> = {
|
|
|
777
777
|
* Logging configuration.
|
|
778
778
|
*/
|
|
779
779
|
log?: KyselyConfig['log'];
|
|
780
|
-
/**
|
|
781
|
-
* Debug mode.
|
|
782
|
-
*/
|
|
783
|
-
debug?: boolean;
|
|
784
780
|
} & (HasComputedFields<Schema> extends true ? {
|
|
785
781
|
/**
|
|
786
782
|
* Computed field definitions.
|
|
@@ -531,8 +531,8 @@ declare abstract class BaseCrudDialect<Schema extends SchemaDef> {
|
|
|
531
531
|
protected readonly options: ClientOptions<Schema>;
|
|
532
532
|
constructor(schema: Schema, options: ClientOptions<Schema>);
|
|
533
533
|
transformPrimitive(value: unknown, _type: BuiltinType, _forArrayField: boolean): unknown;
|
|
534
|
-
buildSelectModel(eb: ExpressionBuilder<any, any>, model: string): SelectQueryBuilder<any, any, {}>;
|
|
535
|
-
buildFilterSortTake(model: GetModels<Schema>, args: FindArgs<Schema, GetModels<Schema>, true>, query: SelectQueryBuilder<any, any, {}
|
|
534
|
+
buildSelectModel(eb: ExpressionBuilder<any, any>, model: string, modelAlias: string): SelectQueryBuilder<any, any, {}>;
|
|
535
|
+
buildFilterSortTake(model: GetModels<Schema>, args: FindArgs<Schema, GetModels<Schema>, true>, query: SelectQueryBuilder<any, any, {}>, modelAlias: string): SelectQueryBuilder<any, any, {}>;
|
|
536
536
|
buildFilter(eb: ExpressionBuilder<any, any>, model: string, modelAlias: string, where: boolean | object | undefined): Expression<SqlBool>;
|
|
537
537
|
private buildCursorFilter;
|
|
538
538
|
private isLogicalCombinator;
|
|
@@ -552,9 +552,9 @@ declare abstract class BaseCrudDialect<Schema extends SchemaDef> {
|
|
|
552
552
|
private buildBytesFilter;
|
|
553
553
|
private buildEnumFilter;
|
|
554
554
|
buildOrderBy(query: SelectQueryBuilder<any, any, any>, model: string, modelAlias: string, orderBy: OrArray<OrderBy<Schema, GetModels<Schema>, boolean, boolean>> | undefined, useDefaultIfEmpty: boolean, negated: boolean): SelectQueryBuilder<any, any, any>;
|
|
555
|
-
buildSelectAllFields(model: string, query: SelectQueryBuilder<any, any, any>, omit
|
|
555
|
+
buildSelectAllFields(model: string, query: SelectQueryBuilder<any, any, any>, omit: Record<string, boolean | undefined> | undefined, modelAlias: string): SelectQueryBuilder<any, any, any>;
|
|
556
556
|
buildSelectField(query: SelectQueryBuilder<any, any, any>, model: string, modelAlias: string, field: string): SelectQueryBuilder<any, any, any>;
|
|
557
|
-
buildDelegateJoin(thisModel: string,
|
|
557
|
+
buildDelegateJoin(thisModel: string, thisModelAlias: string, otherModelAlias: string, query: SelectQueryBuilder<any, any, any>): SelectQueryBuilder<any, any, any>;
|
|
558
558
|
buildCountJson(model: string, eb: ExpressionBuilder<any, any>, parentAlias: string, payload: any): ExpressionWrapper<any, any, unknown>;
|
|
559
559
|
private negateSort;
|
|
560
560
|
true(eb: ExpressionBuilder<any, any>): Expression<SqlBool>;
|
|
@@ -777,10 +777,6 @@ type ClientOptions<Schema extends SchemaDef> = {
|
|
|
777
777
|
* Logging configuration.
|
|
778
778
|
*/
|
|
779
779
|
log?: KyselyConfig['log'];
|
|
780
|
-
/**
|
|
781
|
-
* Debug mode.
|
|
782
|
-
*/
|
|
783
|
-
debug?: boolean;
|
|
784
780
|
} & (HasComputedFields<Schema> extends true ? {
|
|
785
781
|
/**
|
|
786
782
|
* Computed field definitions.
|
package/dist/index.cjs
CHANGED
|
@@ -321,7 +321,9 @@ function buildFieldRef(schema, model, field, options, eb, modelAlias, inlineComp
|
|
|
321
321
|
if (!computer) {
|
|
322
322
|
throw new QueryError(`Computed field "${field}" implementation not provided for model "${model}"`);
|
|
323
323
|
}
|
|
324
|
-
return computer(eb
|
|
324
|
+
return computer(eb, {
|
|
325
|
+
currentModel: modelAlias
|
|
326
|
+
});
|
|
325
327
|
}
|
|
326
328
|
}
|
|
327
329
|
__name(buildFieldRef, "buildFieldRef");
|
|
@@ -372,11 +374,33 @@ function getManyToManyRelation(schema, model, field) {
|
|
|
372
374
|
model,
|
|
373
375
|
fieldDef.type
|
|
374
376
|
].sort();
|
|
377
|
+
let orderedFK;
|
|
378
|
+
if (model !== fieldDef.type) {
|
|
379
|
+
orderedFK = sortedModelNames[0] === model ? [
|
|
380
|
+
"A",
|
|
381
|
+
"B"
|
|
382
|
+
] : [
|
|
383
|
+
"B",
|
|
384
|
+
"A"
|
|
385
|
+
];
|
|
386
|
+
} else {
|
|
387
|
+
const sortedFieldNames = [
|
|
388
|
+
field,
|
|
389
|
+
oppositeFieldDef.name
|
|
390
|
+
].sort();
|
|
391
|
+
orderedFK = sortedFieldNames[0] === field ? [
|
|
392
|
+
"A",
|
|
393
|
+
"B"
|
|
394
|
+
] : [
|
|
395
|
+
"B",
|
|
396
|
+
"A"
|
|
397
|
+
];
|
|
398
|
+
}
|
|
375
399
|
return {
|
|
376
|
-
parentFkName:
|
|
400
|
+
parentFkName: orderedFK[0],
|
|
377
401
|
otherModel: fieldDef.type,
|
|
378
402
|
otherField: fieldDef.relation.opposite,
|
|
379
|
-
otherFkName:
|
|
403
|
+
otherFkName: orderedFK[1],
|
|
380
404
|
joinTable: fieldDef.relation.name ? `_${fieldDef.relation.name}` : `_${sortedModelNames[0]}To${sortedModelNames[1]}`
|
|
381
405
|
};
|
|
382
406
|
} else {
|
|
@@ -455,7 +479,6 @@ var import_cuid2 = require("@paralleldrive/cuid2");
|
|
|
455
479
|
var import_common_helpers8 = require("@zenstackhq/common-helpers");
|
|
456
480
|
var import_kysely8 = require("kysely");
|
|
457
481
|
var import_nanoid = require("nanoid");
|
|
458
|
-
var import_node_util = require("util");
|
|
459
482
|
var import_ts_pattern9 = require("ts-pattern");
|
|
460
483
|
var import_ulid = require("ulid");
|
|
461
484
|
var uuid = __toESM(require("uuid"), 1);
|
|
@@ -540,20 +563,20 @@ var BaseCrudDialect = class {
|
|
|
540
563
|
return value;
|
|
541
564
|
}
|
|
542
565
|
// #region common query builders
|
|
543
|
-
buildSelectModel(eb, model) {
|
|
566
|
+
buildSelectModel(eb, model, modelAlias) {
|
|
544
567
|
const modelDef = requireModel(this.schema, model);
|
|
545
|
-
let result = eb.selectFrom(model);
|
|
568
|
+
let result = eb.selectFrom(model === modelAlias ? model : `${model} as ${modelAlias}`);
|
|
546
569
|
let joinBase = modelDef.baseModel;
|
|
547
570
|
while (joinBase) {
|
|
548
|
-
result = this.buildDelegateJoin(model, joinBase, result);
|
|
571
|
+
result = this.buildDelegateJoin(model, modelAlias, joinBase, result);
|
|
549
572
|
joinBase = requireModel(this.schema, joinBase).baseModel;
|
|
550
573
|
}
|
|
551
574
|
return result;
|
|
552
575
|
}
|
|
553
|
-
buildFilterSortTake(model, args, query) {
|
|
576
|
+
buildFilterSortTake(model, args, query, modelAlias) {
|
|
554
577
|
let result = query;
|
|
555
578
|
if (args.where) {
|
|
556
|
-
result = result.where((eb) => this.buildFilter(eb, model,
|
|
579
|
+
result = result.where((eb) => this.buildFilter(eb, model, modelAlias, args?.where));
|
|
557
580
|
}
|
|
558
581
|
let negateOrderBy = false;
|
|
559
582
|
const skip = args.skip;
|
|
@@ -563,17 +586,17 @@ var BaseCrudDialect = class {
|
|
|
563
586
|
take = -take;
|
|
564
587
|
}
|
|
565
588
|
result = this.buildSkipTake(result, skip, take);
|
|
566
|
-
result = this.buildOrderBy(result, model,
|
|
589
|
+
result = this.buildOrderBy(result, model, modelAlias, args.orderBy, skip !== void 0 || take !== void 0, negateOrderBy);
|
|
567
590
|
if ("distinct" in args && args.distinct) {
|
|
568
591
|
const distinct = ensureArray(args.distinct);
|
|
569
592
|
if (this.supportsDistinctOn) {
|
|
570
|
-
result = result.distinctOn(distinct.map((f) => import_kysely.sql.ref(`${
|
|
593
|
+
result = result.distinctOn(distinct.map((f) => import_kysely.sql.ref(`${modelAlias}.${f}`)));
|
|
571
594
|
} else {
|
|
572
595
|
throw new QueryError(`"distinct" is not supported by "${this.schema.provider.type}" provider`);
|
|
573
596
|
}
|
|
574
597
|
}
|
|
575
598
|
if (args.cursor) {
|
|
576
|
-
result = this.buildCursorFilter(model, result, args.cursor, args.orderBy, negateOrderBy);
|
|
599
|
+
result = this.buildCursorFilter(model, result, args.cursor, args.orderBy, negateOrderBy, modelAlias);
|
|
577
600
|
}
|
|
578
601
|
return result;
|
|
579
602
|
}
|
|
@@ -614,11 +637,12 @@ var BaseCrudDialect = class {
|
|
|
614
637
|
}
|
|
615
638
|
return result;
|
|
616
639
|
}
|
|
617
|
-
buildCursorFilter(model, query, cursor, orderBy, negateOrderBy) {
|
|
640
|
+
buildCursorFilter(model, query, cursor, orderBy, negateOrderBy, modelAlias) {
|
|
618
641
|
const _orderBy = orderBy ?? makeDefaultOrderBy(this.schema, model);
|
|
619
642
|
const orderByItems = ensureArray(_orderBy).flatMap((obj) => Object.entries(obj));
|
|
620
643
|
const eb = (0, import_kysely.expressionBuilder)();
|
|
621
|
-
const
|
|
644
|
+
const subQueryAlias = `${model}$cursor$sub`;
|
|
645
|
+
const cursorFilter = this.buildFilter(eb, model, subQueryAlias, cursor);
|
|
622
646
|
let result = query;
|
|
623
647
|
const filters = [];
|
|
624
648
|
for (let i = orderByItems.length - 1; i >= 0; i--) {
|
|
@@ -627,7 +651,7 @@ var BaseCrudDialect = class {
|
|
|
627
651
|
const [field, order] = orderByItems[j];
|
|
628
652
|
const _order = negateOrderBy ? order === "asc" ? "desc" : "asc" : order;
|
|
629
653
|
const op = j === i ? _order === "asc" ? ">=" : "<=" : "=";
|
|
630
|
-
andFilters.push(eb(eb.ref(`${
|
|
654
|
+
andFilters.push(eb(eb.ref(`${modelAlias}.${field}`), op, this.buildSelectModel(eb, model, subQueryAlias).select(`${subQueryAlias}.${field}`).where(cursorFilter)));
|
|
631
655
|
}
|
|
632
656
|
filters.push(eb.and(andFilters));
|
|
633
657
|
}
|
|
@@ -696,25 +720,26 @@ var BaseCrudDialect = class {
|
|
|
696
720
|
}
|
|
697
721
|
return this.and(eb, ...conditions);
|
|
698
722
|
}
|
|
699
|
-
buildToManyRelationFilter(eb, model,
|
|
723
|
+
buildToManyRelationFilter(eb, model, modelAlias, field, fieldDef, payload) {
|
|
700
724
|
if (payload === null) {
|
|
701
|
-
return eb(import_kysely.sql.ref(`${
|
|
725
|
+
return eb(import_kysely.sql.ref(`${modelAlias}.${field}`), "is", null);
|
|
702
726
|
}
|
|
703
727
|
const relationModel = fieldDef.type;
|
|
728
|
+
const relationFilterSelectAlias = `${modelAlias}$${field}$filter`;
|
|
704
729
|
const buildPkFkWhereRefs = /* @__PURE__ */ __name((eb2) => {
|
|
705
730
|
const m2m = getManyToManyRelation(this.schema, model, field);
|
|
706
731
|
if (m2m) {
|
|
707
732
|
const modelIdField = getIdFields(this.schema, model)[0];
|
|
708
733
|
const relationIdField = getIdFields(this.schema, relationModel)[0];
|
|
709
|
-
return eb2(import_kysely.sql.ref(`${
|
|
734
|
+
return eb2(import_kysely.sql.ref(`${relationFilterSelectAlias}.${relationIdField}`), "in", eb2.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(import_kysely.sql.ref(`${m2m.joinTable}.${m2m.parentFkName}`), "=", import_kysely.sql.ref(`${modelAlias}.${modelIdField}`)));
|
|
710
735
|
} else {
|
|
711
736
|
const relationKeyPairs = getRelationForeignKeyFieldPairs(this.schema, model, field);
|
|
712
737
|
let result2 = this.true(eb2);
|
|
713
738
|
for (const { fk, pk } of relationKeyPairs.keyPairs) {
|
|
714
739
|
if (relationKeyPairs.ownedByModel) {
|
|
715
|
-
result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${
|
|
740
|
+
result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${modelAlias}.${fk}`), "=", import_kysely.sql.ref(`${relationFilterSelectAlias}.${pk}`)));
|
|
716
741
|
} else {
|
|
717
|
-
result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${
|
|
742
|
+
result2 = this.and(eb2, result2, eb2(import_kysely.sql.ref(`${modelAlias}.${pk}`), "=", import_kysely.sql.ref(`${relationFilterSelectAlias}.${fk}`)));
|
|
718
743
|
}
|
|
719
744
|
}
|
|
720
745
|
return result2;
|
|
@@ -727,15 +752,15 @@ var BaseCrudDialect = class {
|
|
|
727
752
|
}
|
|
728
753
|
switch (key) {
|
|
729
754
|
case "some": {
|
|
730
|
-
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,
|
|
755
|
+
result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel, relationFilterSelectAlias).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationFilterSelectAlias, subPayload)), ">", 0));
|
|
731
756
|
break;
|
|
732
757
|
}
|
|
733
758
|
case "every": {
|
|
734
|
-
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,
|
|
759
|
+
result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel, relationFilterSelectAlias).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => eb1.not(this.buildFilter(eb1, relationModel, relationFilterSelectAlias, subPayload))), "=", 0));
|
|
735
760
|
break;
|
|
736
761
|
}
|
|
737
762
|
case "none": {
|
|
738
|
-
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,
|
|
763
|
+
result = this.and(eb, result, eb(this.buildSelectModel(eb, relationModel, relationFilterSelectAlias).select((eb1) => eb1.fn.count(eb1.lit(1)).as("$count")).where(buildPkFkWhereRefs(eb)).where((eb1) => this.buildFilter(eb1, relationModel, relationFilterSelectAlias, subPayload)), "=", 0));
|
|
739
764
|
break;
|
|
740
765
|
}
|
|
741
766
|
}
|
|
@@ -978,8 +1003,9 @@ var BaseCrudDialect = class {
|
|
|
978
1003
|
(0, import_common_helpers.invariant)(value._count === "asc" || value._count === "desc", 'invalid orderBy value for field "_count"');
|
|
979
1004
|
const sort = this.negateSort(value._count, negated);
|
|
980
1005
|
result = result.orderBy((eb) => {
|
|
981
|
-
|
|
982
|
-
|
|
1006
|
+
const subQueryAlias = `${modelAlias}$orderBy$${field}$count`;
|
|
1007
|
+
let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
|
|
1008
|
+
const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, subQueryAlias);
|
|
983
1009
|
subQuery = subQuery.where(() => this.and(eb, ...joinPairs.map(([left, right]) => eb(import_kysely.sql.ref(left), "=", import_kysely.sql.ref(right)))));
|
|
984
1010
|
subQuery = subQuery.select(() => eb.fn.count(eb.lit(1)).as("_count"));
|
|
985
1011
|
return subQuery;
|
|
@@ -997,7 +1023,7 @@ var BaseCrudDialect = class {
|
|
|
997
1023
|
});
|
|
998
1024
|
return result;
|
|
999
1025
|
}
|
|
1000
|
-
buildSelectAllFields(model, query, omit) {
|
|
1026
|
+
buildSelectAllFields(model, query, omit, modelAlias) {
|
|
1001
1027
|
const modelDef = requireModel(this.schema, model);
|
|
1002
1028
|
let result = query;
|
|
1003
1029
|
for (const field of Object.keys(modelDef.fields)) {
|
|
@@ -1007,11 +1033,11 @@ var BaseCrudDialect = class {
|
|
|
1007
1033
|
if (omit?.[field] === true) {
|
|
1008
1034
|
continue;
|
|
1009
1035
|
}
|
|
1010
|
-
result = this.buildSelectField(result, model,
|
|
1036
|
+
result = this.buildSelectField(result, model, modelAlias, field);
|
|
1011
1037
|
}
|
|
1012
1038
|
const descendants = getDelegateDescendantModels(this.schema, model);
|
|
1013
1039
|
for (const subModel of descendants) {
|
|
1014
|
-
result = this.buildDelegateJoin(model, subModel.name, result);
|
|
1040
|
+
result = this.buildDelegateJoin(model, modelAlias, subModel.name, result);
|
|
1015
1041
|
result = result.select((eb) => {
|
|
1016
1042
|
const jsonObject = {};
|
|
1017
1043
|
for (const field of Object.keys(subModel.fields)) {
|
|
@@ -1035,11 +1061,11 @@ var BaseCrudDialect = class {
|
|
|
1035
1061
|
return this.buildSelectField(query, fieldDef.originModel, fieldDef.originModel, field);
|
|
1036
1062
|
}
|
|
1037
1063
|
}
|
|
1038
|
-
buildDelegateJoin(thisModel,
|
|
1064
|
+
buildDelegateJoin(thisModel, thisModelAlias, otherModelAlias, query) {
|
|
1039
1065
|
const idFields = getIdFields(this.schema, thisModel);
|
|
1040
|
-
query = query.leftJoin(
|
|
1066
|
+
query = query.leftJoin(otherModelAlias, (qb) => {
|
|
1041
1067
|
for (const idField of idFields) {
|
|
1042
|
-
qb = qb.onRef(`${
|
|
1068
|
+
qb = qb.onRef(`${thisModelAlias}.${idField}`, "=", `${otherModelAlias}.${idField}`);
|
|
1043
1069
|
}
|
|
1044
1070
|
return qb;
|
|
1045
1071
|
});
|
|
@@ -1156,11 +1182,12 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
1156
1182
|
return qb.leftJoinLateral((eb) => {
|
|
1157
1183
|
const joinTableName = `${parentName}$${relationField}`;
|
|
1158
1184
|
let result = eb.selectFrom(`${relationModel} as ${joinTableName}`);
|
|
1185
|
+
const subQueryAlias = `${relationModel}$${relationField}$sub`;
|
|
1159
1186
|
result = eb.selectFrom(() => {
|
|
1160
|
-
let subQuery = this.buildSelectModel(eb, relationModel);
|
|
1161
|
-
subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0);
|
|
1187
|
+
let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
|
|
1188
|
+
subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
|
|
1162
1189
|
if (payload && typeof payload === "object") {
|
|
1163
|
-
subQuery = this.buildFilterSortTake(relationModel, payload, subQuery);
|
|
1190
|
+
subQuery = this.buildFilterSortTake(relationModel, payload, subQuery, subQueryAlias);
|
|
1164
1191
|
}
|
|
1165
1192
|
const m2m = getManyToManyRelation(this.schema, model, relationField);
|
|
1166
1193
|
if (m2m) {
|
|
@@ -1168,21 +1195,21 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
1168
1195
|
const relationIds = getIdFields(this.schema, relationModel);
|
|
1169
1196
|
(0, import_common_helpers2.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1170
1197
|
(0, import_common_helpers2.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1171
|
-
subQuery = subQuery.where(eb(eb.ref(`${
|
|
1198
|
+
subQuery = subQuery.where(eb(eb.ref(`${subQueryAlias}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentName}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
|
|
1172
1199
|
} else {
|
|
1173
|
-
const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField,
|
|
1200
|
+
const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, subQueryAlias);
|
|
1174
1201
|
subQuery = subQuery.where((eb2) => this.and(eb2, ...joinPairs.map(([left, right]) => eb2(import_kysely2.sql.ref(left), "=", import_kysely2.sql.ref(right)))));
|
|
1175
1202
|
}
|
|
1176
1203
|
return subQuery.as(joinTableName);
|
|
1177
1204
|
});
|
|
1178
|
-
result = this.buildRelationObjectSelect(relationModel, relationField, relationFieldDef, result, payload, parentName);
|
|
1205
|
+
result = this.buildRelationObjectSelect(relationModel, joinTableName, relationField, relationFieldDef, result, payload, parentName);
|
|
1179
1206
|
result = this.buildRelationJoins(relationModel, relationField, result, payload, parentName);
|
|
1180
1207
|
return result.as(joinTableName);
|
|
1181
1208
|
}, (join) => join.onTrue());
|
|
1182
1209
|
}
|
|
1183
|
-
buildRelationObjectSelect(relationModel, relationField, relationFieldDef, qb, payload, parentName) {
|
|
1210
|
+
buildRelationObjectSelect(relationModel, relationModelAlias, relationField, relationFieldDef, qb, payload, parentName) {
|
|
1184
1211
|
qb = qb.select((eb) => {
|
|
1185
|
-
const objArgs = this.buildRelationObjectArgs(relationModel, relationField, eb, payload, parentName);
|
|
1212
|
+
const objArgs = this.buildRelationObjectArgs(relationModel, relationModelAlias, relationField, eb, payload, parentName);
|
|
1186
1213
|
if (relationFieldDef.array) {
|
|
1187
1214
|
return eb.fn.coalesce(import_kysely2.sql`jsonb_agg(jsonb_build_object(${import_kysely2.sql.join(objArgs)}))`, import_kysely2.sql`'[]'::jsonb`).as("$j");
|
|
1188
1215
|
} else {
|
|
@@ -1191,7 +1218,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
1191
1218
|
});
|
|
1192
1219
|
return qb;
|
|
1193
1220
|
}
|
|
1194
|
-
buildRelationObjectArgs(relationModel, relationField, eb, payload, parentAlias) {
|
|
1221
|
+
buildRelationObjectArgs(relationModel, relationModelAlias, relationField, eb, payload, parentAlias) {
|
|
1195
1222
|
const relationModelDef = requireModel(this.schema, relationModel);
|
|
1196
1223
|
const objArgs = [];
|
|
1197
1224
|
const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
|
|
@@ -1204,7 +1231,7 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
1204
1231
|
if (payload === true || !payload.select) {
|
|
1205
1232
|
objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
|
|
1206
1233
|
import_kysely2.sql.lit(field),
|
|
1207
|
-
this.fieldRef(relationModel, field, eb,
|
|
1234
|
+
this.fieldRef(relationModel, field, eb, relationModelAlias, false)
|
|
1208
1235
|
]).flatMap((v) => v));
|
|
1209
1236
|
} else if (payload.select) {
|
|
1210
1237
|
objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
|
|
@@ -1320,10 +1347,11 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
1320
1347
|
const relationModelDef = requireModel(this.schema, relationModel);
|
|
1321
1348
|
const subQueryName = `${parentAlias}$${relationField}`;
|
|
1322
1349
|
let tbl = eb.selectFrom(() => {
|
|
1323
|
-
|
|
1324
|
-
subQuery = this.
|
|
1350
|
+
const subQueryAlias = `${parentAlias}$${relationField}$sub`;
|
|
1351
|
+
let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
|
|
1352
|
+
subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
|
|
1325
1353
|
if (payload && typeof payload === "object") {
|
|
1326
|
-
subQuery = this.buildFilterSortTake(relationModel, payload, subQuery);
|
|
1354
|
+
subQuery = this.buildFilterSortTake(relationModel, payload, subQuery, subQueryAlias);
|
|
1327
1355
|
}
|
|
1328
1356
|
const m2m = getManyToManyRelation(this.schema, model, relationField);
|
|
1329
1357
|
if (m2m) {
|
|
@@ -1331,14 +1359,14 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
1331
1359
|
const relationIds = getIdFields(this.schema, relationModel);
|
|
1332
1360
|
(0, import_common_helpers3.invariant)(parentIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1333
1361
|
(0, import_common_helpers3.invariant)(relationIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1334
|
-
subQuery = subQuery.where(eb(eb.ref(`${
|
|
1362
|
+
subQuery = subQuery.where(eb(eb.ref(`${subQueryAlias}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentAlias}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
|
|
1335
1363
|
} else {
|
|
1336
1364
|
const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
|
|
1337
1365
|
keyPairs.forEach(({ fk, pk }) => {
|
|
1338
1366
|
if (ownedByModel) {
|
|
1339
|
-
subQuery = subQuery.whereRef(`${
|
|
1367
|
+
subQuery = subQuery.whereRef(`${subQueryAlias}.${pk}`, "=", `${parentAlias}.${fk}`);
|
|
1340
1368
|
} else {
|
|
1341
|
-
subQuery = subQuery.whereRef(`${
|
|
1369
|
+
subQuery = subQuery.whereRef(`${subQueryAlias}.${fk}`, "=", `${parentAlias}.${pk}`);
|
|
1342
1370
|
}
|
|
1343
1371
|
});
|
|
1344
1372
|
}
|
|
@@ -2764,14 +2792,14 @@ var BaseOperationHandler = class {
|
|
|
2764
2792
|
return this.executeQueryTakeFirst(kysely, query, "exists");
|
|
2765
2793
|
}
|
|
2766
2794
|
async read(kysely, model, args) {
|
|
2767
|
-
let query = this.dialect.buildSelectModel((0, import_kysely8.expressionBuilder)(), model);
|
|
2795
|
+
let query = this.dialect.buildSelectModel((0, import_kysely8.expressionBuilder)(), model, model);
|
|
2768
2796
|
if (args) {
|
|
2769
|
-
query = this.dialect.buildFilterSortTake(model, args, query);
|
|
2797
|
+
query = this.dialect.buildFilterSortTake(model, args, query, model);
|
|
2770
2798
|
}
|
|
2771
2799
|
if (args && "select" in args && args.select) {
|
|
2772
2800
|
query = this.buildFieldSelection(model, query, args.select, model);
|
|
2773
2801
|
} else {
|
|
2774
|
-
query = this.dialect.buildSelectAllFields(model, query, args?.omit);
|
|
2802
|
+
query = this.dialect.buildSelectAllFields(model, query, args?.omit, model);
|
|
2775
2803
|
}
|
|
2776
2804
|
if (args && "include" in args && args.include) {
|
|
2777
2805
|
query = this.buildFieldSelection(model, query, args.include, model);
|
|
@@ -2789,11 +2817,7 @@ var BaseOperationHandler = class {
|
|
|
2789
2817
|
const r = await kysely.getExecutor().executeQuery(compiled, queryId);
|
|
2790
2818
|
result = r.rows;
|
|
2791
2819
|
} catch (err) {
|
|
2792
|
-
|
|
2793
|
-
if (this.options.debug) {
|
|
2794
|
-
message += `, parameters:
|
|
2795
|
-
${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
|
|
2796
|
-
}
|
|
2820
|
+
const message = `Failed to execute query: ${err}, sql: ${compiled.sql}`;
|
|
2797
2821
|
throw new QueryError(message, err);
|
|
2798
2822
|
}
|
|
2799
2823
|
return result;
|
|
@@ -2961,7 +2985,12 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
|
|
|
2961
2985
|
field: rightField,
|
|
2962
2986
|
entity: rightEntity
|
|
2963
2987
|
}
|
|
2964
|
-
].sort((a, b) =>
|
|
2988
|
+
].sort((a, b) => (
|
|
2989
|
+
// the implement m2m join table's "A", "B" fk fields' order is determined
|
|
2990
|
+
// by model name's sort order, and when identical (for self-relations),
|
|
2991
|
+
// field name's sort order
|
|
2992
|
+
a.model !== b.model ? a.model.localeCompare(b.model) : a.field.localeCompare(b.field)
|
|
2993
|
+
));
|
|
2965
2994
|
const firstIds = getIdFields(this.schema, sortedRecords[0].model);
|
|
2966
2995
|
const secondIds = getIdFields(this.schema, sortedRecords[1].model);
|
|
2967
2996
|
(0, import_common_helpers8.invariant)(firstIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
@@ -3466,7 +3495,7 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
|
|
|
3466
3495
|
} else {
|
|
3467
3496
|
query = query.where((eb) => eb(eb.refTuple(
|
|
3468
3497
|
...this.buildIdFieldRefs(kysely, model)
|
|
3469
|
-
), "in", this.dialect.buildSelectModel(eb, filterModel).where(this.dialect.buildFilter(eb, filterModel, filterModel, where)).select(this.buildIdFieldRefs(kysely, filterModel)).$if(limit !== void 0, (qb) => qb.limit(limit))));
|
|
3498
|
+
), "in", this.dialect.buildSelectModel(eb, filterModel, filterModel).where(this.dialect.buildFilter(eb, filterModel, filterModel, where)).select(this.buildIdFieldRefs(kysely, filterModel)).$if(limit !== void 0, (qb) => qb.limit(limit))));
|
|
3470
3499
|
}
|
|
3471
3500
|
query = query.modifyEnd(this.makeContextComment({
|
|
3472
3501
|
model,
|
|
@@ -3884,7 +3913,7 @@ ${compiled.parameters.map((p) => (0, import_node_util.inspect)(p)).join("\n")}`;
|
|
|
3884
3913
|
} else {
|
|
3885
3914
|
query = query.where((eb) => eb(eb.refTuple(
|
|
3886
3915
|
...this.buildIdFieldRefs(kysely, model)
|
|
3887
|
-
), "in", this.dialect.buildSelectModel(eb, filterModel).where((eb2) => this.dialect.buildFilter(eb2, filterModel, filterModel, where)).select(this.buildIdFieldRefs(kysely, filterModel)).$if(limit !== void 0, (qb) => qb.limit(limit))));
|
|
3916
|
+
), "in", this.dialect.buildSelectModel(eb, filterModel, filterModel).where((eb2) => this.dialect.buildFilter(eb2, filterModel, filterModel, where)).select(this.buildIdFieldRefs(kysely, filterModel)).$if(limit !== void 0, (qb) => qb.limit(limit))));
|
|
3888
3917
|
}
|
|
3889
3918
|
await this.processDelegateRelationDelete(kysely, modelDef, where, limit);
|
|
3890
3919
|
query = query.modifyEnd(this.makeContextComment({
|
|
@@ -4020,7 +4049,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
|
|
|
4020
4049
|
const normalizedArgs = this.normalizeArgs(args);
|
|
4021
4050
|
const parsedArgs = this.inputValidator.validateAggregateArgs(this.model, normalizedArgs);
|
|
4022
4051
|
let query = this.kysely.selectFrom((eb) => {
|
|
4023
|
-
let subQuery = this.dialect.buildSelectModel(eb, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
|
|
4052
|
+
let subQuery = this.dialect.buildSelectModel(eb, this.model, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
|
|
4024
4053
|
const selectedFields = [];
|
|
4025
4054
|
for (const [key, value] of Object.entries(parsedArgs)) {
|
|
4026
4055
|
if (key.startsWith("_") && value && typeof value === "object") {
|
|
@@ -4130,7 +4159,7 @@ var CountOperationHandler = class extends BaseOperationHandler {
|
|
|
4130
4159
|
const parsedArgs = this.inputValidator.validateCountArgs(this.model, normalizedArgs);
|
|
4131
4160
|
const subQueryName = "$sub";
|
|
4132
4161
|
let query = this.kysely.selectFrom((eb) => {
|
|
4133
|
-
let subQuery = this.dialect.buildSelectModel(eb, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
|
|
4162
|
+
let subQuery = this.dialect.buildSelectModel(eb, this.model, this.model).where((eb1) => this.dialect.buildFilter(eb1, this.model, this.model, parsedArgs?.where));
|
|
4134
4163
|
if (parsedArgs?.select && typeof parsedArgs.select === "object") {
|
|
4135
4164
|
for (const [key, value] of Object.entries(parsedArgs.select)) {
|
|
4136
4165
|
if (key !== "_all" && value === true) {
|
|
@@ -5633,7 +5662,6 @@ __name(performanceNow, "performanceNow");
|
|
|
5633
5662
|
// src/client/executor/zenstack-query-executor.ts
|
|
5634
5663
|
var import_kysely13 = require("kysely");
|
|
5635
5664
|
var import_nanoid2 = require("nanoid");
|
|
5636
|
-
var import_node_util2 = require("util");
|
|
5637
5665
|
var import_ts_pattern16 = require("ts-pattern");
|
|
5638
5666
|
|
|
5639
5667
|
// src/client/executor/name-mapper.ts
|
|
@@ -5941,11 +5969,7 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends import_kysely13
|
|
|
5941
5969
|
};
|
|
5942
5970
|
});
|
|
5943
5971
|
} catch (err) {
|
|
5944
|
-
|
|
5945
|
-
if (this.options.debug) {
|
|
5946
|
-
message += `, parameters:
|
|
5947
|
-
${compiled.parameters.map((p) => (0, import_node_util2.inspect)(p)).join("\n")}`;
|
|
5948
|
-
}
|
|
5972
|
+
const message = `Failed to execute query: ${err}, sql: ${compiled.sql}`;
|
|
5949
5973
|
throw new QueryError(message, err);
|
|
5950
5974
|
}
|
|
5951
5975
|
}
|