@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.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, skip !== void 0 || take !== void 0, negateOrderBy);
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, useDefaultIfEmpty, negated) {
1074
+ buildOrderBy(query, model, modelAlias, orderBy, negated) {
1098
1075
  if (!orderBy) {
1099
- if (useDefaultIfEmpty) {
1100
- orderBy = makeDefaultOrderBy(this.schema, model);
1101
- } else {
1102
- return query;
1103
- }
1076
+ return query;
1104
1077
  }
1105
1078
  let result = query;
1106
- const buildFieldRef2 = /* @__PURE__ */ __name((model2, field, modelAlias2) => {
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, buildFieldRef2(model, k, modelAlias), field), sql.raw(this.negateSort(v, negated)));
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(buildFieldRef2(model, k, modelAlias)), sql.raw(this.negateSort(v, negated)));
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 = buildFieldRef2(model, field, modelAlias);
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, false, negated);
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
- if (fieldDef.computed) {
1220
- return query.select(() => this.fieldRef(model, field, modelAlias).as(field));
1221
- } else if (!fieldDef.originModel) {
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
- return buildFieldRef(this.schema, model, field, this.options, this.eb, modelAlias, inlineComputedField);
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
- const idFields = requireIdFields(this.schema, model);
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(idFields).modifyEnd(this.makeContextComment({
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
- const idFields = requireIdFields(this.schema, model);
2236
- const result = await query.returning(idFields).execute();
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
- const idFields = requireIdFields(this.schema, model);
2423
- const query = kysely.updateTable(model).where(() => this.dialect.buildFilter(model, model, combinedWhere)).set(updateFields).returning(idFields).modifyEnd(this.makeContextComment({
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
- const idFields = requireIdFields(this.schema, model);
2573
- const finalQuery = query.returning(idFields);
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.count) {
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
- let query = kysely.deleteFrom(model);
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
- const result = await this.executeQuery(kysely, query, "delete");
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.RepeatableRead);
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, skip !== void 0 || take !== void 0, negateOrderBy);
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
- return this.readUnique(tx, this.model, {
3286
- select: args.select,
3287
- include: args.include,
3288
- omit: args.omit,
3289
- where: getIdValues(this.schema, this.model, createResult)
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
- return this.read(tx, this.model, {
3312
- select: args.select,
3313
- omit: args.omit,
3314
- where: {
3315
- OR: createResult.map((item) => getIdValues(this.schema, this.model, item))
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 existing = await this.readUnique(this.kysely, this.model, {
3334
- select: args.select,
3335
- include: args.include,
3336
- omit: args.omit,
3337
- where: args.where
3338
- });
3339
- await this.safeTransaction(async (tx) => {
3340
- const result = await this.delete(tx, this.model, args.where);
3341
- if (result.count === 0) {
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 (!existing && this.hasPolicyEnabled) {
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 existing;
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 result;
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((eb) => {
3390
- let subQuery = eb.selectFrom(this.model).selectAll().where(() => this.dialect.buildFilter(this.model, this.model, parsedArgs?.where));
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
- if (parsedArgs.orderBy) {
3408
- query = this.dialect.buildOrderBy(query, this.model, "$sub", parsedArgs.orderBy, false, false);
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, "$sub", parsedArgs.having));
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 readBackResult = await this.safeTransaction(async (tx) => {
3501
- const updateResult = await this.update(tx, this.model, args.where, args.data);
3502
- const readFilter = updateResult ?? args.where;
3503
- let readBackResult2 = void 0;
3504
- try {
3505
- readBackResult2 = await this.readUnique(tx, this.model, {
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
- } catch {
3550
+ return readBackResult;
3551
+ } else {
3552
+ return updateResult;
3512
3553
  }
3513
- return readBackResult2;
3514
3554
  });
3515
- if (!readBackResult) {
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 readBackResult;
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
- const readBackResult2 = await this.read(tx, this.model, {
3537
- select: args.select,
3538
- omit: args.omit,
3539
- where: {
3540
- OR: updateResult2.map((item) => getIdValues(this.schema, this.model, item))
3541
- }
3542
- });
3543
- return {
3544
- readBackResult: readBackResult2,
3545
- updateResult: updateResult2
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.schemaCache.get(cacheKey);
4087
+ let schema = this.getSchemaCache(cacheKey);
3996
4088
  if (!schema) {
3997
4089
  schema = getSchema(model, options);
3998
- this.schemaCache.set(cacheKey, schema);
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 = `$typedef-${type}`;
4058
- let schema = this.schemaCache.get(key);
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.schemaCache.set(key, schema);
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.nameMapper = new QueryNameMapper(client.$schema);
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.RepeatableRead
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.nameMapper.transformNode(query);
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.nameMapper.transformNode(query);
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
  }