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