prisma-sql 1.74.0 → 1.75.0
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/generator.cjs +196 -55
- package/dist/generator.cjs.map +1 -1
- package/dist/generator.js +196 -55
- package/dist/generator.js.map +1 -1
- package/dist/index.cjs +195 -54
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +195 -54
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1228,7 +1228,7 @@ var getNextSort = (sortRaw) => {
|
|
|
1228
1228
|
if (s === "desc") return "asc";
|
|
1229
1229
|
return sortRaw;
|
|
1230
1230
|
};
|
|
1231
|
-
var
|
|
1231
|
+
var flipScalarSortObject = (obj) => {
|
|
1232
1232
|
const out = __spreadValues({}, obj);
|
|
1233
1233
|
const hasSort = Object.prototype.hasOwnProperty.call(obj, "sort");
|
|
1234
1234
|
const hasDirection = Object.prototype.hasOwnProperty.call(obj, "direction");
|
|
@@ -1244,26 +1244,64 @@ var flipObjectSort = (obj) => {
|
|
|
1244
1244
|
}
|
|
1245
1245
|
return out;
|
|
1246
1246
|
};
|
|
1247
|
+
function isScalarSortConfig(obj) {
|
|
1248
|
+
return Object.prototype.hasOwnProperty.call(obj, "sort") || Object.prototype.hasOwnProperty.call(obj, "direction");
|
|
1249
|
+
}
|
|
1250
|
+
function flipRelationOrderByValue(obj) {
|
|
1251
|
+
const out = {};
|
|
1252
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
1253
|
+
out[k] = flipValue(v);
|
|
1254
|
+
}
|
|
1255
|
+
return out;
|
|
1256
|
+
}
|
|
1247
1257
|
var flipValue = (v) => {
|
|
1248
1258
|
if (typeof v === "string") return flipSortString(v);
|
|
1249
|
-
if (isPlainObject(v))
|
|
1259
|
+
if (isPlainObject(v)) {
|
|
1260
|
+
if (isScalarSortConfig(v)) return flipScalarSortObject(v);
|
|
1261
|
+
return flipRelationOrderByValue(v);
|
|
1262
|
+
}
|
|
1250
1263
|
return v;
|
|
1251
1264
|
};
|
|
1252
|
-
var
|
|
1265
|
+
var expandToSingleFieldEntries = (item) => {
|
|
1253
1266
|
if (!isPlainObject(item)) {
|
|
1254
1267
|
throw new Error("orderBy array entries must be objects");
|
|
1255
1268
|
}
|
|
1256
1269
|
const entries = Object.entries(item);
|
|
1257
|
-
if (entries.length
|
|
1258
|
-
throw new Error("orderBy array entries must have
|
|
1270
|
+
if (entries.length === 0) {
|
|
1271
|
+
throw new Error("orderBy array entries must have at least one field");
|
|
1259
1272
|
}
|
|
1260
|
-
return entries
|
|
1273
|
+
return entries;
|
|
1261
1274
|
};
|
|
1275
|
+
function expandOrderByInput(orderBy) {
|
|
1276
|
+
if (!isNotNullish(orderBy)) return [];
|
|
1277
|
+
if (Array.isArray(orderBy)) {
|
|
1278
|
+
const result = [];
|
|
1279
|
+
for (const item of orderBy) {
|
|
1280
|
+
result.push(...expandToSingleFieldEntries(item));
|
|
1281
|
+
}
|
|
1282
|
+
return result;
|
|
1283
|
+
}
|
|
1284
|
+
if (isPlainObject(orderBy)) {
|
|
1285
|
+
return Object.entries(orderBy);
|
|
1286
|
+
}
|
|
1287
|
+
throw new Error("orderBy must be an object or array of objects");
|
|
1288
|
+
}
|
|
1289
|
+
function isScalarOrderByValue(v) {
|
|
1290
|
+
if (typeof v === "string") {
|
|
1291
|
+
const lower = v.toLowerCase();
|
|
1292
|
+
return lower === "asc" || lower === "desc";
|
|
1293
|
+
}
|
|
1294
|
+
if (isPlainObject(v) && isScalarSortConfig(v)) return true;
|
|
1295
|
+
return false;
|
|
1296
|
+
}
|
|
1262
1297
|
var flipOrderByArray = (orderBy) => {
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1298
|
+
const result = [];
|
|
1299
|
+
for (const item of orderBy) {
|
|
1300
|
+
for (const [k, v] of expandToSingleFieldEntries(item)) {
|
|
1301
|
+
result.push({ [k]: flipValue(v) });
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
return result;
|
|
1267
1305
|
};
|
|
1268
1306
|
var flipOrderByObject = (orderBy) => {
|
|
1269
1307
|
const out = {};
|
|
@@ -1283,18 +1321,24 @@ function reverseOrderByInput(orderBy) {
|
|
|
1283
1321
|
throw new Error("orderBy must be an object or array of objects");
|
|
1284
1322
|
}
|
|
1285
1323
|
var normalizePairs = (pairs, parseValue) => {
|
|
1286
|
-
|
|
1324
|
+
const result = [];
|
|
1325
|
+
for (const [field, rawValue] of pairs) {
|
|
1326
|
+
if (!isScalarOrderByValue(rawValue)) continue;
|
|
1287
1327
|
const parsed = parseValue(rawValue, field);
|
|
1288
|
-
|
|
1328
|
+
result.push({
|
|
1289
1329
|
[field]: parsed.nulls !== void 0 ? { direction: parsed.direction, nulls: parsed.nulls } : parsed.direction
|
|
1290
|
-
};
|
|
1291
|
-
}
|
|
1330
|
+
});
|
|
1331
|
+
}
|
|
1332
|
+
return result;
|
|
1292
1333
|
};
|
|
1293
1334
|
function normalizeOrderByInput(orderBy, parseValue) {
|
|
1294
1335
|
if (!isNotNullish(orderBy)) return [];
|
|
1295
1336
|
if (Array.isArray(orderBy)) {
|
|
1296
|
-
const
|
|
1297
|
-
|
|
1337
|
+
const allPairs = [];
|
|
1338
|
+
for (const item of orderBy) {
|
|
1339
|
+
allPairs.push(...expandToSingleFieldEntries(item));
|
|
1340
|
+
}
|
|
1341
|
+
return normalizePairs(allPairs, parseValue);
|
|
1298
1342
|
}
|
|
1299
1343
|
if (isPlainObject(orderBy)) {
|
|
1300
1344
|
return normalizePairs(Object.entries(orderBy), parseValue);
|
|
@@ -1306,9 +1350,11 @@ function normalizeAndValidateOrderBy(orderBy, model, parseValue) {
|
|
|
1306
1350
|
const normalized = normalizeOrderByInput(orderBy, parseValue);
|
|
1307
1351
|
const entries = [];
|
|
1308
1352
|
const scalarSet = getScalarFieldSet(model);
|
|
1353
|
+
const relationSet = getRelationFieldSet(model);
|
|
1309
1354
|
for (const item of normalized) {
|
|
1310
1355
|
const [[field, value]] = Object.entries(item);
|
|
1311
1356
|
if (!scalarSet.has(field)) {
|
|
1357
|
+
if (relationSet.has(field)) continue;
|
|
1312
1358
|
throw new Error(
|
|
1313
1359
|
`orderBy field '${field}' not found on model ${model.name}`
|
|
1314
1360
|
);
|
|
@@ -1767,16 +1813,6 @@ function buildOrderBy(orderBy, alias, dialect, model) {
|
|
|
1767
1813
|
const d = dialect != null ? dialect : getGlobalDialect();
|
|
1768
1814
|
return buildOrderByFragment(entries, alias, d, model);
|
|
1769
1815
|
}
|
|
1770
|
-
function buildOrderByClause(args, alias, dialect, model) {
|
|
1771
|
-
if (!isNotNullish(args.orderBy)) return "";
|
|
1772
|
-
const result = buildOrderBy(args.orderBy, alias, dialect, model);
|
|
1773
|
-
if (!isNonEmptyString(result)) {
|
|
1774
|
-
throw new Error(
|
|
1775
|
-
"buildOrderByClause: orderBy specified but produced empty result"
|
|
1776
|
-
);
|
|
1777
|
-
}
|
|
1778
|
-
return result;
|
|
1779
|
-
}
|
|
1780
1816
|
function normalizeTakeLike(v) {
|
|
1781
1817
|
const n = normalizeIntLike("take", v, {
|
|
1782
1818
|
min: Number.MIN_SAFE_INTEGER,
|
|
@@ -5571,6 +5607,114 @@ function buildIncludeSql(args, model, schemas, parentAlias, params, dialect, out
|
|
|
5571
5607
|
});
|
|
5572
5608
|
}
|
|
5573
5609
|
|
|
5610
|
+
// src/builder/shared/order-by-relation.ts
|
|
5611
|
+
function resolveTableRef(model, dialect) {
|
|
5612
|
+
const tableName = model.tableName || model.dbName || model.name;
|
|
5613
|
+
if (dialect === "sqlite") {
|
|
5614
|
+
return quote(tableName);
|
|
5615
|
+
}
|
|
5616
|
+
const schema = model.schema || model.schemaName || "public";
|
|
5617
|
+
return buildTableReference(schema, tableName, dialect);
|
|
5618
|
+
}
|
|
5619
|
+
function findRelationField(model, fieldName) {
|
|
5620
|
+
return model.fields.find((f) => f.name === fieldName && f.isRelation);
|
|
5621
|
+
}
|
|
5622
|
+
function buildOrderByWithRelations(orderBy, alias, dialect, model, schemas) {
|
|
5623
|
+
if (!isNotNullish(orderBy)) return { sql: "", joins: [] };
|
|
5624
|
+
const expanded = expandOrderByInput(orderBy);
|
|
5625
|
+
if (expanded.length === 0) return { sql: "", joins: [] };
|
|
5626
|
+
const relationSet = getRelationFieldSet(model);
|
|
5627
|
+
const scalarSet = getScalarFieldSet(model);
|
|
5628
|
+
const orderFragments = [];
|
|
5629
|
+
const joins = [];
|
|
5630
|
+
const usedAliases = /* @__PURE__ */ new Set();
|
|
5631
|
+
let relAliasCounter = 0;
|
|
5632
|
+
for (const [fieldName, value] of expanded) {
|
|
5633
|
+
if (scalarSet.has(fieldName)) {
|
|
5634
|
+
const entries = normalizeAndValidateOrderBy(
|
|
5635
|
+
[{ [fieldName]: value }],
|
|
5636
|
+
model,
|
|
5637
|
+
parseOrderByValue
|
|
5638
|
+
);
|
|
5639
|
+
const sql = buildOrderByFragment(entries, alias, dialect, model);
|
|
5640
|
+
if (sql) orderFragments.push(sql);
|
|
5641
|
+
continue;
|
|
5642
|
+
}
|
|
5643
|
+
if (relationSet.has(fieldName)) {
|
|
5644
|
+
if (!isPlainObject(value)) {
|
|
5645
|
+
throw new Error(`Relation orderBy for '${fieldName}' must be an object`);
|
|
5646
|
+
}
|
|
5647
|
+
const nestedEntries = Object.entries(value);
|
|
5648
|
+
if (nestedEntries.length === 0) continue;
|
|
5649
|
+
if ("_count" in value) {
|
|
5650
|
+
throw new Error(
|
|
5651
|
+
`Relation orderBy with _count on '${fieldName}' is not yet supported by prisma-sql`
|
|
5652
|
+
);
|
|
5653
|
+
}
|
|
5654
|
+
const field = findRelationField(model, fieldName);
|
|
5655
|
+
if (!field) {
|
|
5656
|
+
throw new Error(
|
|
5657
|
+
`Relation field '${fieldName}' not found on model ${model.name}`
|
|
5658
|
+
);
|
|
5659
|
+
}
|
|
5660
|
+
const relatedModel = getModelByName(schemas, field.relatedModel);
|
|
5661
|
+
if (!relatedModel) {
|
|
5662
|
+
throw new Error(
|
|
5663
|
+
`Related model '${field.relatedModel}' not found for relation '${fieldName}'`
|
|
5664
|
+
);
|
|
5665
|
+
}
|
|
5666
|
+
const relScalarSet = getScalarFieldSet(relatedModel);
|
|
5667
|
+
const relRelationSet = getRelationFieldSet(relatedModel);
|
|
5668
|
+
for (const [nestedField] of nestedEntries) {
|
|
5669
|
+
if (relRelationSet.has(nestedField)) {
|
|
5670
|
+
throw new Error(
|
|
5671
|
+
`Nested relation orderBy (${fieldName}.${nestedField}) is not yet supported by prisma-sql`
|
|
5672
|
+
);
|
|
5673
|
+
}
|
|
5674
|
+
if (!relScalarSet.has(nestedField)) {
|
|
5675
|
+
throw new Error(
|
|
5676
|
+
`orderBy field '${nestedField}' does not exist on related model '${relatedModel.name}'`
|
|
5677
|
+
);
|
|
5678
|
+
}
|
|
5679
|
+
}
|
|
5680
|
+
let joinAlias;
|
|
5681
|
+
do {
|
|
5682
|
+
joinAlias = `ob_${relAliasCounter++}`;
|
|
5683
|
+
} while (usedAliases.has(joinAlias));
|
|
5684
|
+
usedAliases.add(joinAlias);
|
|
5685
|
+
const tableRef = resolveTableRef(relatedModel, dialect);
|
|
5686
|
+
const cond = joinCondition(
|
|
5687
|
+
field,
|
|
5688
|
+
model,
|
|
5689
|
+
relatedModel,
|
|
5690
|
+
alias,
|
|
5691
|
+
joinAlias
|
|
5692
|
+
);
|
|
5693
|
+
joins.push(`LEFT JOIN ${tableRef} ${joinAlias} ON ${cond}`);
|
|
5694
|
+
const entries = normalizeAndValidateOrderBy(
|
|
5695
|
+
[value],
|
|
5696
|
+
relatedModel,
|
|
5697
|
+
parseOrderByValue
|
|
5698
|
+
);
|
|
5699
|
+
const sql = buildOrderByFragment(
|
|
5700
|
+
entries,
|
|
5701
|
+
joinAlias,
|
|
5702
|
+
dialect,
|
|
5703
|
+
relatedModel
|
|
5704
|
+
);
|
|
5705
|
+
if (sql) orderFragments.push(sql);
|
|
5706
|
+
continue;
|
|
5707
|
+
}
|
|
5708
|
+
throw new Error(
|
|
5709
|
+
`orderBy field '${fieldName}' does not exist on model ${model.name}`
|
|
5710
|
+
);
|
|
5711
|
+
}
|
|
5712
|
+
return {
|
|
5713
|
+
sql: orderFragments.join(SQL_SEPARATORS.ORDER_BY),
|
|
5714
|
+
joins
|
|
5715
|
+
};
|
|
5716
|
+
}
|
|
5717
|
+
|
|
5574
5718
|
// src/builder/select.ts
|
|
5575
5719
|
function normalizeOrderByInput3(orderBy) {
|
|
5576
5720
|
return normalizeOrderByInput(orderBy, parseOrderByValue);
|
|
@@ -5650,20 +5794,13 @@ Available fields: ${[...scalarSet].join(", ")}`
|
|
|
5650
5794
|
assertScalarField(model, f, "distinct");
|
|
5651
5795
|
}
|
|
5652
5796
|
}
|
|
5653
|
-
function validateOrderBy(model, orderBy) {
|
|
5797
|
+
function validateOrderBy(model, orderBy, schemas) {
|
|
5654
5798
|
if (!isNotNullish(orderBy)) return;
|
|
5655
|
-
const
|
|
5656
|
-
if (
|
|
5799
|
+
const expanded = expandOrderByInput(orderBy);
|
|
5800
|
+
if (expanded.length === 0) return;
|
|
5657
5801
|
const scalarSet = getScalarFieldSet(model);
|
|
5658
5802
|
const relationSet = getRelationFieldSet(model);
|
|
5659
|
-
for (const
|
|
5660
|
-
const entries = Object.entries(it);
|
|
5661
|
-
if (entries.length !== 1) {
|
|
5662
|
-
throw new Error(
|
|
5663
|
-
`orderBy array entries must have exactly one field. Got ${entries.length} fields: ${Object.keys(it).join(", ")}`
|
|
5664
|
-
);
|
|
5665
|
-
}
|
|
5666
|
-
const [fieldName, value] = entries[0];
|
|
5803
|
+
for (const [fieldName, value] of expanded) {
|
|
5667
5804
|
const f = String(fieldName).trim();
|
|
5668
5805
|
if (f.length === 0) {
|
|
5669
5806
|
throw new Error("orderBy field name cannot be empty");
|
|
@@ -5673,20 +5810,21 @@ function validateOrderBy(model, orderBy) {
|
|
|
5673
5810
|
`orderBy field name too long (${f.length} chars, max 255): ${f.slice(0, 50)}...`
|
|
5674
5811
|
);
|
|
5675
5812
|
}
|
|
5676
|
-
if (
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5813
|
+
if (scalarSet.has(f)) {
|
|
5814
|
+
assertScalarField(model, f, "orderBy");
|
|
5815
|
+
parseOrderByValue(value, f);
|
|
5816
|
+
continue;
|
|
5817
|
+
}
|
|
5818
|
+
if (relationSet.has(f)) {
|
|
5819
|
+
if (!isPlainObject(value)) {
|
|
5820
|
+
throw new Error(`Relation orderBy for '${f}' must be an object`);
|
|
5682
5821
|
}
|
|
5683
|
-
|
|
5684
|
-
`orderBy field '${f}' does not exist on model ${model.name}.
|
|
5685
|
-
Available fields: ${[...scalarSet].join(", ")}`
|
|
5686
|
-
);
|
|
5822
|
+
continue;
|
|
5687
5823
|
}
|
|
5688
|
-
|
|
5689
|
-
|
|
5824
|
+
throw new Error(
|
|
5825
|
+
`orderBy field '${f}' does not exist on model ${model.name}.
|
|
5826
|
+
Available fields: ${[...scalarSet].join(", ")}`
|
|
5827
|
+
);
|
|
5690
5828
|
}
|
|
5691
5829
|
}
|
|
5692
5830
|
function validateCursor(model, cursor, distinct) {
|
|
@@ -5769,11 +5907,12 @@ function buildSelectSpec(input) {
|
|
|
5769
5907
|
model,
|
|
5770
5908
|
alias
|
|
5771
5909
|
);
|
|
5772
|
-
const
|
|
5773
|
-
normalizedArgs,
|
|
5910
|
+
const orderByResult = buildOrderByWithRelations(
|
|
5911
|
+
normalizedArgs.orderBy,
|
|
5774
5912
|
alias,
|
|
5775
5913
|
dialect,
|
|
5776
|
-
model
|
|
5914
|
+
model,
|
|
5915
|
+
schemas
|
|
5777
5916
|
);
|
|
5778
5917
|
const { take, skip, cursor } = getPaginationParams(method, normalizedArgs);
|
|
5779
5918
|
const params = createParamStoreFrom(
|
|
@@ -5806,13 +5945,15 @@ function buildSelectSpec(input) {
|
|
|
5806
5945
|
"Cursor pagination with distinct is not supported in SQLite due to window function limitations. Use findMany with skip/take instead, or remove distinct."
|
|
5807
5946
|
);
|
|
5808
5947
|
}
|
|
5948
|
+
const orderByJoins = orderByResult.joins;
|
|
5949
|
+
const combinedWhereJoins = whereResult.joins ? [...whereResult.joins, ...orderByJoins] : orderByJoins.length > 0 ? orderByJoins : [];
|
|
5809
5950
|
return {
|
|
5810
5951
|
select: selectFields,
|
|
5811
5952
|
includes,
|
|
5812
5953
|
from: { table: tableName, alias },
|
|
5813
5954
|
whereClause: whereResult.clause,
|
|
5814
|
-
whereJoins:
|
|
5815
|
-
orderBy:
|
|
5955
|
+
whereJoins: combinedWhereJoins,
|
|
5956
|
+
orderBy: orderByResult.sql,
|
|
5816
5957
|
pagination: { take, skip },
|
|
5817
5958
|
distinct: normalizedArgs.distinct,
|
|
5818
5959
|
method,
|