@zenstackhq/runtime 3.0.0-alpha.32 → 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/index.js CHANGED
@@ -92,7 +92,10 @@ var ExpressionUtils = {
92
92
  isUnary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "unary"), "isUnary"),
93
93
  isBinary: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "binary"), "isBinary"),
94
94
  isField: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "field"), "isField"),
95
- isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember")
95
+ isMember: /* @__PURE__ */ __name((value) => ExpressionUtils.is(value, "member"), "isMember"),
96
+ getLiteralValue: /* @__PURE__ */ __name((expr2) => {
97
+ return ExpressionUtils.isLiteral(expr2) ? expr2.value : void 0;
98
+ }, "getLiteralValue")
96
99
  };
97
100
 
98
101
  // src/utils/object-utils.ts
@@ -1016,6 +1019,16 @@ var BaseCrudDialect = class {
1016
1019
  }
1017
1020
  return result;
1018
1021
  }
1022
+ buildModelSelect(eb, model, subQueryAlias, payload, selectAllFields) {
1023
+ let subQuery = this.buildSelectModel(eb, model, subQueryAlias);
1024
+ if (selectAllFields) {
1025
+ subQuery = this.buildSelectAllFields(model, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
1026
+ }
1027
+ if (payload && typeof payload === "object") {
1028
+ subQuery = this.buildFilterSortTake(model, payload, subQuery, subQueryAlias);
1029
+ }
1030
+ return subQuery;
1031
+ }
1019
1032
  buildSelectField(query, model, modelAlias, field) {
1020
1033
  const fieldDef = requireField(this.schema, model, field);
1021
1034
  if (fieldDef.computed) {
@@ -1113,6 +1126,18 @@ var BaseCrudDialect = class {
1113
1126
  fieldRef(model, field, eb, modelAlias, inlineComputedField = true) {
1114
1127
  return buildFieldRef(this.schema, model, field, this.options, eb, modelAlias, inlineComputedField);
1115
1128
  }
1129
+ canJoinWithoutNestedSelect(modelDef, payload) {
1130
+ if (modelDef.computedFields) {
1131
+ return false;
1132
+ }
1133
+ if (modelDef.baseModel || modelDef.isDelegate) {
1134
+ return false;
1135
+ }
1136
+ if (typeof payload === "object" && (payload.orderBy || payload.skip !== void 0 || payload.take !== void 0 || payload.cursor || payload.distinct)) {
1137
+ return false;
1138
+ }
1139
+ return true;
1140
+ }
1116
1141
  };
1117
1142
 
1118
1143
  // src/client/crud/dialects/postgresql.ts
@@ -1138,52 +1163,58 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1138
1163
  }
1139
1164
  }
1140
1165
  buildRelationSelection(query, model, relationField, parentAlias, payload) {
1141
- const joinedQuery = this.buildRelationJSON(model, query, relationField, parentAlias, payload);
1142
- return joinedQuery.select(`${parentAlias}$${relationField}.$j as ${relationField}`);
1166
+ const relationResultName = `${parentAlias}$${relationField}`;
1167
+ const joinedQuery = this.buildRelationJSON(model, query, relationField, parentAlias, payload, relationResultName);
1168
+ return joinedQuery.select(`${relationResultName}.$data as ${relationField}`);
1143
1169
  }
1144
- buildRelationJSON(model, qb, relationField, parentName, payload) {
1170
+ buildRelationJSON(model, qb, relationField, parentAlias, payload, resultName) {
1145
1171
  const relationFieldDef = requireField(this.schema, model, relationField);
1146
1172
  const relationModel = relationFieldDef.type;
1147
1173
  return qb.leftJoinLateral((eb) => {
1148
- const joinTableName = `${parentName}$${relationField}`;
1149
- let result = eb.selectFrom(`${relationModel} as ${joinTableName}`);
1150
- const subQueryAlias = `${relationModel}$${relationField}$sub`;
1151
- result = eb.selectFrom(() => {
1152
- let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
1153
- subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
1154
- if (payload && typeof payload === "object") {
1155
- subQuery = this.buildFilterSortTake(relationModel, payload, subQuery, subQueryAlias);
1156
- }
1157
- const m2m = getManyToManyRelation(this.schema, model, relationField);
1158
- if (m2m) {
1159
- const parentIds = getIdFields(this.schema, model);
1160
- const relationIds = getIdFields(this.schema, relationModel);
1161
- invariant2(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1162
- invariant2(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1163
- 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}`)));
1164
- } else {
1165
- const joinPairs = buildJoinPairs(this.schema, model, parentName, relationField, subQueryAlias);
1166
- subQuery = subQuery.where((eb2) => this.and(eb2, ...joinPairs.map(([left, right]) => eb2(sql2.ref(left), "=", sql2.ref(right)))));
1167
- }
1168
- return subQuery.as(joinTableName);
1169
- });
1170
- result = this.buildRelationObjectSelect(relationModel, joinTableName, relationField, relationFieldDef, result, payload, parentName);
1171
- result = this.buildRelationJoins(relationModel, relationField, result, payload, parentName);
1172
- return result.as(joinTableName);
1174
+ const relationSelectName = `${resultName}$sub`;
1175
+ const relationModelDef = requireModel(this.schema, relationModel);
1176
+ let tbl;
1177
+ if (this.canJoinWithoutNestedSelect(relationModelDef, payload)) {
1178
+ tbl = this.buildModelSelect(eb, relationModel, relationSelectName, payload, false);
1179
+ tbl = this.buildRelationJoinFilter(tbl, model, relationField, relationModel, relationSelectName, parentAlias);
1180
+ } else {
1181
+ tbl = eb.selectFrom(() => {
1182
+ let subQuery = this.buildModelSelect(eb, relationModel, `${relationSelectName}$t`, payload, true);
1183
+ subQuery = this.buildRelationJoinFilter(subQuery, model, relationField, relationModel, `${relationSelectName}$t`, parentAlias);
1184
+ return subQuery.as(relationSelectName);
1185
+ });
1186
+ }
1187
+ tbl = this.buildRelationObjectSelect(relationModel, relationSelectName, relationFieldDef, tbl, payload, resultName);
1188
+ tbl = this.buildRelationJoins(tbl, relationModel, relationSelectName, payload, resultName);
1189
+ return tbl.as(resultName);
1173
1190
  }, (join) => join.onTrue());
1174
1191
  }
1175
- buildRelationObjectSelect(relationModel, relationModelAlias, relationField, relationFieldDef, qb, payload, parentName) {
1192
+ buildRelationJoinFilter(query, model, relationField, relationModel, relationModelAlias, parentAlias) {
1193
+ const m2m = getManyToManyRelation(this.schema, model, relationField);
1194
+ if (m2m) {
1195
+ const parentIds = getIdFields(this.schema, model);
1196
+ const relationIds = getIdFields(this.schema, relationModel);
1197
+ invariant2(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1198
+ invariant2(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1199
+ 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}`)));
1200
+ } else {
1201
+ const joinPairs = buildJoinPairs(this.schema, model, parentAlias, relationField, relationModelAlias);
1202
+ query = query.where((eb) => this.and(eb, ...joinPairs.map(([left, right]) => eb(sql2.ref(left), "=", sql2.ref(right)))));
1203
+ }
1204
+ return query;
1205
+ }
1206
+ buildRelationObjectSelect(relationModel, relationModelAlias, relationFieldDef, qb, payload, parentResultName) {
1176
1207
  qb = qb.select((eb) => {
1177
- const objArgs = this.buildRelationObjectArgs(relationModel, relationModelAlias, relationField, eb, payload, parentName);
1208
+ const objArgs = this.buildRelationObjectArgs(relationModel, relationModelAlias, eb, payload, parentResultName);
1178
1209
  if (relationFieldDef.array) {
1179
- return eb.fn.coalesce(sql2`jsonb_agg(jsonb_build_object(${sql2.join(objArgs)}))`, sql2`'[]'::jsonb`).as("$j");
1210
+ return eb.fn.coalesce(sql2`jsonb_agg(jsonb_build_object(${sql2.join(objArgs)}))`, sql2`'[]'::jsonb`).as("$data");
1180
1211
  } else {
1181
- return sql2`jsonb_build_object(${sql2.join(objArgs)})`.as("$j");
1212
+ return sql2`jsonb_build_object(${sql2.join(objArgs)})`.as("$data");
1182
1213
  }
1183
1214
  });
1184
1215
  return qb;
1185
1216
  }
1186
- buildRelationObjectArgs(relationModel, relationModelAlias, relationField, eb, payload, parentAlias) {
1217
+ buildRelationObjectArgs(relationModel, relationModelAlias, eb, payload, parentResultName) {
1187
1218
  const relationModelDef = requireModel(this.schema, relationModel);
1188
1219
  const objArgs = [];
1189
1220
  const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
@@ -1201,14 +1232,14 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1201
1232
  } else if (payload.select) {
1202
1233
  objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
1203
1234
  if (field === "_count") {
1204
- const subJson = this.buildCountJson(relationModel, eb, `${parentAlias}$${relationField}`, value);
1235
+ const subJson = this.buildCountJson(relationModel, eb, relationModelAlias, value);
1205
1236
  return [
1206
1237
  sql2.lit(field),
1207
1238
  subJson
1208
1239
  ];
1209
1240
  } else {
1210
1241
  const fieldDef = requireField(this.schema, relationModel, field);
1211
- const fieldValue = fieldDef.relation ? eb.ref(`${parentAlias}$${relationField}$${field}.$j`) : this.fieldRef(relationModel, field, eb, void 0, false);
1242
+ const fieldValue = fieldDef.relation ? eb.ref(`${parentResultName}$${field}.$data`) : this.fieldRef(relationModel, field, eb, relationModelAlias, false);
1212
1243
  return [
1213
1244
  sql2.lit(field),
1214
1245
  fieldValue
@@ -1220,18 +1251,18 @@ var PostgresCrudDialect = class extends BaseCrudDialect {
1220
1251
  objArgs.push(...Object.entries(payload.include).filter(([, value]) => value).map(([field]) => [
1221
1252
  sql2.lit(field),
1222
1253
  // reference the synthesized JSON field
1223
- eb.ref(`${parentAlias}$${relationField}$${field}.$j`)
1254
+ eb.ref(`${parentResultName}$${field}.$data`)
1224
1255
  ]).flatMap((v) => v));
1225
1256
  }
1226
1257
  return objArgs;
1227
1258
  }
1228
- buildRelationJoins(relationModel, relationField, qb, payload, parentName) {
1229
- let result = qb;
1259
+ buildRelationJoins(query, relationModel, relationModelAlias, payload, parentResultName) {
1260
+ let result = query;
1230
1261
  if (typeof payload === "object") {
1231
1262
  const selectInclude = payload.include ?? payload.select;
1232
1263
  if (selectInclude && typeof selectInclude === "object") {
1233
1264
  Object.entries(selectInclude).filter(([, value]) => value).filter(([field]) => isRelationField(this.schema, relationModel, field)).forEach(([field, value]) => {
1234
- result = this.buildRelationJSON(relationModel, result, field, `${parentName}$${relationField}`, value);
1265
+ result = this.buildRelationJSON(relationModel, result, field, relationModelAlias, value, `${parentResultName}$${field}`);
1235
1266
  });
1236
1267
  }
1237
1268
  }
@@ -1311,32 +1342,18 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1311
1342
  const relationModel = relationFieldDef.type;
1312
1343
  const relationModelDef = requireModel(this.schema, relationModel);
1313
1344
  const subQueryName = `${parentAlias}$${relationField}`;
1314
- let tbl = eb.selectFrom(() => {
1315
- const subQueryAlias = `${parentAlias}$${relationField}$sub`;
1316
- let subQuery = this.buildSelectModel(eb, relationModel, subQueryAlias);
1317
- subQuery = this.buildSelectAllFields(relationModel, subQuery, typeof payload === "object" ? payload?.omit : void 0, subQueryAlias);
1318
- if (payload && typeof payload === "object") {
1319
- subQuery = this.buildFilterSortTake(relationModel, payload, subQuery, subQueryAlias);
1320
- }
1321
- const m2m = getManyToManyRelation(this.schema, model, relationField);
1322
- if (m2m) {
1323
- const parentIds = getIdFields(this.schema, model);
1324
- const relationIds = getIdFields(this.schema, relationModel);
1325
- invariant3(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1326
- invariant3(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1327
- 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}`)));
1328
- } else {
1329
- const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
1330
- keyPairs.forEach(({ fk, pk }) => {
1331
- if (ownedByModel) {
1332
- subQuery = subQuery.whereRef(`${subQueryAlias}.${pk}`, "=", `${parentAlias}.${fk}`);
1333
- } else {
1334
- subQuery = subQuery.whereRef(`${subQueryAlias}.${fk}`, "=", `${parentAlias}.${pk}`);
1335
- }
1336
- });
1337
- }
1338
- return subQuery.as(subQueryName);
1339
- });
1345
+ let tbl;
1346
+ if (this.canJoinWithoutNestedSelect(relationModelDef, payload)) {
1347
+ tbl = this.buildModelSelect(eb, relationModel, subQueryName, payload, false);
1348
+ tbl = this.buildRelationJoinFilter(tbl, model, relationField, subQueryName, parentAlias);
1349
+ } else {
1350
+ tbl = eb.selectFrom(() => {
1351
+ const selectModelAlias = `${parentAlias}$${relationField}$sub`;
1352
+ let selectModelQuery = this.buildModelSelect(eb, relationModel, selectModelAlias, payload, true);
1353
+ selectModelQuery = this.buildRelationJoinFilter(selectModelQuery, model, relationField, selectModelAlias, parentAlias);
1354
+ return selectModelQuery.as(subQueryName);
1355
+ });
1356
+ }
1340
1357
  tbl = tbl.select(() => {
1341
1358
  const objArgs = [];
1342
1359
  const descendantModels = getDelegateDescendantModels(this.schema, relationModel);
@@ -1349,7 +1366,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1349
1366
  if (payload === true || !payload.select) {
1350
1367
  objArgs.push(...Object.entries(relationModelDef.fields).filter(([, value]) => !value.relation).filter(([name]) => !(typeof payload === "object" && payload.omit?.[name] === true)).map(([field]) => [
1351
1368
  sql3.lit(field),
1352
- this.fieldRef(relationModel, field, eb, void 0, false)
1369
+ this.fieldRef(relationModel, field, eb, subQueryName, false)
1353
1370
  ]).flatMap((v) => v));
1354
1371
  } else if (payload.select) {
1355
1372
  objArgs.push(...Object.entries(payload.select).filter(([, value]) => value).map(([field, value]) => {
@@ -1370,7 +1387,7 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1370
1387
  } else {
1371
1388
  return [
1372
1389
  sql3.lit(field),
1373
- this.fieldRef(relationModel, field, eb, void 0, false)
1390
+ this.fieldRef(relationModel, field, eb, subQueryName, false)
1374
1391
  ];
1375
1392
  }
1376
1393
  }
@@ -1386,13 +1403,35 @@ var SqliteCrudDialect = class extends BaseCrudDialect {
1386
1403
  }).flatMap((v) => v));
1387
1404
  }
1388
1405
  if (relationFieldDef.array) {
1389
- return eb.fn.coalesce(sql3`json_group_array(json_object(${sql3.join(objArgs)}))`, sql3`json_array()`).as("$j");
1406
+ return eb.fn.coalesce(sql3`json_group_array(json_object(${sql3.join(objArgs)}))`, sql3`json_array()`).as("$data");
1390
1407
  } else {
1391
- return sql3`json_object(${sql3.join(objArgs)})`.as("data");
1408
+ return sql3`json_object(${sql3.join(objArgs)})`.as("$data");
1392
1409
  }
1393
1410
  });
1394
1411
  return tbl;
1395
1412
  }
1413
+ buildRelationJoinFilter(selectModelQuery, model, relationField, relationModelAlias, parentAlias) {
1414
+ const fieldDef = requireField(this.schema, model, relationField);
1415
+ const relationModel = fieldDef.type;
1416
+ const m2m = getManyToManyRelation(this.schema, model, relationField);
1417
+ if (m2m) {
1418
+ const parentIds = getIdFields(this.schema, model);
1419
+ const relationIds = getIdFields(this.schema, relationModel);
1420
+ invariant3(parentIds.length === 1, "many-to-many relation must have exactly one id field");
1421
+ invariant3(relationIds.length === 1, "many-to-many relation must have exactly one id field");
1422
+ 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}`)));
1423
+ } else {
1424
+ const { keyPairs, ownedByModel } = getRelationForeignKeyFieldPairs(this.schema, model, relationField);
1425
+ keyPairs.forEach(({ fk, pk }) => {
1426
+ if (ownedByModel) {
1427
+ selectModelQuery = selectModelQuery.whereRef(`${relationModelAlias}.${pk}`, "=", `${parentAlias}.${fk}`);
1428
+ } else {
1429
+ selectModelQuery = selectModelQuery.whereRef(`${relationModelAlias}.${fk}`, "=", `${parentAlias}.${pk}`);
1430
+ }
1431
+ });
1432
+ }
1433
+ return selectModelQuery;
1434
+ }
1396
1435
  buildSkipTake(query, skip, take) {
1397
1436
  if (take !== void 0) {
1398
1437
  query = query.limit(take);
@@ -5673,7 +5712,7 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
5673
5712
  schema;
5674
5713
  modelToTableMap = /* @__PURE__ */ new Map();
5675
5714
  fieldToColumnMap = /* @__PURE__ */ new Map();
5676
- modelScopes = [];
5715
+ scopes = [];
5677
5716
  constructor(schema) {
5678
5717
  super(), this.schema = schema;
5679
5718
  for (const [modelName, modelDef] of Object.entries(schema.models)) {
@@ -5694,12 +5733,23 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
5694
5733
  if (!node.from?.froms) {
5695
5734
  return super.transformSelectQuery(node);
5696
5735
  }
5697
- const scopes = this.createScopesFromFroms(node.from, true);
5736
+ const processedFroms = node.from.froms.map((from) => this.processSelectTable(from));
5737
+ const processedJoins = (node.joins ?? []).map((join) => this.processSelectTable(join.table));
5738
+ const scopes = [
5739
+ ...processedFroms.map(({ scope }) => scope),
5740
+ ...processedJoins.map(({ scope }) => scope)
5741
+ ];
5698
5742
  return this.withScopes(scopes, () => {
5743
+ const joins = node.joins ? node.joins.map((join, i) => ({
5744
+ ...join,
5745
+ table: processedJoins[i].node,
5746
+ on: this.transformNode(join.on)
5747
+ })) : void 0;
5699
5748
  return {
5700
5749
  ...super.transformSelectQuery(node),
5701
- // convert "from" to nested query as needed
5702
- from: this.processFrom(node.from)
5750
+ from: FromNode3.create(processedFroms.map((f) => f.node)),
5751
+ joins,
5752
+ selections: this.processSelectQuerySelections(node)
5703
5753
  };
5704
5754
  });
5705
5755
  }
@@ -5722,27 +5772,13 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
5722
5772
  selections: this.processSelections(node.selections)
5723
5773
  };
5724
5774
  }
5725
- transformJoin(node) {
5726
- const { alias, node: innerNode } = stripAlias(node.table);
5727
- if (TableNode4.is(innerNode)) {
5728
- const modelName = innerNode.table.identifier.name;
5729
- if (this.hasMappedColumns(modelName)) {
5730
- const select = this.createSelectAll(modelName);
5731
- return {
5732
- ...super.transformJoin(node),
5733
- table: this.wrapAlias(select, alias ?? modelName)
5734
- };
5735
- }
5736
- }
5737
- return super.transformJoin(node);
5738
- }
5739
5775
  transformReference(node) {
5740
5776
  if (!ColumnNode3.is(node.column)) {
5741
5777
  return super.transformReference(node);
5742
5778
  }
5743
- const { fieldDef, modelDef, scope } = this.resolveFieldFromScopes(node.column.column.name, node.table?.table.identifier.name);
5744
- if (fieldDef && !scope.namesMapped) {
5745
- const mappedFieldName = this.mapFieldName(modelDef.name, fieldDef.name);
5779
+ const scope = this.resolveFieldFromScopes(node.column.column.name, node.table?.table.identifier.name);
5780
+ if (scope && !scope.namesMapped && scope.model) {
5781
+ const mappedFieldName = this.mapFieldName(scope.model, node.column.column.name);
5746
5782
  let mappedTableName = node.table?.table.identifier.name;
5747
5783
  if (mappedTableName) {
5748
5784
  if (scope.alias === mappedTableName) {
@@ -5756,11 +5792,11 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
5756
5792
  }
5757
5793
  }
5758
5794
  transformColumn(node) {
5759
- const { modelDef, fieldDef, scope } = this.resolveFieldFromScopes(node.column.name);
5760
- if (!fieldDef || scope.namesMapped) {
5795
+ const scope = this.resolveFieldFromScopes(node.column.name);
5796
+ if (!scope || scope.namesMapped || !scope.model) {
5761
5797
  return super.transformColumn(node);
5762
5798
  }
5763
- const mappedName = this.mapFieldName(modelDef.name, fieldDef.name);
5799
+ const mappedName = this.mapFieldName(scope.model, node.column.name);
5764
5800
  return ColumnNode3.create(mappedName);
5765
5801
  }
5766
5802
  transformUpdateQuery(node) {
@@ -5783,7 +5819,14 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
5783
5819
  });
5784
5820
  }
5785
5821
  transformDeleteQuery(node) {
5786
- const scopes = this.createScopesFromFroms(node.from, false);
5822
+ const scopes = node.from.froms.map((node2) => {
5823
+ const { alias, node: innerNode } = stripAlias(node2);
5824
+ return {
5825
+ model: this.extractModelName(innerNode),
5826
+ alias,
5827
+ namesMapped: false
5828
+ };
5829
+ });
5787
5830
  const froms = node.from.froms.map((from) => {
5788
5831
  const { alias, node: innerNode } = stripAlias(from);
5789
5832
  if (TableNode4.is(innerNode)) {
@@ -5801,46 +5844,75 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
5801
5844
  }
5802
5845
  // #endregion
5803
5846
  // #region utils
5847
+ processSelectQuerySelections(node) {
5848
+ const selections = [];
5849
+ for (const selection of node.selections ?? []) {
5850
+ if (SelectAllNode.is(selection.selection)) {
5851
+ const scope = this.scopes[this.scopes.length - 1];
5852
+ if (scope?.model && !scope.namesMapped) {
5853
+ selections.push(...this.createSelectAllFields(scope.model, scope.alias));
5854
+ } else {
5855
+ selections.push(super.transformSelection(selection));
5856
+ }
5857
+ } else if (ReferenceNode3.is(selection.selection) || ColumnNode3.is(selection.selection)) {
5858
+ const transformed = this.transformNode(selection.selection);
5859
+ if (AliasNode5.is(transformed)) {
5860
+ selections.push(SelectionNode3.create(transformed));
5861
+ } else {
5862
+ const origFieldName = this.extractFieldName(selection.selection);
5863
+ const fieldName = this.extractFieldName(transformed);
5864
+ if (fieldName !== origFieldName) {
5865
+ selections.push(SelectionNode3.create(this.wrapAlias(transformed, origFieldName)));
5866
+ } else {
5867
+ selections.push(SelectionNode3.create(transformed));
5868
+ }
5869
+ }
5870
+ } else {
5871
+ selections.push(super.transformSelection(selection));
5872
+ }
5873
+ }
5874
+ return selections;
5875
+ }
5804
5876
  resolveFieldFromScopes(name, qualifier) {
5805
- for (const scope of this.modelScopes.toReversed()) {
5877
+ for (let i = this.scopes.length - 1; i >= 0; i--) {
5878
+ const scope = this.scopes[i];
5806
5879
  if (qualifier) {
5807
5880
  if (scope.alias) {
5808
- if (qualifier !== scope.alias) {
5881
+ if (scope.alias === qualifier) {
5882
+ return scope;
5883
+ } else {
5809
5884
  continue;
5810
5885
  }
5811
- } else {
5812
- if (qualifier !== scope.model) {
5886
+ } else if (scope.model) {
5887
+ if (scope.model === qualifier) {
5888
+ return scope;
5889
+ } else {
5813
5890
  continue;
5814
5891
  }
5815
5892
  }
5816
- }
5817
- const modelDef = getModel(this.schema, scope.model);
5818
- if (!modelDef) {
5819
- continue;
5820
- }
5821
- if (modelDef.fields[name]) {
5822
- return {
5823
- modelDef,
5824
- fieldDef: modelDef.fields[name],
5825
- scope
5826
- };
5893
+ } else {
5894
+ if (scope.model) {
5895
+ const modelDef = getModel(this.schema, scope.model);
5896
+ if (!modelDef) {
5897
+ continue;
5898
+ }
5899
+ if (modelDef.fields[name]) {
5900
+ return scope;
5901
+ }
5902
+ }
5827
5903
  }
5828
5904
  }
5829
- return {
5830
- modelDef: void 0,
5831
- fieldDef: void 0,
5832
- scope: void 0
5833
- };
5905
+ return void 0;
5834
5906
  }
5835
5907
  pushScope(scope) {
5836
- this.modelScopes.push(scope);
5908
+ this.scopes.push(scope);
5837
5909
  }
5838
5910
  withScope(scope, fn) {
5839
5911
  this.pushScope(scope);
5840
5912
  try {
5841
5913
  return fn();
5842
5914
  } finally {
5843
- this.modelScopes.pop();
5915
+ this.scopes.pop();
5844
5916
  }
5845
5917
  }
5846
5918
  withScopes(scopes, fn) {
@@ -5848,18 +5920,12 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
5848
5920
  try {
5849
5921
  return fn();
5850
5922
  } finally {
5851
- scopes.forEach(() => this.modelScopes.pop());
5923
+ scopes.forEach(() => this.scopes.pop());
5852
5924
  }
5853
5925
  }
5854
5926
  wrapAlias(node, alias) {
5855
5927
  return alias ? AliasNode5.create(node, IdentifierNode4.create(alias)) : node;
5856
5928
  }
5857
- ensureAlias(node, alias, fallbackName) {
5858
- if (!node) {
5859
- return node;
5860
- }
5861
- return alias ? AliasNode5.create(node, IdentifierNode4.create(alias)) : AliasNode5.create(node, IdentifierNode4.create(fallbackName));
5862
- }
5863
5929
  processTableRef(node) {
5864
5930
  if (!node) {
5865
5931
  return node;
@@ -5900,62 +5966,44 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
5900
5966
  ...this.fieldToColumnMap.keys()
5901
5967
  ].some((key) => key.startsWith(modelName + "."));
5902
5968
  }
5903
- createScopesFromFroms(node, namesMapped) {
5904
- if (!node) {
5905
- return [];
5906
- }
5907
- return node.froms.map((from) => {
5908
- const { alias, node: innerNode } = stripAlias(from);
5909
- if (innerNode && TableNode4.is(innerNode)) {
5910
- return {
5911
- model: innerNode.table.identifier.name,
5912
- alias,
5913
- namesMapped
5914
- };
5915
- } else {
5916
- return void 0;
5917
- }
5918
- }).filter((s) => !!s);
5919
- }
5920
5969
  // convert a "from" node to a nested query if there are columns with name mapping
5921
- processFrom(node) {
5922
- return {
5923
- ...super.transformFrom(node),
5924
- froms: node.froms.map((from) => {
5925
- const { alias, node: innerNode } = stripAlias(from);
5926
- if (!innerNode) {
5927
- return super.transformNode(from);
5928
- }
5929
- if (TableNode4.is(innerNode)) {
5930
- if (this.hasMappedColumns(innerNode.table.identifier.name)) {
5931
- const selectAll = this.createSelectAll(innerNode.table.identifier.name);
5932
- return this.ensureAlias(selectAll, alias, innerNode.table.identifier.name);
5933
- }
5970
+ processSelectTable(node) {
5971
+ const { alias, node: innerNode } = stripAlias(node);
5972
+ if (innerNode && TableNode4.is(innerNode)) {
5973
+ const modelName = innerNode.table.identifier.name;
5974
+ const mappedName = this.mapTableName(modelName);
5975
+ const finalAlias = alias ?? (mappedName !== modelName ? modelName : void 0);
5976
+ return {
5977
+ node: this.wrapAlias(TableNode4.create(mappedName), finalAlias),
5978
+ scope: {
5979
+ alias: alias ?? modelName,
5980
+ model: modelName,
5981
+ namesMapped: !this.hasMappedColumns(modelName)
5934
5982
  }
5935
- return this.transformNode(from);
5936
- })
5937
- };
5983
+ };
5984
+ } else {
5985
+ return {
5986
+ node: super.transformNode(node),
5987
+ scope: {
5988
+ alias,
5989
+ model: void 0,
5990
+ namesMapped: true
5991
+ }
5992
+ };
5993
+ }
5938
5994
  }
5939
- // create a `SelectQueryNode` for the given model with all columns mapped
5940
- createSelectAll(model) {
5995
+ createSelectAllFields(model, alias) {
5941
5996
  const modelDef = requireModel(this.schema, model);
5942
- const tableName = this.mapTableName(model);
5943
- return {
5944
- kind: "SelectQueryNode",
5945
- from: FromNode3.create([
5946
- TableNode4.create(tableName)
5947
- ]),
5948
- selections: this.getModelFields(modelDef).map((fieldDef) => {
5949
- const columnName = this.mapFieldName(model, fieldDef.name);
5950
- const columnRef = ReferenceNode3.create(ColumnNode3.create(columnName), TableNode4.create(tableName));
5951
- if (columnName !== fieldDef.name) {
5952
- const aliased = AliasNode5.create(columnRef, IdentifierNode4.create(fieldDef.name));
5953
- return SelectionNode3.create(aliased);
5954
- } else {
5955
- return SelectionNode3.create(columnRef);
5956
- }
5957
- })
5958
- };
5997
+ return this.getModelFields(modelDef).map((fieldDef) => {
5998
+ const columnName = this.mapFieldName(model, fieldDef.name);
5999
+ const columnRef = ReferenceNode3.create(ColumnNode3.create(columnName), alias ? TableNode4.create(alias) : void 0);
6000
+ if (columnName !== fieldDef.name) {
6001
+ const aliased = AliasNode5.create(columnRef, IdentifierNode4.create(fieldDef.name));
6002
+ return SelectionNode3.create(aliased);
6003
+ } else {
6004
+ return SelectionNode3.create(columnRef);
6005
+ }
6006
+ });
5959
6007
  }
5960
6008
  getModelFields(modelDef) {
5961
6009
  return Object.values(modelDef.fields).filter((f) => !f.relation && !f.computed && !f.originModel);
@@ -5985,18 +6033,22 @@ var QueryNameMapper = class extends OperationNodeTransformer2 {
5985
6033
  return this.wrapAlias(result, alias);
5986
6034
  }
5987
6035
  processSelectAll(node) {
5988
- const scope = this.modelScopes[this.modelScopes.length - 1];
6036
+ const scope = this.scopes[this.scopes.length - 1];
5989
6037
  invariant10(scope);
5990
- if (!this.hasMappedColumns(scope.model)) {
6038
+ if (!scope.model || !this.hasMappedColumns(scope.model)) {
5991
6039
  return super.transformSelectAll(node);
5992
6040
  }
5993
6041
  const modelDef = requireModel(this.schema, scope.model);
5994
6042
  return this.getModelFields(modelDef).map((fieldDef) => {
5995
- const columnName = this.mapFieldName(scope.model, fieldDef.name);
6043
+ const columnName = this.mapFieldName(modelDef.name, fieldDef.name);
5996
6044
  const columnRef = ReferenceNode3.create(ColumnNode3.create(columnName));
5997
6045
  return columnName !== fieldDef.name ? this.wrapAlias(columnRef, fieldDef.name) : columnRef;
5998
6046
  });
5999
6047
  }
6048
+ extractModelName(node) {
6049
+ const { node: innerNode } = stripAlias(node);
6050
+ return TableNode4.is(innerNode) ? innerNode.table.identifier.name : void 0;
6051
+ }
6000
6052
  extractFieldName(node) {
6001
6053
  if (ReferenceNode3.is(node) && ColumnNode3.is(node.column)) {
6002
6054
  return node.column.column.name;
@@ -6496,7 +6548,7 @@ var SchemaDbPusher = class {
6496
6548
  return toposort(graph).reverse().filter((m) => !!m);
6497
6549
  }
6498
6550
  createModelTable(kysely, modelDef) {
6499
- let table = kysely.schema.createTable(modelDef.name).ifNotExists();
6551
+ let table = kysely.schema.createTable(this.getTableName(modelDef)).ifNotExists();
6500
6552
  for (const [fieldName, fieldDef] of Object.entries(modelDef.fields)) {
6501
6553
  if (fieldDef.originModel && !fieldDef.id) {
6502
6554
  continue;
@@ -6515,6 +6567,26 @@ var SchemaDbPusher = class {
6515
6567
  table = this.addUniqueConstraint(table, modelDef);
6516
6568
  return table;
6517
6569
  }
6570
+ getTableName(modelDef) {
6571
+ const mapAttr = modelDef.attributes?.find((a) => a.name === "@@map");
6572
+ if (mapAttr && mapAttr.args?.[0]) {
6573
+ const mappedName = ExpressionUtils.getLiteralValue(mapAttr.args[0].value);
6574
+ if (mappedName) {
6575
+ return mappedName;
6576
+ }
6577
+ }
6578
+ return modelDef.name;
6579
+ }
6580
+ getColumnName(fieldDef) {
6581
+ const mapAttr = fieldDef.attributes?.find((a) => a.name === "@map");
6582
+ if (mapAttr && mapAttr.args?.[0]) {
6583
+ const mappedName = ExpressionUtils.getLiteralValue(mapAttr.args[0].value);
6584
+ if (mappedName) {
6585
+ return mappedName;
6586
+ }
6587
+ }
6588
+ return fieldDef.name;
6589
+ }
6518
6590
  isComputedField(fieldDef) {
6519
6591
  return fieldDef.attributes?.some((a) => a.name === "@computed");
6520
6592
  }
@@ -6525,7 +6597,7 @@ var SchemaDbPusher = class {
6525
6597
  }
6526
6598
  }
6527
6599
  if (modelDef.idFields.length > 0) {
6528
- table = table.addPrimaryKeyConstraint(`pk_${modelDef.name}`, modelDef.idFields);
6600
+ table = table.addPrimaryKeyConstraint(`pk_${modelDef.name}`, modelDef.idFields.map((f) => this.getColumnName(modelDef.fields[f])));
6529
6601
  }
6530
6602
  return table;
6531
6603
  }
@@ -6538,16 +6610,16 @@ var SchemaDbPusher = class {
6538
6610
  continue;
6539
6611
  }
6540
6612
  table = table.addUniqueConstraint(`unique_${modelDef.name}_${key}`, [
6541
- key
6613
+ this.getColumnName(fieldDef)
6542
6614
  ]);
6543
6615
  } else {
6544
- table = table.addUniqueConstraint(`unique_${modelDef.name}_${key}`, Object.keys(value));
6616
+ table = table.addUniqueConstraint(`unique_${modelDef.name}_${key}`, Object.keys(value).map((f) => this.getColumnName(modelDef.fields[f])));
6545
6617
  }
6546
6618
  }
6547
6619
  return table;
6548
6620
  }
6549
6621
  createModelField(table, fieldDef, modelDef) {
6550
- return table.addColumn(fieldDef.name, this.mapFieldType(fieldDef), (col) => {
6622
+ return table.addColumn(this.getColumnName(fieldDef), this.mapFieldType(fieldDef), (col) => {
6551
6623
  if (fieldDef.id && modelDef.idFields.length === 1) {
6552
6624
  col = col.primaryKey();
6553
6625
  }
@@ -6603,7 +6675,9 @@ var SchemaDbPusher = class {
6603
6675
  if (!fieldDef.relation.fields || !fieldDef.relation.references) {
6604
6676
  return table;
6605
6677
  }
6606
- table = table.addForeignKeyConstraint(`fk_${model}_${fieldName}`, fieldDef.relation.fields, fieldDef.type, fieldDef.relation.references, (cb) => {
6678
+ const modelDef = requireModel(this.schema, model);
6679
+ const relationModelDef = requireModel(this.schema, fieldDef.type);
6680
+ table = table.addForeignKeyConstraint(`fk_${model}_${fieldName}`, fieldDef.relation.fields.map((f) => this.getColumnName(modelDef.fields[f])), this.getTableName(relationModelDef), fieldDef.relation.references.map((f) => this.getColumnName(relationModelDef.fields[f])), (cb) => {
6607
6681
  if (fieldDef.relation?.onDelete) {
6608
6682
  cb = cb.onDelete(this.mapCascadeAction(fieldDef.relation.onDelete));
6609
6683
  }