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/generator.cjs
CHANGED
|
@@ -2323,7 +2323,7 @@ var require_package = __commonJS({
|
|
|
2323
2323
|
"package.json"(exports$1, module) {
|
|
2324
2324
|
module.exports = {
|
|
2325
2325
|
name: "prisma-sql",
|
|
2326
|
-
version: "1.
|
|
2326
|
+
version: "1.75.0",
|
|
2327
2327
|
description: "Convert Prisma queries to optimized SQL with type safety. 2-7x faster than Prisma Client.",
|
|
2328
2328
|
main: "dist/index.cjs",
|
|
2329
2329
|
module: "dist/index.js",
|
|
@@ -3536,7 +3536,7 @@ var getNextSort = (sortRaw) => {
|
|
|
3536
3536
|
if (s === "desc") return "asc";
|
|
3537
3537
|
return sortRaw;
|
|
3538
3538
|
};
|
|
3539
|
-
var
|
|
3539
|
+
var flipScalarSortObject = (obj) => {
|
|
3540
3540
|
const out = __spreadValues({}, obj);
|
|
3541
3541
|
const hasSort = Object.prototype.hasOwnProperty.call(obj, "sort");
|
|
3542
3542
|
const hasDirection = Object.prototype.hasOwnProperty.call(obj, "direction");
|
|
@@ -3552,26 +3552,64 @@ var flipObjectSort = (obj) => {
|
|
|
3552
3552
|
}
|
|
3553
3553
|
return out;
|
|
3554
3554
|
};
|
|
3555
|
+
function isScalarSortConfig(obj) {
|
|
3556
|
+
return Object.prototype.hasOwnProperty.call(obj, "sort") || Object.prototype.hasOwnProperty.call(obj, "direction");
|
|
3557
|
+
}
|
|
3558
|
+
function flipRelationOrderByValue(obj) {
|
|
3559
|
+
const out = {};
|
|
3560
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
3561
|
+
out[k] = flipValue(v);
|
|
3562
|
+
}
|
|
3563
|
+
return out;
|
|
3564
|
+
}
|
|
3555
3565
|
var flipValue = (v) => {
|
|
3556
3566
|
if (typeof v === "string") return flipSortString(v);
|
|
3557
|
-
if (isPlainObject(v))
|
|
3567
|
+
if (isPlainObject(v)) {
|
|
3568
|
+
if (isScalarSortConfig(v)) return flipScalarSortObject(v);
|
|
3569
|
+
return flipRelationOrderByValue(v);
|
|
3570
|
+
}
|
|
3558
3571
|
return v;
|
|
3559
3572
|
};
|
|
3560
|
-
var
|
|
3573
|
+
var expandToSingleFieldEntries = (item) => {
|
|
3561
3574
|
if (!isPlainObject(item)) {
|
|
3562
3575
|
throw new Error("orderBy array entries must be objects");
|
|
3563
3576
|
}
|
|
3564
3577
|
const entries = Object.entries(item);
|
|
3565
|
-
if (entries.length
|
|
3566
|
-
throw new Error("orderBy array entries must have
|
|
3578
|
+
if (entries.length === 0) {
|
|
3579
|
+
throw new Error("orderBy array entries must have at least one field");
|
|
3567
3580
|
}
|
|
3568
|
-
return entries
|
|
3581
|
+
return entries;
|
|
3569
3582
|
};
|
|
3583
|
+
function expandOrderByInput(orderBy) {
|
|
3584
|
+
if (!isNotNullish(orderBy)) return [];
|
|
3585
|
+
if (Array.isArray(orderBy)) {
|
|
3586
|
+
const result = [];
|
|
3587
|
+
for (const item of orderBy) {
|
|
3588
|
+
result.push(...expandToSingleFieldEntries(item));
|
|
3589
|
+
}
|
|
3590
|
+
return result;
|
|
3591
|
+
}
|
|
3592
|
+
if (isPlainObject(orderBy)) {
|
|
3593
|
+
return Object.entries(orderBy);
|
|
3594
|
+
}
|
|
3595
|
+
throw new Error("orderBy must be an object or array of objects");
|
|
3596
|
+
}
|
|
3597
|
+
function isScalarOrderByValue(v) {
|
|
3598
|
+
if (typeof v === "string") {
|
|
3599
|
+
const lower = v.toLowerCase();
|
|
3600
|
+
return lower === "asc" || lower === "desc";
|
|
3601
|
+
}
|
|
3602
|
+
if (isPlainObject(v) && isScalarSortConfig(v)) return true;
|
|
3603
|
+
return false;
|
|
3604
|
+
}
|
|
3570
3605
|
var flipOrderByArray = (orderBy) => {
|
|
3571
|
-
|
|
3572
|
-
|
|
3573
|
-
|
|
3574
|
-
|
|
3606
|
+
const result = [];
|
|
3607
|
+
for (const item of orderBy) {
|
|
3608
|
+
for (const [k, v] of expandToSingleFieldEntries(item)) {
|
|
3609
|
+
result.push({ [k]: flipValue(v) });
|
|
3610
|
+
}
|
|
3611
|
+
}
|
|
3612
|
+
return result;
|
|
3575
3613
|
};
|
|
3576
3614
|
var flipOrderByObject = (orderBy) => {
|
|
3577
3615
|
const out = {};
|
|
@@ -3591,18 +3629,24 @@ function reverseOrderByInput(orderBy) {
|
|
|
3591
3629
|
throw new Error("orderBy must be an object or array of objects");
|
|
3592
3630
|
}
|
|
3593
3631
|
var normalizePairs = (pairs, parseValue) => {
|
|
3594
|
-
|
|
3632
|
+
const result = [];
|
|
3633
|
+
for (const [field, rawValue] of pairs) {
|
|
3634
|
+
if (!isScalarOrderByValue(rawValue)) continue;
|
|
3595
3635
|
const parsed = parseValue(rawValue, field);
|
|
3596
|
-
|
|
3636
|
+
result.push({
|
|
3597
3637
|
[field]: parsed.nulls !== void 0 ? { direction: parsed.direction, nulls: parsed.nulls } : parsed.direction
|
|
3598
|
-
};
|
|
3599
|
-
}
|
|
3638
|
+
});
|
|
3639
|
+
}
|
|
3640
|
+
return result;
|
|
3600
3641
|
};
|
|
3601
3642
|
function normalizeOrderByInput(orderBy, parseValue) {
|
|
3602
3643
|
if (!isNotNullish(orderBy)) return [];
|
|
3603
3644
|
if (Array.isArray(orderBy)) {
|
|
3604
|
-
const
|
|
3605
|
-
|
|
3645
|
+
const allPairs = [];
|
|
3646
|
+
for (const item of orderBy) {
|
|
3647
|
+
allPairs.push(...expandToSingleFieldEntries(item));
|
|
3648
|
+
}
|
|
3649
|
+
return normalizePairs(allPairs, parseValue);
|
|
3606
3650
|
}
|
|
3607
3651
|
if (isPlainObject(orderBy)) {
|
|
3608
3652
|
return normalizePairs(Object.entries(orderBy), parseValue);
|
|
@@ -3614,9 +3658,11 @@ function normalizeAndValidateOrderBy(orderBy, model, parseValue) {
|
|
|
3614
3658
|
const normalized = normalizeOrderByInput(orderBy, parseValue);
|
|
3615
3659
|
const entries = [];
|
|
3616
3660
|
const scalarSet = getScalarFieldSet(model);
|
|
3661
|
+
const relationSet = getRelationFieldSet(model);
|
|
3617
3662
|
for (const item of normalized) {
|
|
3618
3663
|
const [[field, value]] = Object.entries(item);
|
|
3619
3664
|
if (!scalarSet.has(field)) {
|
|
3665
|
+
if (relationSet.has(field)) continue;
|
|
3620
3666
|
throw new Error(
|
|
3621
3667
|
`orderBy field '${field}' not found on model ${model.name}`
|
|
3622
3668
|
);
|
|
@@ -4075,16 +4121,6 @@ function buildOrderBy(orderBy, alias, dialect, model) {
|
|
|
4075
4121
|
const d = dialect != null ? dialect : getGlobalDialect();
|
|
4076
4122
|
return buildOrderByFragment(entries, alias, d, model);
|
|
4077
4123
|
}
|
|
4078
|
-
function buildOrderByClause(args, alias, dialect, model) {
|
|
4079
|
-
if (!isNotNullish(args.orderBy)) return "";
|
|
4080
|
-
const result = buildOrderBy(args.orderBy, alias, dialect, model);
|
|
4081
|
-
if (!isNonEmptyString(result)) {
|
|
4082
|
-
throw new Error(
|
|
4083
|
-
"buildOrderByClause: orderBy specified but produced empty result"
|
|
4084
|
-
);
|
|
4085
|
-
}
|
|
4086
|
-
return result;
|
|
4087
|
-
}
|
|
4088
4124
|
function normalizeTakeLike(v) {
|
|
4089
4125
|
const n = normalizeIntLike("take", v, {
|
|
4090
4126
|
min: Number.MIN_SAFE_INTEGER,
|
|
@@ -7859,6 +7895,114 @@ function buildIncludeSql(args, model, schemas, parentAlias, params, dialect, out
|
|
|
7859
7895
|
});
|
|
7860
7896
|
}
|
|
7861
7897
|
|
|
7898
|
+
// src/builder/shared/order-by-relation.ts
|
|
7899
|
+
function resolveTableRef(model, dialect) {
|
|
7900
|
+
const tableName = model.tableName || model.dbName || model.name;
|
|
7901
|
+
if (dialect === "sqlite") {
|
|
7902
|
+
return quote(tableName);
|
|
7903
|
+
}
|
|
7904
|
+
const schema = model.schema || model.schemaName || "public";
|
|
7905
|
+
return buildTableReference(schema, tableName, dialect);
|
|
7906
|
+
}
|
|
7907
|
+
function findRelationField(model, fieldName) {
|
|
7908
|
+
return model.fields.find((f) => f.name === fieldName && f.isRelation);
|
|
7909
|
+
}
|
|
7910
|
+
function buildOrderByWithRelations(orderBy, alias, dialect, model, schemas) {
|
|
7911
|
+
if (!isNotNullish(orderBy)) return { sql: "", joins: [] };
|
|
7912
|
+
const expanded = expandOrderByInput(orderBy);
|
|
7913
|
+
if (expanded.length === 0) return { sql: "", joins: [] };
|
|
7914
|
+
const relationSet = getRelationFieldSet(model);
|
|
7915
|
+
const scalarSet = getScalarFieldSet(model);
|
|
7916
|
+
const orderFragments = [];
|
|
7917
|
+
const joins = [];
|
|
7918
|
+
const usedAliases = /* @__PURE__ */ new Set();
|
|
7919
|
+
let relAliasCounter = 0;
|
|
7920
|
+
for (const [fieldName, value] of expanded) {
|
|
7921
|
+
if (scalarSet.has(fieldName)) {
|
|
7922
|
+
const entries = normalizeAndValidateOrderBy(
|
|
7923
|
+
[{ [fieldName]: value }],
|
|
7924
|
+
model,
|
|
7925
|
+
parseOrderByValue
|
|
7926
|
+
);
|
|
7927
|
+
const sql = buildOrderByFragment(entries, alias, dialect, model);
|
|
7928
|
+
if (sql) orderFragments.push(sql);
|
|
7929
|
+
continue;
|
|
7930
|
+
}
|
|
7931
|
+
if (relationSet.has(fieldName)) {
|
|
7932
|
+
if (!isPlainObject(value)) {
|
|
7933
|
+
throw new Error(`Relation orderBy for '${fieldName}' must be an object`);
|
|
7934
|
+
}
|
|
7935
|
+
const nestedEntries = Object.entries(value);
|
|
7936
|
+
if (nestedEntries.length === 0) continue;
|
|
7937
|
+
if ("_count" in value) {
|
|
7938
|
+
throw new Error(
|
|
7939
|
+
`Relation orderBy with _count on '${fieldName}' is not yet supported by prisma-sql`
|
|
7940
|
+
);
|
|
7941
|
+
}
|
|
7942
|
+
const field = findRelationField(model, fieldName);
|
|
7943
|
+
if (!field) {
|
|
7944
|
+
throw new Error(
|
|
7945
|
+
`Relation field '${fieldName}' not found on model ${model.name}`
|
|
7946
|
+
);
|
|
7947
|
+
}
|
|
7948
|
+
const relatedModel = getModelByName(schemas, field.relatedModel);
|
|
7949
|
+
if (!relatedModel) {
|
|
7950
|
+
throw new Error(
|
|
7951
|
+
`Related model '${field.relatedModel}' not found for relation '${fieldName}'`
|
|
7952
|
+
);
|
|
7953
|
+
}
|
|
7954
|
+
const relScalarSet = getScalarFieldSet(relatedModel);
|
|
7955
|
+
const relRelationSet = getRelationFieldSet(relatedModel);
|
|
7956
|
+
for (const [nestedField] of nestedEntries) {
|
|
7957
|
+
if (relRelationSet.has(nestedField)) {
|
|
7958
|
+
throw new Error(
|
|
7959
|
+
`Nested relation orderBy (${fieldName}.${nestedField}) is not yet supported by prisma-sql`
|
|
7960
|
+
);
|
|
7961
|
+
}
|
|
7962
|
+
if (!relScalarSet.has(nestedField)) {
|
|
7963
|
+
throw new Error(
|
|
7964
|
+
`orderBy field '${nestedField}' does not exist on related model '${relatedModel.name}'`
|
|
7965
|
+
);
|
|
7966
|
+
}
|
|
7967
|
+
}
|
|
7968
|
+
let joinAlias;
|
|
7969
|
+
do {
|
|
7970
|
+
joinAlias = `ob_${relAliasCounter++}`;
|
|
7971
|
+
} while (usedAliases.has(joinAlias));
|
|
7972
|
+
usedAliases.add(joinAlias);
|
|
7973
|
+
const tableRef = resolveTableRef(relatedModel, dialect);
|
|
7974
|
+
const cond = joinCondition(
|
|
7975
|
+
field,
|
|
7976
|
+
model,
|
|
7977
|
+
relatedModel,
|
|
7978
|
+
alias,
|
|
7979
|
+
joinAlias
|
|
7980
|
+
);
|
|
7981
|
+
joins.push(`LEFT JOIN ${tableRef} ${joinAlias} ON ${cond}`);
|
|
7982
|
+
const entries = normalizeAndValidateOrderBy(
|
|
7983
|
+
[value],
|
|
7984
|
+
relatedModel,
|
|
7985
|
+
parseOrderByValue
|
|
7986
|
+
);
|
|
7987
|
+
const sql = buildOrderByFragment(
|
|
7988
|
+
entries,
|
|
7989
|
+
joinAlias,
|
|
7990
|
+
dialect,
|
|
7991
|
+
relatedModel
|
|
7992
|
+
);
|
|
7993
|
+
if (sql) orderFragments.push(sql);
|
|
7994
|
+
continue;
|
|
7995
|
+
}
|
|
7996
|
+
throw new Error(
|
|
7997
|
+
`orderBy field '${fieldName}' does not exist on model ${model.name}`
|
|
7998
|
+
);
|
|
7999
|
+
}
|
|
8000
|
+
return {
|
|
8001
|
+
sql: orderFragments.join(SQL_SEPARATORS.ORDER_BY),
|
|
8002
|
+
joins
|
|
8003
|
+
};
|
|
8004
|
+
}
|
|
8005
|
+
|
|
7862
8006
|
// src/builder/select.ts
|
|
7863
8007
|
function normalizeOrderByInput3(orderBy) {
|
|
7864
8008
|
return normalizeOrderByInput(orderBy, parseOrderByValue);
|
|
@@ -7938,20 +8082,13 @@ Available fields: ${[...scalarSet].join(", ")}`
|
|
|
7938
8082
|
assertScalarField(model, f, "distinct");
|
|
7939
8083
|
}
|
|
7940
8084
|
}
|
|
7941
|
-
function validateOrderBy(model, orderBy) {
|
|
8085
|
+
function validateOrderBy(model, orderBy, schemas) {
|
|
7942
8086
|
if (!isNotNullish(orderBy)) return;
|
|
7943
|
-
const
|
|
7944
|
-
if (
|
|
8087
|
+
const expanded = expandOrderByInput(orderBy);
|
|
8088
|
+
if (expanded.length === 0) return;
|
|
7945
8089
|
const scalarSet = getScalarFieldSet(model);
|
|
7946
8090
|
const relationSet = getRelationFieldSet(model);
|
|
7947
|
-
for (const
|
|
7948
|
-
const entries = Object.entries(it);
|
|
7949
|
-
if (entries.length !== 1) {
|
|
7950
|
-
throw new Error(
|
|
7951
|
-
`orderBy array entries must have exactly one field. Got ${entries.length} fields: ${Object.keys(it).join(", ")}`
|
|
7952
|
-
);
|
|
7953
|
-
}
|
|
7954
|
-
const [fieldName, value] = entries[0];
|
|
8091
|
+
for (const [fieldName, value] of expanded) {
|
|
7955
8092
|
const f = String(fieldName).trim();
|
|
7956
8093
|
if (f.length === 0) {
|
|
7957
8094
|
throw new Error("orderBy field name cannot be empty");
|
|
@@ -7961,20 +8098,21 @@ function validateOrderBy(model, orderBy) {
|
|
|
7961
8098
|
`orderBy field name too long (${f.length} chars, max 255): ${f.slice(0, 50)}...`
|
|
7962
8099
|
);
|
|
7963
8100
|
}
|
|
7964
|
-
if (
|
|
7965
|
-
|
|
7966
|
-
|
|
7967
|
-
|
|
7968
|
-
|
|
7969
|
-
|
|
8101
|
+
if (scalarSet.has(f)) {
|
|
8102
|
+
assertScalarField(model, f, "orderBy");
|
|
8103
|
+
parseOrderByValue(value, f);
|
|
8104
|
+
continue;
|
|
8105
|
+
}
|
|
8106
|
+
if (relationSet.has(f)) {
|
|
8107
|
+
if (!isPlainObject(value)) {
|
|
8108
|
+
throw new Error(`Relation orderBy for '${f}' must be an object`);
|
|
7970
8109
|
}
|
|
7971
|
-
|
|
7972
|
-
`orderBy field '${f}' does not exist on model ${model.name}.
|
|
7973
|
-
Available fields: ${[...scalarSet].join(", ")}`
|
|
7974
|
-
);
|
|
8110
|
+
continue;
|
|
7975
8111
|
}
|
|
7976
|
-
|
|
7977
|
-
|
|
8112
|
+
throw new Error(
|
|
8113
|
+
`orderBy field '${f}' does not exist on model ${model.name}.
|
|
8114
|
+
Available fields: ${[...scalarSet].join(", ")}`
|
|
8115
|
+
);
|
|
7978
8116
|
}
|
|
7979
8117
|
}
|
|
7980
8118
|
function validateCursor(model, cursor, distinct) {
|
|
@@ -8057,11 +8195,12 @@ function buildSelectSpec(input) {
|
|
|
8057
8195
|
model,
|
|
8058
8196
|
alias
|
|
8059
8197
|
);
|
|
8060
|
-
const
|
|
8061
|
-
normalizedArgs,
|
|
8198
|
+
const orderByResult = buildOrderByWithRelations(
|
|
8199
|
+
normalizedArgs.orderBy,
|
|
8062
8200
|
alias,
|
|
8063
8201
|
dialect,
|
|
8064
|
-
model
|
|
8202
|
+
model,
|
|
8203
|
+
schemas
|
|
8065
8204
|
);
|
|
8066
8205
|
const { take, skip, cursor } = getPaginationParams(method, normalizedArgs);
|
|
8067
8206
|
const params = createParamStoreFrom(
|
|
@@ -8094,13 +8233,15 @@ function buildSelectSpec(input) {
|
|
|
8094
8233
|
"Cursor pagination with distinct is not supported in SQLite due to window function limitations. Use findMany with skip/take instead, or remove distinct."
|
|
8095
8234
|
);
|
|
8096
8235
|
}
|
|
8236
|
+
const orderByJoins = orderByResult.joins;
|
|
8237
|
+
const combinedWhereJoins = whereResult.joins ? [...whereResult.joins, ...orderByJoins] : orderByJoins.length > 0 ? orderByJoins : [];
|
|
8097
8238
|
return {
|
|
8098
8239
|
select: selectFields,
|
|
8099
8240
|
includes,
|
|
8100
8241
|
from: { table: tableName, alias },
|
|
8101
8242
|
whereClause: whereResult.clause,
|
|
8102
|
-
whereJoins:
|
|
8103
|
-
orderBy:
|
|
8243
|
+
whereJoins: combinedWhereJoins,
|
|
8244
|
+
orderBy: orderByResult.sql,
|
|
8104
8245
|
pagination: { take, skip },
|
|
8105
8246
|
distinct: normalizedArgs.distinct,
|
|
8106
8247
|
method,
|