@zenstackhq/runtime 3.0.0-beta.10 → 3.0.0-beta.12
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/index.cjs +264 -149
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -7
- package/dist/index.d.ts +9 -7
- package/dist/index.js +264 -149
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -16,7 +16,6 @@ import { match as match7 } from "ts-pattern";
|
|
|
16
16
|
var query_utils_exports = {};
|
|
17
17
|
__export(query_utils_exports, {
|
|
18
18
|
aggregate: () => aggregate,
|
|
19
|
-
buildFieldRef: () => buildFieldRef,
|
|
20
19
|
buildJoinPairs: () => buildJoinPairs,
|
|
21
20
|
ensureArray: () => ensureArray,
|
|
22
21
|
extractFieldName: () => extractFieldName,
|
|
@@ -362,28 +361,6 @@ function getIdValues(schema, model, data) {
|
|
|
362
361
|
}), {});
|
|
363
362
|
}
|
|
364
363
|
__name(getIdValues, "getIdValues");
|
|
365
|
-
function buildFieldRef(schema, model, field, options, eb, modelAlias, inlineComputedField = true) {
|
|
366
|
-
const fieldDef = requireField(schema, model, field);
|
|
367
|
-
if (!fieldDef.computed) {
|
|
368
|
-
return eb.ref(modelAlias ? `${modelAlias}.${field}` : field);
|
|
369
|
-
} else {
|
|
370
|
-
if (!inlineComputedField) {
|
|
371
|
-
return eb.ref(modelAlias ? `${modelAlias}.${field}` : field);
|
|
372
|
-
}
|
|
373
|
-
let computer;
|
|
374
|
-
if ("computedFields" in options) {
|
|
375
|
-
const computedFields = options.computedFields;
|
|
376
|
-
computer = computedFields?.[model]?.[field];
|
|
377
|
-
}
|
|
378
|
-
if (!computer) {
|
|
379
|
-
throw new QueryError(`Computed field "${field}" implementation not provided for model "${model}"`);
|
|
380
|
-
}
|
|
381
|
-
return computer(eb, {
|
|
382
|
-
modelAlias
|
|
383
|
-
});
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
__name(buildFieldRef, "buildFieldRef");
|
|
387
364
|
function fieldHasDefaultValue(fieldDef) {
|
|
388
365
|
return fieldDef.default !== void 0 || fieldDef.updatedAt;
|
|
389
366
|
}
|
|
@@ -735,7 +712,7 @@ var BaseCrudDialect = class {
|
|
|
735
712
|
take = -take;
|
|
736
713
|
}
|
|
737
714
|
result = this.buildSkipTake(result, skip, take);
|
|
738
|
-
result = this.buildOrderBy(result, model, modelAlias, args.orderBy,
|
|
715
|
+
result = this.buildOrderBy(result, model, modelAlias, args.orderBy, negateOrderBy);
|
|
739
716
|
if ("distinct" in args && args.distinct) {
|
|
740
717
|
const distinct = ensureArray(args.distinct);
|
|
741
718
|
if (this.supportsDistinctOn) {
|
|
@@ -1094,16 +1071,12 @@ var BaseCrudDialect = class {
|
|
|
1094
1071
|
]);
|
|
1095
1072
|
return this.and(...conditions.conditions);
|
|
1096
1073
|
}
|
|
1097
|
-
buildOrderBy(query, model, modelAlias, orderBy,
|
|
1074
|
+
buildOrderBy(query, model, modelAlias, orderBy, negated) {
|
|
1098
1075
|
if (!orderBy) {
|
|
1099
|
-
|
|
1100
|
-
orderBy = makeDefaultOrderBy(this.schema, model);
|
|
1101
|
-
} else {
|
|
1102
|
-
return query;
|
|
1103
|
-
}
|
|
1076
|
+
return query;
|
|
1104
1077
|
}
|
|
1105
1078
|
let result = query;
|
|
1106
|
-
const
|
|
1079
|
+
const buildFieldRef = /* @__PURE__ */ __name((model2, field, modelAlias2) => {
|
|
1107
1080
|
const fieldDef = requireField(this.schema, model2, field);
|
|
1108
1081
|
return fieldDef.originModel ? this.fieldRef(fieldDef.originModel, field, fieldDef.originModel) : this.fieldRef(model2, field, modelAlias2);
|
|
1109
1082
|
}, "buildFieldRef");
|
|
@@ -1122,7 +1095,7 @@ var BaseCrudDialect = class {
|
|
|
1122
1095
|
invariant2(value && typeof value === "object", `invalid orderBy value for field "${field}"`);
|
|
1123
1096
|
for (const [k, v] of Object.entries(value)) {
|
|
1124
1097
|
invariant2(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
|
|
1125
|
-
result = result.orderBy((eb) => aggregate(eb,
|
|
1098
|
+
result = result.orderBy((eb) => aggregate(eb, buildFieldRef(model, k, modelAlias), field), sql.raw(this.negateSort(v, negated)));
|
|
1126
1099
|
}
|
|
1127
1100
|
continue;
|
|
1128
1101
|
}
|
|
@@ -1131,7 +1104,7 @@ var BaseCrudDialect = class {
|
|
|
1131
1104
|
invariant2(value && typeof value === "object", 'invalid orderBy value for field "_count"');
|
|
1132
1105
|
for (const [k, v] of Object.entries(value)) {
|
|
1133
1106
|
invariant2(v === "asc" || v === "desc", `invalid orderBy value for field "${field}"`);
|
|
1134
|
-
result = result.orderBy((eb) => eb.fn.count(
|
|
1107
|
+
result = result.orderBy((eb) => eb.fn.count(buildFieldRef(model, k, modelAlias)), sql.raw(this.negateSort(v, negated)));
|
|
1135
1108
|
}
|
|
1136
1109
|
continue;
|
|
1137
1110
|
}
|
|
@@ -1140,7 +1113,7 @@ var BaseCrudDialect = class {
|
|
|
1140
1113
|
}
|
|
1141
1114
|
const fieldDef = requireField(this.schema, model, field);
|
|
1142
1115
|
if (!fieldDef.relation) {
|
|
1143
|
-
const fieldRef =
|
|
1116
|
+
const fieldRef = buildFieldRef(model, field, modelAlias);
|
|
1144
1117
|
if (value === "asc" || value === "desc") {
|
|
1145
1118
|
result = result.orderBy(fieldRef, this.negateSort(value, negated));
|
|
1146
1119
|
} else if (value && typeof value === "object" && "nulls" in value && "sort" in value && (value.sort === "asc" || value.sort === "desc") && (value.nulls === "first" || value.nulls === "last")) {
|
|
@@ -1169,7 +1142,7 @@ var BaseCrudDialect = class {
|
|
|
1169
1142
|
const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, relationModel);
|
|
1170
1143
|
return join.on((eb) => this.and(...joinPairs.map(([left, right]) => eb(this.eb.ref(left), "=", this.eb.ref(right)))));
|
|
1171
1144
|
});
|
|
1172
|
-
result = this.buildOrderBy(result, fieldDef.type, relationModel, value,
|
|
1145
|
+
result = this.buildOrderBy(result, fieldDef.type, relationModel, value, negated);
|
|
1173
1146
|
}
|
|
1174
1147
|
}
|
|
1175
1148
|
}
|
|
@@ -1216,13 +1189,9 @@ var BaseCrudDialect = class {
|
|
|
1216
1189
|
}
|
|
1217
1190
|
buildSelectField(query, model, modelAlias, field) {
|
|
1218
1191
|
const fieldDef = requireField(this.schema, model, field);
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
return query.select(this.eb.ref(`${modelAlias}.${field}`).as(field));
|
|
1223
|
-
} else {
|
|
1224
|
-
return this.buildSelectField(query, fieldDef.originModel, fieldDef.originModel, field);
|
|
1225
|
-
}
|
|
1192
|
+
const fieldModel = fieldDef.originModel ?? model;
|
|
1193
|
+
const alias = fieldDef.originModel ?? modelAlias;
|
|
1194
|
+
return query.select(() => this.fieldRef(fieldModel, field, alias).as(field));
|
|
1226
1195
|
}
|
|
1227
1196
|
buildDelegateJoin(thisModel, thisModelAlias, otherModelAlias, query) {
|
|
1228
1197
|
const idFields = requireIdFields(this.schema, thisModel);
|
|
@@ -1311,7 +1280,25 @@ var BaseCrudDialect = class {
|
|
|
1311
1280
|
return this.eb.not(this.and(...args));
|
|
1312
1281
|
}
|
|
1313
1282
|
fieldRef(model, field, modelAlias, inlineComputedField = true) {
|
|
1314
|
-
|
|
1283
|
+
const fieldDef = requireField(this.schema, model, field);
|
|
1284
|
+
if (!fieldDef.computed) {
|
|
1285
|
+
return this.eb.ref(modelAlias ? `${modelAlias}.${field}` : field);
|
|
1286
|
+
} else {
|
|
1287
|
+
if (!inlineComputedField) {
|
|
1288
|
+
return this.eb.ref(modelAlias ? `${modelAlias}.${field}` : field);
|
|
1289
|
+
}
|
|
1290
|
+
let computer;
|
|
1291
|
+
if ("computedFields" in this.options) {
|
|
1292
|
+
const computedFields = this.options.computedFields;
|
|
1293
|
+
computer = computedFields?.[fieldDef.originModel ?? model]?.[field];
|
|
1294
|
+
}
|
|
1295
|
+
if (!computer) {
|
|
1296
|
+
throw new QueryError(`Computed field "${field}" implementation not provided for model "${model}"`);
|
|
1297
|
+
}
|
|
1298
|
+
return computer(this.eb, {
|
|
1299
|
+
modelAlias
|
|
1300
|
+
});
|
|
1301
|
+
}
|
|
1315
1302
|
}
|
|
1316
1303
|
canJoinWithoutNestedSelect(modelDef, payload) {
|
|
1317
1304
|
if (modelDef.computedFields) {
|
|
@@ -1904,7 +1891,7 @@ var BaseOperationHandler = class {
|
|
|
1904
1891
|
buildCountSelection(query, model, parentAlias, payload) {
|
|
1905
1892
|
return query.select((eb) => this.dialect.buildCountJson(model, eb, parentAlias, payload).as("_count"));
|
|
1906
1893
|
}
|
|
1907
|
-
async create(kysely, model, data, fromRelation, creatingForDelegate = false) {
|
|
1894
|
+
async create(kysely, model, data, fromRelation, creatingForDelegate = false, returnFields) {
|
|
1908
1895
|
const modelDef = this.requireModel(model);
|
|
1909
1896
|
if (modelDef.isDelegate && !creatingForDelegate) {
|
|
1910
1897
|
throw new QueryError(`Model "${this.model}" is a delegate and cannot be created directly.`);
|
|
@@ -1957,8 +1944,8 @@ var BaseOperationHandler = class {
|
|
|
1957
1944
|
createFields = baseCreateResult.remainingFields;
|
|
1958
1945
|
}
|
|
1959
1946
|
const updatedData = this.fillGeneratedAndDefaultValues(modelDef, createFields);
|
|
1960
|
-
|
|
1961
|
-
const query = kysely.insertInto(model).$if(Object.keys(updatedData).length === 0, (qb) => qb.defaultValues()).$if(Object.keys(updatedData).length > 0, (qb) => qb.values(updatedData)).returning(
|
|
1947
|
+
returnFields = returnFields ?? requireIdFields(this.schema, model);
|
|
1948
|
+
const query = kysely.insertInto(model).$if(Object.keys(updatedData).length === 0, (qb) => qb.defaultValues()).$if(Object.keys(updatedData).length > 0, (qb) => qb.values(updatedData)).returning(returnFields).modifyEnd(this.makeContextComment({
|
|
1962
1949
|
model,
|
|
1963
1950
|
operation: "create"
|
|
1964
1951
|
}));
|
|
@@ -2163,7 +2150,7 @@ var BaseOperationHandler = class {
|
|
|
2163
2150
|
}
|
|
2164
2151
|
}
|
|
2165
2152
|
}
|
|
2166
|
-
async createMany(kysely, model, input, returnData, fromRelation) {
|
|
2153
|
+
async createMany(kysely, model, input, returnData, fromRelation, fieldsToReturn) {
|
|
2167
2154
|
if (!input.data || Array.isArray(input.data) && input.data.length === 0) {
|
|
2168
2155
|
return returnData ? [] : {
|
|
2169
2156
|
count: 0
|
|
@@ -2232,8 +2219,8 @@ var BaseOperationHandler = class {
|
|
|
2232
2219
|
count: Number(result.numAffectedRows)
|
|
2233
2220
|
};
|
|
2234
2221
|
} else {
|
|
2235
|
-
|
|
2236
|
-
const result = await query.returning(
|
|
2222
|
+
fieldsToReturn = fieldsToReturn ?? requireIdFields(this.schema, model);
|
|
2223
|
+
const result = await query.returning(fieldsToReturn).execute();
|
|
2237
2224
|
return result;
|
|
2238
2225
|
}
|
|
2239
2226
|
}
|
|
@@ -2313,7 +2300,7 @@ var BaseOperationHandler = class {
|
|
|
2313
2300
|
return void 0;
|
|
2314
2301
|
}
|
|
2315
2302
|
}
|
|
2316
|
-
async update(kysely, model, where, data, fromRelation, allowRelationUpdate = true, throwIfNotFound = true) {
|
|
2303
|
+
async update(kysely, model, where, data, fromRelation, allowRelationUpdate = true, throwIfNotFound = true, fieldsToReturn) {
|
|
2317
2304
|
if (!data || typeof data !== "object") {
|
|
2318
2305
|
throw new InternalError("data must be an object");
|
|
2319
2306
|
}
|
|
@@ -2419,8 +2406,8 @@ var BaseOperationHandler = class {
|
|
|
2419
2406
|
if (!hasFieldUpdate) {
|
|
2420
2407
|
return combinedWhere;
|
|
2421
2408
|
} else {
|
|
2422
|
-
|
|
2423
|
-
const query = kysely.updateTable(model).where(() => this.dialect.buildFilter(model, model, combinedWhere)).set(updateFields).returning(
|
|
2409
|
+
fieldsToReturn = fieldsToReturn ?? requireIdFields(this.schema, model);
|
|
2410
|
+
const query = kysely.updateTable(model).where(() => this.dialect.buildFilter(model, model, combinedWhere)).set(updateFields).returning(fieldsToReturn).modifyEnd(this.makeContextComment({
|
|
2424
2411
|
model,
|
|
2425
2412
|
operation: "update"
|
|
2426
2413
|
}));
|
|
@@ -2512,7 +2499,7 @@ var BaseOperationHandler = class {
|
|
|
2512
2499
|
makeContextComment(_context) {
|
|
2513
2500
|
return sql4``;
|
|
2514
2501
|
}
|
|
2515
|
-
async updateMany(kysely, model, where, data, limit, returnData, filterModel) {
|
|
2502
|
+
async updateMany(kysely, model, where, data, limit, returnData, filterModel, fieldsToReturn) {
|
|
2516
2503
|
if (typeof data !== "object") {
|
|
2517
2504
|
throw new InternalError("data must be an object");
|
|
2518
2505
|
}
|
|
@@ -2569,8 +2556,8 @@ var BaseOperationHandler = class {
|
|
|
2569
2556
|
count: Number(result.numAffectedRows)
|
|
2570
2557
|
};
|
|
2571
2558
|
} else {
|
|
2572
|
-
|
|
2573
|
-
const finalQuery = query.returning(
|
|
2559
|
+
fieldsToReturn = fieldsToReturn ?? requireIdFields(this.schema, model);
|
|
2560
|
+
const finalQuery = query.returning(fieldsToReturn);
|
|
2574
2561
|
const result = await this.executeQuery(kysely, finalQuery, "update");
|
|
2575
2562
|
return result.rows;
|
|
2576
2563
|
}
|
|
@@ -2974,7 +2961,7 @@ var BaseOperationHandler = class {
|
|
|
2974
2961
|
});
|
|
2975
2962
|
}
|
|
2976
2963
|
}
|
|
2977
|
-
if (throwForNotFound && expectedDeleteCount > deleteResult.
|
|
2964
|
+
if (throwForNotFound && expectedDeleteCount > deleteResult.rows.length) {
|
|
2978
2965
|
throw new NotFoundError(deleteFromModel);
|
|
2979
2966
|
}
|
|
2980
2967
|
}
|
|
@@ -2982,7 +2969,7 @@ var BaseOperationHandler = class {
|
|
|
2982
2969
|
return enumerate(data).map((item) => flattenCompoundUniqueFilters(this.schema, model, item));
|
|
2983
2970
|
}
|
|
2984
2971
|
// #endregion
|
|
2985
|
-
async delete(kysely, model, where, limit, filterModel) {
|
|
2972
|
+
async delete(kysely, model, where, limit, filterModel, fieldsToReturn) {
|
|
2986
2973
|
filterModel ??= model;
|
|
2987
2974
|
const modelDef = this.requireModel(model);
|
|
2988
2975
|
if (modelDef.baseModel) {
|
|
@@ -2991,7 +2978,8 @@ var BaseOperationHandler = class {
|
|
|
2991
2978
|
}
|
|
2992
2979
|
return this.processBaseModelDelete(kysely, modelDef.baseModel, where, limit, filterModel);
|
|
2993
2980
|
}
|
|
2994
|
-
|
|
2981
|
+
fieldsToReturn = fieldsToReturn ?? requireIdFields(this.schema, model);
|
|
2982
|
+
let query = kysely.deleteFrom(model).returning(fieldsToReturn);
|
|
2995
2983
|
let needIdFilter = false;
|
|
2996
2984
|
if (limit !== void 0 && !this.dialect.supportsDeleteWithLimit) {
|
|
2997
2985
|
needIdFilter = true;
|
|
@@ -3011,10 +2999,7 @@ var BaseOperationHandler = class {
|
|
|
3011
2999
|
model,
|
|
3012
3000
|
operation: "delete"
|
|
3013
3001
|
}));
|
|
3014
|
-
|
|
3015
|
-
return {
|
|
3016
|
-
count: Number(result.numAffectedRows)
|
|
3017
|
-
};
|
|
3002
|
+
return this.executeQuery(kysely, query, "delete");
|
|
3018
3003
|
}
|
|
3019
3004
|
async processDelegateRelationDelete(kysely, modelDef, where, limit) {
|
|
3020
3005
|
for (const fieldDef of Object.values(modelDef.fields)) {
|
|
@@ -3068,7 +3053,7 @@ var BaseOperationHandler = class {
|
|
|
3068
3053
|
return callback(this.kysely);
|
|
3069
3054
|
} else {
|
|
3070
3055
|
let txBuilder = this.kysely.transaction();
|
|
3071
|
-
txBuilder = txBuilder.setIsolationLevel(isolationLevel ?? TransactionIsolationLevel.
|
|
3056
|
+
txBuilder = txBuilder.setIsolationLevel(isolationLevel ?? TransactionIsolationLevel.ReadCommitted);
|
|
3072
3057
|
return txBuilder.execute(callback);
|
|
3073
3058
|
}
|
|
3074
3059
|
}
|
|
@@ -3120,6 +3105,48 @@ var BaseOperationHandler = class {
|
|
|
3120
3105
|
}
|
|
3121
3106
|
return result.rows[0];
|
|
3122
3107
|
}
|
|
3108
|
+
mutationNeedsReadBack(model, args) {
|
|
3109
|
+
if (this.hasPolicyEnabled) {
|
|
3110
|
+
return {
|
|
3111
|
+
needReadBack: true,
|
|
3112
|
+
selectedFields: void 0
|
|
3113
|
+
};
|
|
3114
|
+
}
|
|
3115
|
+
if (args.include && typeof args.include === "object" && Object.keys(args.include).length > 0) {
|
|
3116
|
+
return {
|
|
3117
|
+
needReadBack: true,
|
|
3118
|
+
selectedFields: void 0
|
|
3119
|
+
};
|
|
3120
|
+
}
|
|
3121
|
+
const modelDef = this.requireModel(model);
|
|
3122
|
+
if (modelDef.baseModel || modelDef.isDelegate) {
|
|
3123
|
+
return {
|
|
3124
|
+
needReadBack: true,
|
|
3125
|
+
selectedFields: void 0
|
|
3126
|
+
};
|
|
3127
|
+
}
|
|
3128
|
+
const allFields = Object.keys(modelDef.fields);
|
|
3129
|
+
const relationFields = Object.values(modelDef.fields).filter((f) => f.relation).map((f) => f.name);
|
|
3130
|
+
const computedFields = Object.values(modelDef.fields).filter((f) => f.computed).map((f) => f.name);
|
|
3131
|
+
const omit = Object.entries(args.omit ?? {}).filter(([, v]) => v).map(([k]) => k);
|
|
3132
|
+
const allFieldsSelected = [];
|
|
3133
|
+
if (!args.select || typeof args.select !== "object") {
|
|
3134
|
+
allFieldsSelected.push(...allFields.filter((f) => !relationFields.includes(f) && !omit.includes(f)));
|
|
3135
|
+
} else {
|
|
3136
|
+
allFieldsSelected.push(...Object.entries(args.select).filter(([k, v]) => v && !omit.includes(k)).map(([k]) => k));
|
|
3137
|
+
}
|
|
3138
|
+
if (allFieldsSelected.some((f) => relationFields.includes(f) || computedFields.includes(f))) {
|
|
3139
|
+
return {
|
|
3140
|
+
needReadBack: true,
|
|
3141
|
+
selectedFields: void 0
|
|
3142
|
+
};
|
|
3143
|
+
} else {
|
|
3144
|
+
return {
|
|
3145
|
+
needReadBack: false,
|
|
3146
|
+
selectedFields: allFieldsSelected
|
|
3147
|
+
};
|
|
3148
|
+
}
|
|
3149
|
+
}
|
|
3123
3150
|
};
|
|
3124
3151
|
|
|
3125
3152
|
// src/client/crud/operations/aggregate.ts
|
|
@@ -3155,7 +3182,7 @@ var AggregateOperationHandler = class extends BaseOperationHandler {
|
|
|
3155
3182
|
take = -take;
|
|
3156
3183
|
}
|
|
3157
3184
|
subQuery = this.dialect.buildSkipTake(subQuery, skip, take);
|
|
3158
|
-
subQuery = this.dialect.buildOrderBy(subQuery, this.model, this.model, parsedArgs.orderBy,
|
|
3185
|
+
subQuery = this.dialect.buildOrderBy(subQuery, this.model, this.model, parsedArgs.orderBy, negateOrderBy);
|
|
3159
3186
|
return subQuery.as("$sub");
|
|
3160
3187
|
});
|
|
3161
3188
|
for (const [key, value] of Object.entries(parsedArgs)) {
|
|
@@ -3280,14 +3307,19 @@ var CreateOperationHandler = class extends BaseOperationHandler {
|
|
|
3280
3307
|
}).exhaustive();
|
|
3281
3308
|
}
|
|
3282
3309
|
async runCreate(args) {
|
|
3310
|
+
const { needReadBack, selectedFields } = this.mutationNeedsReadBack(this.model, args);
|
|
3283
3311
|
const result = await this.safeTransaction(async (tx) => {
|
|
3284
|
-
const createResult = await this.create(tx, this.model, args.data);
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3312
|
+
const createResult = await this.create(tx, this.model, args.data, void 0, false, selectedFields);
|
|
3313
|
+
if (needReadBack) {
|
|
3314
|
+
return this.readUnique(tx, this.model, {
|
|
3315
|
+
select: args.select,
|
|
3316
|
+
include: args.include,
|
|
3317
|
+
omit: args.omit,
|
|
3318
|
+
where: getIdValues(this.schema, this.model, createResult)
|
|
3319
|
+
});
|
|
3320
|
+
} else {
|
|
3321
|
+
return createResult;
|
|
3322
|
+
}
|
|
3291
3323
|
});
|
|
3292
3324
|
if (!result && this.hasPolicyEnabled) {
|
|
3293
3325
|
throw new RejectedByPolicyError(this.model, RejectedByPolicyReason.CANNOT_READ_BACK, `result is not allowed to be read back`);
|
|
@@ -3306,15 +3338,20 @@ var CreateOperationHandler = class extends BaseOperationHandler {
|
|
|
3306
3338
|
if (args === void 0) {
|
|
3307
3339
|
return [];
|
|
3308
3340
|
}
|
|
3341
|
+
const { needReadBack, selectedFields } = this.mutationNeedsReadBack(this.model, args);
|
|
3309
3342
|
return this.safeTransaction(async (tx) => {
|
|
3310
|
-
const createResult = await this.createMany(tx, this.model, args, true);
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3343
|
+
const createResult = await this.createMany(tx, this.model, args, true, void 0, selectedFields);
|
|
3344
|
+
if (needReadBack) {
|
|
3345
|
+
return this.read(tx, this.model, {
|
|
3346
|
+
select: args.select,
|
|
3347
|
+
omit: args.omit,
|
|
3348
|
+
where: {
|
|
3349
|
+
OR: createResult.map((item) => getIdValues(this.schema, this.model, item))
|
|
3350
|
+
}
|
|
3351
|
+
});
|
|
3352
|
+
} else {
|
|
3353
|
+
return createResult;
|
|
3354
|
+
}
|
|
3318
3355
|
});
|
|
3319
3356
|
}
|
|
3320
3357
|
};
|
|
@@ -3330,27 +3367,34 @@ var DeleteOperationHandler = class extends BaseOperationHandler {
|
|
|
3330
3367
|
return match9(operation).with("delete", () => this.runDelete(this.inputValidator.validateDeleteArgs(this.model, normalizedArgs))).with("deleteMany", () => this.runDeleteMany(this.inputValidator.validateDeleteManyArgs(this.model, normalizedArgs))).exhaustive();
|
|
3331
3368
|
}
|
|
3332
3369
|
async runDelete(args) {
|
|
3333
|
-
const
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3370
|
+
const { needReadBack, selectedFields } = this.mutationNeedsReadBack(this.model, args);
|
|
3371
|
+
const result = await this.safeTransaction(async (tx) => {
|
|
3372
|
+
let preDeleteRead = void 0;
|
|
3373
|
+
if (needReadBack) {
|
|
3374
|
+
preDeleteRead = await this.readUnique(tx, this.model, {
|
|
3375
|
+
select: args.select,
|
|
3376
|
+
include: args.include,
|
|
3377
|
+
omit: args.omit,
|
|
3378
|
+
where: args.where
|
|
3379
|
+
});
|
|
3380
|
+
}
|
|
3381
|
+
const deleteResult = await this.delete(tx, this.model, args.where, void 0, void 0, selectedFields);
|
|
3382
|
+
if (deleteResult.rows.length === 0) {
|
|
3342
3383
|
throw new NotFoundError(this.model);
|
|
3343
3384
|
}
|
|
3385
|
+
return needReadBack ? preDeleteRead : deleteResult.rows[0];
|
|
3344
3386
|
});
|
|
3345
|
-
if (!
|
|
3387
|
+
if (!result && this.hasPolicyEnabled) {
|
|
3346
3388
|
throw new RejectedByPolicyError(this.model, RejectedByPolicyReason.CANNOT_READ_BACK, "result is not allowed to be read back");
|
|
3347
3389
|
}
|
|
3348
|
-
return
|
|
3390
|
+
return result;
|
|
3349
3391
|
}
|
|
3350
3392
|
async runDeleteMany(args) {
|
|
3351
3393
|
return await this.safeTransaction(async (tx) => {
|
|
3352
3394
|
const result = await this.delete(tx, this.model, args?.where, args?.limit);
|
|
3353
|
-
return
|
|
3395
|
+
return {
|
|
3396
|
+
count: result.rows.length
|
|
3397
|
+
};
|
|
3354
3398
|
});
|
|
3355
3399
|
}
|
|
3356
3400
|
};
|
|
@@ -3386,29 +3430,23 @@ var GroupByOperationHandler = class extends BaseOperationHandler {
|
|
|
3386
3430
|
async handle(_operation, args) {
|
|
3387
3431
|
const normalizedArgs = this.normalizeArgs(args);
|
|
3388
3432
|
const parsedArgs = this.inputValidator.validateGroupByArgs(this.model, normalizedArgs);
|
|
3389
|
-
let query = this.kysely.selectFrom((
|
|
3390
|
-
|
|
3391
|
-
const skip = parsedArgs?.skip;
|
|
3392
|
-
let take = parsedArgs?.take;
|
|
3393
|
-
let negateOrderBy = false;
|
|
3394
|
-
if (take !== void 0 && take < 0) {
|
|
3395
|
-
negateOrderBy = true;
|
|
3396
|
-
take = -take;
|
|
3397
|
-
}
|
|
3398
|
-
subQuery = this.dialect.buildSkipTake(subQuery, skip, take);
|
|
3399
|
-
subQuery = this.dialect.buildOrderBy(subQuery, this.model, this.model, void 0, skip !== void 0 || take !== void 0, negateOrderBy);
|
|
3400
|
-
return subQuery.as("$sub");
|
|
3401
|
-
});
|
|
3402
|
-
const fieldRef = /* @__PURE__ */ __name((field) => this.dialect.fieldRef(this.model, field, "$sub"), "fieldRef");
|
|
3433
|
+
let query = this.kysely.selectFrom(this.model).where(() => this.dialect.buildFilter(this.model, this.model, parsedArgs?.where));
|
|
3434
|
+
const fieldRef = /* @__PURE__ */ __name((field) => this.dialect.fieldRef(this.model, field), "fieldRef");
|
|
3403
3435
|
const bys = typeof parsedArgs.by === "string" ? [
|
|
3404
3436
|
parsedArgs.by
|
|
3405
3437
|
] : parsedArgs.by;
|
|
3406
3438
|
query = query.groupBy(bys.map((by) => fieldRef(by)));
|
|
3407
|
-
|
|
3408
|
-
|
|
3439
|
+
const skip = parsedArgs?.skip;
|
|
3440
|
+
let take = parsedArgs?.take;
|
|
3441
|
+
let negateOrderBy = false;
|
|
3442
|
+
if (take !== void 0 && take < 0) {
|
|
3443
|
+
negateOrderBy = true;
|
|
3444
|
+
take = -take;
|
|
3409
3445
|
}
|
|
3446
|
+
query = this.dialect.buildSkipTake(query, skip, take);
|
|
3447
|
+
query = this.dialect.buildOrderBy(query, this.model, this.model, parsedArgs.orderBy, negateOrderBy);
|
|
3410
3448
|
if (parsedArgs.having) {
|
|
3411
|
-
query = query.having(() => this.dialect.buildFilter(this.model,
|
|
3449
|
+
query = query.having(() => this.dialect.buildFilter(this.model, this.model, parsedArgs.having));
|
|
3412
3450
|
}
|
|
3413
3451
|
for (const by of bys) {
|
|
3414
3452
|
query = query.select(() => fieldRef(by).as(by));
|
|
@@ -3497,29 +3535,31 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
|
|
|
3497
3535
|
return match11(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();
|
|
3498
3536
|
}
|
|
3499
3537
|
async runUpdate(args) {
|
|
3500
|
-
const
|
|
3501
|
-
|
|
3502
|
-
const
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3538
|
+
const { needReadBack, selectedFields } = this.needReadBack(args);
|
|
3539
|
+
const result = await this.safeTransaction(async (tx) => {
|
|
3540
|
+
const updateResult = await this.update(tx, this.model, args.where, args.data, void 0, void 0, void 0, selectedFields);
|
|
3541
|
+
if (needReadBack) {
|
|
3542
|
+
const readFilter = updateResult ?? args.where;
|
|
3543
|
+
let readBackResult = void 0;
|
|
3544
|
+
readBackResult = await this.readUnique(tx, this.model, {
|
|
3506
3545
|
select: args.select,
|
|
3507
3546
|
include: args.include,
|
|
3508
3547
|
omit: args.omit,
|
|
3509
3548
|
where: readFilter
|
|
3510
3549
|
});
|
|
3511
|
-
|
|
3550
|
+
return readBackResult;
|
|
3551
|
+
} else {
|
|
3552
|
+
return updateResult;
|
|
3512
3553
|
}
|
|
3513
|
-
return readBackResult2;
|
|
3514
3554
|
});
|
|
3515
|
-
if (!
|
|
3555
|
+
if (!result) {
|
|
3516
3556
|
if (this.hasPolicyEnabled) {
|
|
3517
3557
|
throw new RejectedByPolicyError(this.model, RejectedByPolicyReason.CANNOT_READ_BACK, "result is not allowed to be read back");
|
|
3518
3558
|
} else {
|
|
3519
3559
|
return null;
|
|
3520
3560
|
}
|
|
3521
3561
|
} else {
|
|
3522
|
-
return
|
|
3562
|
+
return result;
|
|
3523
3563
|
}
|
|
3524
3564
|
}
|
|
3525
3565
|
async runUpdateMany(args) {
|
|
@@ -3531,19 +3571,27 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
|
|
|
3531
3571
|
if (!args) {
|
|
3532
3572
|
return [];
|
|
3533
3573
|
}
|
|
3574
|
+
const { needReadBack, selectedFields } = this.needReadBack(args);
|
|
3534
3575
|
const { readBackResult, updateResult } = await this.safeTransaction(async (tx) => {
|
|
3535
|
-
const updateResult2 = await this.updateMany(tx, this.model, args.where, args.data, args.limit, true);
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
|
|
3576
|
+
const updateResult2 = await this.updateMany(tx, this.model, args.where, args.data, args.limit, true, void 0, selectedFields);
|
|
3577
|
+
if (needReadBack) {
|
|
3578
|
+
const readBackResult2 = await this.read(tx, this.model, {
|
|
3579
|
+
select: args.select,
|
|
3580
|
+
omit: args.omit,
|
|
3581
|
+
where: {
|
|
3582
|
+
OR: updateResult2.map((item) => getIdValues(this.schema, this.model, item))
|
|
3583
|
+
}
|
|
3584
|
+
});
|
|
3585
|
+
return {
|
|
3586
|
+
readBackResult: readBackResult2,
|
|
3587
|
+
updateResult: updateResult2
|
|
3588
|
+
};
|
|
3589
|
+
} else {
|
|
3590
|
+
return {
|
|
3591
|
+
readBackResult: updateResult2,
|
|
3592
|
+
updateResult: updateResult2
|
|
3593
|
+
};
|
|
3594
|
+
}
|
|
3547
3595
|
});
|
|
3548
3596
|
if (readBackResult.length < updateResult.length && this.hasPolicyEnabled) {
|
|
3549
3597
|
throw new RejectedByPolicyError(this.model, RejectedByPolicyReason.CANNOT_READ_BACK, "result is not allowed to be read back");
|
|
@@ -3551,23 +3599,49 @@ var UpdateOperationHandler = class extends BaseOperationHandler {
|
|
|
3551
3599
|
return readBackResult;
|
|
3552
3600
|
}
|
|
3553
3601
|
async runUpsert(args) {
|
|
3602
|
+
const { needReadBack, selectedFields } = this.needReadBack(args);
|
|
3554
3603
|
const result = await this.safeTransaction(async (tx) => {
|
|
3555
|
-
let mutationResult = await this.update(tx, this.model, args.where, args.update, void 0, true, false);
|
|
3604
|
+
let mutationResult = await this.update(tx, this.model, args.where, args.update, void 0, true, false, selectedFields);
|
|
3556
3605
|
if (!mutationResult) {
|
|
3557
|
-
mutationResult = await this.create(tx, this.model, args.create);
|
|
3606
|
+
mutationResult = await this.create(tx, this.model, args.create, void 0, void 0, selectedFields);
|
|
3607
|
+
}
|
|
3608
|
+
if (needReadBack) {
|
|
3609
|
+
return this.readUnique(tx, this.model, {
|
|
3610
|
+
select: args.select,
|
|
3611
|
+
include: args.include,
|
|
3612
|
+
omit: args.omit,
|
|
3613
|
+
where: getIdValues(this.schema, this.model, mutationResult)
|
|
3614
|
+
});
|
|
3615
|
+
} else {
|
|
3616
|
+
return mutationResult;
|
|
3558
3617
|
}
|
|
3559
|
-
return this.readUnique(tx, this.model, {
|
|
3560
|
-
select: args.select,
|
|
3561
|
-
include: args.include,
|
|
3562
|
-
omit: args.omit,
|
|
3563
|
-
where: getIdValues(this.schema, this.model, mutationResult)
|
|
3564
|
-
});
|
|
3565
3618
|
});
|
|
3566
3619
|
if (!result && this.hasPolicyEnabled) {
|
|
3567
3620
|
throw new RejectedByPolicyError(this.model, RejectedByPolicyReason.CANNOT_READ_BACK, "result is not allowed to be read back");
|
|
3568
3621
|
}
|
|
3569
3622
|
return result;
|
|
3570
3623
|
}
|
|
3624
|
+
needReadBack(args) {
|
|
3625
|
+
const baseResult = this.mutationNeedsReadBack(this.model, args);
|
|
3626
|
+
if (baseResult.needReadBack) {
|
|
3627
|
+
return baseResult;
|
|
3628
|
+
}
|
|
3629
|
+
const modelDef = this.requireModel(this.model);
|
|
3630
|
+
const nonRelationFields = Object.entries(modelDef.fields).filter(([_, def]) => !def.relation).map(([name, _]) => name);
|
|
3631
|
+
if (args.data && !Object.keys(args.data).some((field) => nonRelationFields.includes(field))) {
|
|
3632
|
+
return {
|
|
3633
|
+
needReadBack: true,
|
|
3634
|
+
selectedFields: void 0
|
|
3635
|
+
};
|
|
3636
|
+
}
|
|
3637
|
+
if (args.update && !Object.keys(args.update).some((field) => nonRelationFields.includes(field))) {
|
|
3638
|
+
return {
|
|
3639
|
+
needReadBack: true,
|
|
3640
|
+
selectedFields: void 0
|
|
3641
|
+
};
|
|
3642
|
+
}
|
|
3643
|
+
return baseResult;
|
|
3644
|
+
}
|
|
3571
3645
|
};
|
|
3572
3646
|
|
|
3573
3647
|
// src/client/crud/validator/index.ts
|
|
@@ -3932,12 +4006,12 @@ function evalCall(data, expr) {
|
|
|
3932
4006
|
__name(evalCall, "evalCall");
|
|
3933
4007
|
|
|
3934
4008
|
// src/client/crud/validator/index.ts
|
|
4009
|
+
var schemaCache = /* @__PURE__ */ new WeakMap();
|
|
3935
4010
|
var InputValidator = class {
|
|
3936
4011
|
static {
|
|
3937
4012
|
__name(this, "InputValidator");
|
|
3938
4013
|
}
|
|
3939
4014
|
client;
|
|
3940
|
-
schemaCache = /* @__PURE__ */ new Map();
|
|
3941
4015
|
constructor(client) {
|
|
3942
4016
|
this.client = client;
|
|
3943
4017
|
}
|
|
@@ -3986,16 +4060,34 @@ var InputValidator = class {
|
|
|
3986
4060
|
validateGroupByArgs(model, args) {
|
|
3987
4061
|
return this.validate(model, "groupBy", void 0, (model2) => this.makeGroupBySchema(model2), args);
|
|
3988
4062
|
}
|
|
4063
|
+
getSchemaCache(cacheKey) {
|
|
4064
|
+
let thisCache = schemaCache.get(this.schema);
|
|
4065
|
+
if (!thisCache) {
|
|
4066
|
+
thisCache = /* @__PURE__ */ new Map();
|
|
4067
|
+
schemaCache.set(this.schema, thisCache);
|
|
4068
|
+
}
|
|
4069
|
+
return thisCache.get(cacheKey);
|
|
4070
|
+
}
|
|
4071
|
+
setSchemaCache(cacheKey, schema) {
|
|
4072
|
+
let thisCache = schemaCache.get(this.schema);
|
|
4073
|
+
if (!thisCache) {
|
|
4074
|
+
thisCache = /* @__PURE__ */ new Map();
|
|
4075
|
+
schemaCache.set(this.schema, thisCache);
|
|
4076
|
+
}
|
|
4077
|
+
return thisCache.set(cacheKey, schema);
|
|
4078
|
+
}
|
|
3989
4079
|
validate(model, operation, options, getSchema, args) {
|
|
3990
4080
|
const cacheKey = stableStringify({
|
|
4081
|
+
type: "model",
|
|
3991
4082
|
model,
|
|
3992
4083
|
operation,
|
|
3993
|
-
options
|
|
4084
|
+
options,
|
|
4085
|
+
extraValidationsEnabled: this.extraValidationsEnabled
|
|
3994
4086
|
});
|
|
3995
|
-
let schema = this.
|
|
4087
|
+
let schema = this.getSchemaCache(cacheKey);
|
|
3996
4088
|
if (!schema) {
|
|
3997
4089
|
schema = getSchema(model, options);
|
|
3998
|
-
this.
|
|
4090
|
+
this.setSchemaCache(cacheKey, schema);
|
|
3999
4091
|
}
|
|
4000
4092
|
const { error, data } = schema.safeParse(args);
|
|
4001
4093
|
if (error) {
|
|
@@ -4054,8 +4146,12 @@ var InputValidator = class {
|
|
|
4054
4146
|
}
|
|
4055
4147
|
}
|
|
4056
4148
|
makeTypeDefSchema(type) {
|
|
4057
|
-
const key =
|
|
4058
|
-
|
|
4149
|
+
const key = stableStringify({
|
|
4150
|
+
type: "typedef",
|
|
4151
|
+
name: type,
|
|
4152
|
+
extraValidationsEnabled: this.extraValidationsEnabled
|
|
4153
|
+
});
|
|
4154
|
+
let schema = this.getSchemaCache(key);
|
|
4059
4155
|
if (schema) {
|
|
4060
4156
|
return schema;
|
|
4061
4157
|
}
|
|
@@ -4074,7 +4170,7 @@ var InputValidator = class {
|
|
|
4074
4170
|
fieldSchema
|
|
4075
4171
|
];
|
|
4076
4172
|
}))).passthrough();
|
|
4077
|
-
this.
|
|
4173
|
+
this.setSchemaCache(key, schema);
|
|
4078
4174
|
return schema;
|
|
4079
4175
|
}
|
|
4080
4176
|
makeWhereSchema(model, unique, withoutRelationFields = false, withAggregations = false) {
|
|
@@ -5523,7 +5619,18 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends DefaultQueryExe
|
|
|
5523
5619
|
nameMapper;
|
|
5524
5620
|
constructor(client, driver, compiler, adapter, connectionProvider, plugins = [], suppressMutationHooks = false) {
|
|
5525
5621
|
super(compiler, adapter, connectionProvider, plugins), this.client = client, this.driver = driver, this.compiler = compiler, this.connectionProvider = connectionProvider, this.suppressMutationHooks = suppressMutationHooks;
|
|
5526
|
-
this.
|
|
5622
|
+
if (this.schemaHasMappedNames(client.$schema)) {
|
|
5623
|
+
this.nameMapper = new QueryNameMapper(client.$schema);
|
|
5624
|
+
}
|
|
5625
|
+
}
|
|
5626
|
+
schemaHasMappedNames(schema) {
|
|
5627
|
+
const hasMapAttr = /* @__PURE__ */ __name((decl) => {
|
|
5628
|
+
if (decl.attributes?.some((attr) => attr.name === "@@map")) {
|
|
5629
|
+
return true;
|
|
5630
|
+
}
|
|
5631
|
+
return Object.values(decl.fields).some((field) => field.attributes?.some((attr) => attr.name === "@map"));
|
|
5632
|
+
}, "hasMapAttr");
|
|
5633
|
+
return Object.values(schema.models).some(hasMapAttr) || Object.values(schema.typeDefs ?? []).some(hasMapAttr);
|
|
5527
5634
|
}
|
|
5528
5635
|
get kysely() {
|
|
5529
5636
|
return this.client.$qb;
|
|
@@ -5538,7 +5645,7 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends DefaultQueryExe
|
|
|
5538
5645
|
try {
|
|
5539
5646
|
if (this.isMutationNode(compiledQuery.query) && !this.driver.isTransactionConnection(connection)) {
|
|
5540
5647
|
await this.driver.beginTransaction(connection, {
|
|
5541
|
-
isolationLevel: TransactionIsolationLevel.
|
|
5648
|
+
isolationLevel: TransactionIsolationLevel.ReadCommitted
|
|
5542
5649
|
});
|
|
5543
5650
|
startedTx = true;
|
|
5544
5651
|
}
|
|
@@ -5605,7 +5712,7 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends DefaultQueryExe
|
|
|
5605
5712
|
async proceedQuery(connection, query, parameters, queryId) {
|
|
5606
5713
|
let compiled;
|
|
5607
5714
|
if (this.suppressMutationHooks || !this.isMutationNode(query) || !this.hasEntityMutationPlugins) {
|
|
5608
|
-
const finalQuery2 = this.
|
|
5715
|
+
const finalQuery2 = this.processNameMapping(query);
|
|
5609
5716
|
compiled = this.compileQuery(finalQuery2);
|
|
5610
5717
|
if (parameters) {
|
|
5611
5718
|
compiled = {
|
|
@@ -5623,7 +5730,7 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends DefaultQueryExe
|
|
|
5623
5730
|
])
|
|
5624
5731
|
};
|
|
5625
5732
|
}
|
|
5626
|
-
const finalQuery = this.
|
|
5733
|
+
const finalQuery = this.processNameMapping(query);
|
|
5627
5734
|
compiled = this.compileQuery(finalQuery);
|
|
5628
5735
|
if (parameters) {
|
|
5629
5736
|
compiled = {
|
|
@@ -5651,6 +5758,9 @@ var ZenStackQueryExecutor = class _ZenStackQueryExecutor extends DefaultQueryExe
|
|
|
5651
5758
|
}
|
|
5652
5759
|
return result;
|
|
5653
5760
|
}
|
|
5761
|
+
processNameMapping(query) {
|
|
5762
|
+
return this.nameMapper?.transformNode(query) ?? query;
|
|
5763
|
+
}
|
|
5654
5764
|
createClientForConnection(connection, inTx) {
|
|
5655
5765
|
const innerExecutor = this.withConnectionProvider(new SingleConnectionProvider(connection));
|
|
5656
5766
|
innerExecutor.suppressMutationHooks = true;
|
|
@@ -6435,6 +6545,11 @@ var ClientImpl = class _ClientImpl {
|
|
|
6435
6545
|
...args
|
|
6436
6546
|
]);
|
|
6437
6547
|
}
|
|
6548
|
+
async $connect() {
|
|
6549
|
+
await this.kysely.connection().execute(async (conn) => {
|
|
6550
|
+
await conn.executeQuery(sql7`select 1`.compile(this.kysely));
|
|
6551
|
+
});
|
|
6552
|
+
}
|
|
6438
6553
|
async $disconnect() {
|
|
6439
6554
|
await this.kysely.destroy();
|
|
6440
6555
|
}
|