@zenstackhq/runtime 3.0.0-alpha.31 → 3.0.0-alpha.33
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-5Wcmlo5v.d.cts → contract-CusA0mQO.d.cts} +39 -39
- package/dist/{contract-5Wcmlo5v.d.ts → contract-CusA0mQO.d.ts} +39 -39
- package/dist/index.cjs +543 -433
- 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 +499 -389
- package/dist/index.js.map +1 -1
- package/dist/plugins/policy/index.cjs +109 -70
- 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 +109 -70
- package/dist/plugins/policy/index.js.map +1 -1
- package/dist/schema.cjs +4 -1
- package/dist/schema.cjs.map +1 -1
- package/dist/schema.d.cts +1 -0
- package/dist/schema.d.ts +1 -0
- package/dist/schema.js +4 -1
- package/dist/schema.js.map +1 -1
- package/package.json +8 -8
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as kysely from 'kysely';
|
|
2
|
-
import { R as RuntimePlugin, V as OnKyselyQueryArgs } from '../../contract-
|
|
2
|
+
import { R as RuntimePlugin, V as OnKyselyQueryArgs } from '../../contract-CusA0mQO.cjs';
|
|
3
3
|
import { SchemaDef } from '@zenstackhq/sdk/schema';
|
|
4
4
|
import 'decimal.js';
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as kysely from 'kysely';
|
|
2
|
-
import { R as RuntimePlugin, V as OnKyselyQueryArgs } from '../../contract-
|
|
2
|
+
import { R as RuntimePlugin, V as OnKyselyQueryArgs } from '../../contract-CusA0mQO.js';
|
|
3
3
|
import { SchemaDef } from '@zenstackhq/sdk/schema';
|
|
4
4
|
import 'decimal.js';
|
|
5
5
|
|
|
@@ -120,7 +120,10 @@ var ExpressionUtils = {
|
|
|
120
120
|
isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
|
|
121
121
|
isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
|
|
122
122
|
isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
|
|
123
|
-
isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
|
|
123
|
+
isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember"),
|
|
124
|
+
getLiteralValue: /* @__PURE__ */ __name((expr2) => {
|
|
125
|
+
return ExpressionUtils.isLiteral(expr2) ? expr2.value : void 0;
|
|
126
|
+
}, "getLiteralValue")
|
|
124
127
|
};
|
|
125
128
|
|
|
126
129
|
// src/client/errors.ts
|
|
@@ -911,6 +914,16 @@ var BaseCrudDialect = class {
|
|
|
911
914
|
}
|
|
912
915
|
return result;
|
|
913
916
|
}
|
|
917
|
+
buildModelSelect(eb, model, subQueryAlias, payload, selectAllFields) {
|
|
918
|
+
let subQuery = this.buildSelectModel(eb, model, subQueryAlias);
|
|
919
|
+
if (selectAllFields) {
|
|
920
|
+
subQuery = this.buildSelectAllFields(model, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
|
|
921
|
+
}
|
|
922
|
+
if (payload && typeof payload === "object") {
|
|
923
|
+
subQuery = this.buildFilterSortTake(model, payload, subQuery, subQueryAlias);
|
|
924
|
+
}
|
|
925
|
+
return subQuery;
|
|
926
|
+
}
|
|
914
927
|
buildSelectField(query, model, modelAlias, field) {
|
|
915
928
|
const fieldDef = requireField(this.schema, model, field);
|
|
916
929
|
if (fieldDef.computed) {
|
|
@@ -1008,6 +1021,18 @@ var BaseCrudDialect = class {
|
|
|
1008
1021
|
fieldRef(model, field, eb, modelAlias, inlineComputedField = true) {
|
|
1009
1022
|
return buildFieldRef(this.schema, model, field, this.options, eb, modelAlias, inlineComputedField);
|
|
1010
1023
|
}
|
|
1024
|
+
canJoinWithoutNestedSelect(modelDef, payload) {
|
|
1025
|
+
if (modelDef.computedFields) {
|
|
1026
|
+
return false;
|
|
1027
|
+
}
|
|
1028
|
+
if (modelDef.baseModel || modelDef.isDelegate) {
|
|
1029
|
+
return false;
|
|
1030
|
+
}
|
|
1031
|
+
if (typeof payload === "object" && (payload.orderBy || payload.skip !== void 0 || payload.take !== void 0 || payload.cursor || payload.distinct)) {
|
|
1032
|
+
return false;
|
|
1033
|
+
}
|
|
1034
|
+
return true;
|
|
1035
|
+
}
|
|
1011
1036
|
};
|
|
1012
1037
|
|
|
1013
1038
|
// src/client/crud/dialects/postgresql.ts
|
|
@@ -1033,52 +1058,58 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
1033
1058
|
}
|
|
1034
1059
|
}
|
|
1035
1060
|
buildRelationSelection(query, model, relationField, parentAlias, payload) {
|
|
1036
|
-
const
|
|
1037
|
-
|
|
1061
|
+
const relationResultName = `${parentAlias}$${relationField}`;
|
|
1062
|
+
const joinedQuery = this.buildRelationJSON(model, query, relationField, parentAlias, payload, relationResultName);
|
|
1063
|
+
return joinedQuery.select(`${relationResultName}.$data as ${relationField}`);
|
|
1038
1064
|
}
|
|
1039
|
-
buildRelationJSON(model, qb, relationField,
|
|
1065
|
+
buildRelationJSON(model, qb, relationField, parentAlias, payload, resultName) {
|
|
1040
1066
|
const relationFieldDef = requireField(this.schema, model, relationField);
|
|
1041
1067
|
const relationModel = relationFieldDef.type;
|
|
1042
1068
|
return qb.leftJoinLateral((eb) => {
|
|
1043
|
-
const
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
} else {
|
|
1060
|
-
const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, subQueryAlias);
|
|
1061
|
-
subQuery = subQuery.where((eb2) => this.and(eb2, ...joinPairs.map(([left, right]) => eb2(sql2.ref(left), "=", sql2.ref(right)))));
|
|
1062
|
-
}
|
|
1063
|
-
return subQuery.as(joinTableName);
|
|
1064
|
-
});
|
|
1065
|
-
result = this.buildRelationObjectSelect(relationModel, joinTableName, relationField, relationFieldDef, result, payload, parentName);
|
|
1066
|
-
result = this.buildRelationJoins(relationModel, relationField, result, payload, parentName);
|
|
1067
|
-
return result.as(joinTableName);
|
|
1069
|
+
const relationSelectName = `${resultName}$sub`;
|
|
1070
|
+
const relationModelDef = requireModel(this.schema, relationModel);
|
|
1071
|
+
let tbl;
|
|
1072
|
+
if (this.canJoinWithoutNestedSelect(relationModelDef, payload)) {
|
|
1073
|
+
tbl = this.buildModelSelect(eb, relationModel, relationSelectName, payload, false);
|
|
1074
|
+
tbl = this.buildRelationJoinFilter(tbl, model, relationField, relationModel, relationSelectName, parentAlias);
|
|
1075
|
+
} else {
|
|
1076
|
+
tbl = eb.selectFrom(() => {
|
|
1077
|
+
let subQuery = this.buildModelSelect(eb, relationModel, `${relationSelectName}$t`, payload, true);
|
|
1078
|
+
subQuery = this.buildRelationJoinFilter(subQuery, model, relationField, relationModel, `${relationSelectName}$t`, parentAlias);
|
|
1079
|
+
return subQuery.as(relationSelectName);
|
|
1080
|
+
});
|
|
1081
|
+
}
|
|
1082
|
+
tbl = this.buildRelationObjectSelect(relationModel, relationSelectName, relationFieldDef, tbl, payload, resultName);
|
|
1083
|
+
tbl = this.buildRelationJoins(tbl, relationModel, relationSelectName, payload, resultName);
|
|
1084
|
+
return tbl.as(resultName);
|
|
1068
1085
|
}, (join) => join.onTrue());
|
|
1069
1086
|
}
|
|
1070
|
-
|
|
1087
|
+
buildRelationJoinFilter(query, model, relationField, relationModel, relationModelAlias, parentAlias) {
|
|
1088
|
+
const m2m = getManyToManyRelation(this.schema, model, relationField);
|
|
1089
|
+
if (m2m) {
|
|
1090
|
+
const parentIds = getIdFields(this.schema, model);
|
|
1091
|
+
const relationIds = getIdFields(this.schema, relationModel);
|
|
1092
|
+
invariant2(parentIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1093
|
+
invariant2(relationIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1094
|
+
query = query.where((eb) => eb(eb.ref(`${relationModelAlias}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentAlias}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
|
|
1095
|
+
} else {
|
|
1096
|
+
const joinPairs = buildJoinPairs(this.schema, model, parentAlias, relationField, relationModelAlias);
|
|
1097
|
+
query = query.where((eb) => this.and(eb, ...joinPairs.map(([left, right]) => eb(sql2.ref(left), "=", sql2.ref(right)))));
|
|
1098
|
+
}
|
|
1099
|
+
return query;
|
|
1100
|
+
}
|
|
1101
|
+
buildRelationObjectSelect(relationModel, relationModelAlias, relationFieldDef, qb, payload, parentResultName) {
|
|
1071
1102
|
qb = qb.select((eb) => {
|
|
1072
|
-
const objArgs = this.buildRelationObjectArgs(relationModel, relationModelAlias,
|
|
1103
|
+
const objArgs = this.buildRelationObjectArgs(relationModel, relationModelAlias, eb, payload, parentResultName);
|
|
1073
1104
|
if (relationFieldDef.array) {
|
|
1074
|
-
return eb.fn.coalesce(sql2`jsonb_agg(jsonb_build_object(${sql2.join(objArgs)}))`, sql2`'[]'::jsonb`).as("$
|
|
1105
|
+
return eb.fn.coalesce(sql2`jsonb_agg(jsonb_build_object(${sql2.join(objArgs)}))`, sql2`'[]'::jsonb`).as("$data");
|
|
1075
1106
|
} else {
|
|
1076
|
-
return sql2`jsonb_build_object(${sql2.join(objArgs)})`.as("$
|
|
1107
|
+
return sql2`jsonb_build_object(${sql2.join(objArgs)})`.as("$data");
|
|
1077
1108
|
}
|
|
1078
1109
|
});
|
|
1079
1110
|
return qb;
|
|
1080
1111
|
}
|
|
1081
|
-
buildRelationObjectArgs(relationModel, relationModelAlias,
|
|
1112
|
+
buildRelationObjectArgs(relationModel, relationModelAlias, eb, payload, parentResultName) {
|
|
1082
1113
|
const relationModelDef = requireModel(this.schema, relationModel);
|
|
1083
1114
|
const objArgs = [];
|
|
1084
1115
|
const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
|
|
@@ -1096,14 +1127,14 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
1096
1127
|
} else if (payload.select) {
|
|
1097
1128
|
objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
|
|
1098
1129
|
if (field === "_count") {
|
|
1099
|
-
const subJson = this.buildCountJson(relationModel, eb,
|
|
1130
|
+
const subJson = this.buildCountJson(relationModel, eb, relationModelAlias, value);
|
|
1100
1131
|
return [
|
|
1101
1132
|
sql2.lit(field),
|
|
1102
1133
|
subJson
|
|
1103
1134
|
];
|
|
1104
1135
|
} else {
|
|
1105
1136
|
const fieldDef = requireField(this.schema, relationModel, field);
|
|
1106
|
-
const fieldValue = fieldDef.relation ? eb.ref(`${
|
|
1137
|
+
const fieldValue = fieldDef.relation ? eb.ref(`${parentResultName}$${field}.$data`) : this.fieldRef(relationModel, field, eb, relationModelAlias, false);
|
|
1107
1138
|
return [
|
|
1108
1139
|
sql2.lit(field),
|
|
1109
1140
|
fieldValue
|
|
@@ -1115,18 +1146,18 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
|
|
|
1115
1146
|
objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field]) => [
|
|
1116
1147
|
sql2.lit(field),
|
|
1117
1148
|
// reference the synthesized JSON field
|
|
1118
|
-
eb.ref(`${
|
|
1149
|
+
eb.ref(`${parentResultName}$${field}.$data`)
|
|
1119
1150
|
]).flatMap((v) => v));
|
|
1120
1151
|
}
|
|
1121
1152
|
return objArgs;
|
|
1122
1153
|
}
|
|
1123
|
-
buildRelationJoins(
|
|
1124
|
-
let result =
|
|
1154
|
+
buildRelationJoins(query, relationModel, relationModelAlias, payload, parentResultName) {
|
|
1155
|
+
let result = query;
|
|
1125
1156
|
if (typeof payload === "object") {
|
|
1126
1157
|
const selectInclude = payload.include ?? payload.select;
|
|
1127
1158
|
if (selectInclude && typeof selectInclude === "object") {
|
|
1128
1159
|
Object.entries(selectInclude).filter(([, value]) => value).filter(([field]) => isRelationField(this.schema, relationModel, field)).forEach(([field, value]) => {
|
|
1129
|
-
result = this.buildRelationJSON(relationModel, result, field, `${
|
|
1160
|
+
result = this.buildRelationJSON(relationModel, result, field, relationModelAlias, value, `${parentResultName}$${field}`);
|
|
1130
1161
|
});
|
|
1131
1162
|
}
|
|
1132
1163
|
}
|
|
@@ -1206,32 +1237,18 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
1206
1237
|
const relationModel = relationFieldDef.type;
|
|
1207
1238
|
const relationModelDef = requireModel(this.schema, relationModel);
|
|
1208
1239
|
const subQueryName = `${parentAlias}$${relationField}`;
|
|
1209
|
-
let tbl
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
invariant3(relationIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1222
|
-
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}`)));
|
|
1223
|
-
} else {
|
|
1224
|
-
const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
|
|
1225
|
-
keyPairs.forEach(({ fk, pk }) => {
|
|
1226
|
-
if (ownedByModel) {
|
|
1227
|
-
subQuery = subQuery.whereRef(`${subQueryAlias}.${pk}`, "=", `${parentAlias}.${fk}`);
|
|
1228
|
-
} else {
|
|
1229
|
-
subQuery = subQuery.whereRef(`${subQueryAlias}.${fk}`, "=", `${parentAlias}.${pk}`);
|
|
1230
|
-
}
|
|
1231
|
-
});
|
|
1232
|
-
}
|
|
1233
|
-
return subQuery.as(subQueryName);
|
|
1234
|
-
});
|
|
1240
|
+
let tbl;
|
|
1241
|
+
if (this.canJoinWithoutNestedSelect(relationModelDef, payload)) {
|
|
1242
|
+
tbl = this.buildModelSelect(eb, relationModel, subQueryName, payload, false);
|
|
1243
|
+
tbl = this.buildRelationJoinFilter(tbl, model, relationField, subQueryName, parentAlias);
|
|
1244
|
+
} else {
|
|
1245
|
+
tbl = eb.selectFrom(() => {
|
|
1246
|
+
const selectModelAlias = `${parentAlias}$${relationField}$sub`;
|
|
1247
|
+
let selectModelQuery = this.buildModelSelect(eb, relationModel, selectModelAlias, payload, true);
|
|
1248
|
+
selectModelQuery = this.buildRelationJoinFilter(selectModelQuery, model, relationField, selectModelAlias, parentAlias);
|
|
1249
|
+
return selectModelQuery.as(subQueryName);
|
|
1250
|
+
});
|
|
1251
|
+
}
|
|
1235
1252
|
tbl = tbl.select(() => {
|
|
1236
1253
|
const objArgs = [];
|
|
1237
1254
|
const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
|
|
@@ -1244,7 +1261,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
1244
1261
|
if (payload === true || !payload.select) {
|
|
1245
1262
|
objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
|
|
1246
1263
|
sql3.lit(field),
|
|
1247
|
-
this.fieldRef(relationModel, field, eb,
|
|
1264
|
+
this.fieldRef(relationModel, field, eb, subQueryName, false)
|
|
1248
1265
|
]).flatMap((v) => v));
|
|
1249
1266
|
} else if (payload.select) {
|
|
1250
1267
|
objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
|
|
@@ -1265,7 +1282,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
1265
1282
|
} else {
|
|
1266
1283
|
return [
|
|
1267
1284
|
sql3.lit(field),
|
|
1268
|
-
this.fieldRef(relationModel, field, eb,
|
|
1285
|
+
this.fieldRef(relationModel, field, eb, subQueryName, false)
|
|
1269
1286
|
];
|
|
1270
1287
|
}
|
|
1271
1288
|
}
|
|
@@ -1281,13 +1298,35 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
|
|
|
1281
1298
|
}).flatMap((v) => v));
|
|
1282
1299
|
}
|
|
1283
1300
|
if (relationFieldDef.array) {
|
|
1284
|
-
return eb.fn.coalesce(sql3`json_group_array(json_object(${sql3.join(objArgs)}))`, sql3`json_array()`).as("$
|
|
1301
|
+
return eb.fn.coalesce(sql3`json_group_array(json_object(${sql3.join(objArgs)}))`, sql3`json_array()`).as("$data");
|
|
1285
1302
|
} else {
|
|
1286
|
-
return sql3`json_object(${sql3.join(objArgs)})`.as("data");
|
|
1303
|
+
return sql3`json_object(${sql3.join(objArgs)})`.as("$data");
|
|
1287
1304
|
}
|
|
1288
1305
|
});
|
|
1289
1306
|
return tbl;
|
|
1290
1307
|
}
|
|
1308
|
+
buildRelationJoinFilter(selectModelQuery, model, relationField, relationModelAlias, parentAlias) {
|
|
1309
|
+
const fieldDef = requireField(this.schema, model, relationField);
|
|
1310
|
+
const relationModel = fieldDef.type;
|
|
1311
|
+
const m2m = getManyToManyRelation(this.schema, model, relationField);
|
|
1312
|
+
if (m2m) {
|
|
1313
|
+
const parentIds = getIdFields(this.schema, model);
|
|
1314
|
+
const relationIds = getIdFields(this.schema, relationModel);
|
|
1315
|
+
invariant3(parentIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1316
|
+
invariant3(relationIds.length === 1, "many-to-many relation must have exactly one id field");
|
|
1317
|
+
selectModelQuery = selectModelQuery.where((eb) => eb(eb.ref(`${relationModelAlias}.${relationIds[0]}`), "in", eb.selectFrom(m2m.joinTable).select(`${m2m.joinTable}.${m2m.otherFkName}`).whereRef(`${parentAlias}.${parentIds[0]}`, "=", `${m2m.joinTable}.${m2m.parentFkName}`)));
|
|
1318
|
+
} else {
|
|
1319
|
+
const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
|
|
1320
|
+
keyPairs.forEach(({ fk, pk }) => {
|
|
1321
|
+
if (ownedByModel) {
|
|
1322
|
+
selectModelQuery = selectModelQuery.whereRef(`${relationModelAlias}.${pk}`, "=", `${parentAlias}.${fk}`);
|
|
1323
|
+
} else {
|
|
1324
|
+
selectModelQuery = selectModelQuery.whereRef(`${relationModelAlias}.${fk}`, "=", `${parentAlias}.${pk}`);
|
|
1325
|
+
}
|
|
1326
|
+
});
|
|
1327
|
+
}
|
|
1328
|
+
return selectModelQuery;
|
|
1329
|
+
}
|
|
1291
1330
|
buildSkipTake(query, skip, take) {
|
|
1292
1331
|
if (take !== void 0) {
|
|
1293
1332
|
query = query.limit(take);
|