prisma-sql 1.71.0 → 1.73.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 +293 -252
- package/dist/generator.cjs.map +1 -1
- package/dist/generator.js +293 -252
- package/dist/generator.js.map +1 -1
- package/dist/index.cjs +459 -389
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +459 -390
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
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.73.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",
|
|
@@ -2389,13 +2389,13 @@ var require_package = __commonJS({
|
|
|
2389
2389
|
license: "MIT",
|
|
2390
2390
|
dependencies: {
|
|
2391
2391
|
"@dee-wan/schema-parser": "1.4.0",
|
|
2392
|
-
"@prisma/generator-helper": "^
|
|
2393
|
-
"@prisma/internals": "^
|
|
2392
|
+
"@prisma/generator-helper": "^7.4.0",
|
|
2393
|
+
"@prisma/internals": "^7.4.0"
|
|
2394
2394
|
},
|
|
2395
2395
|
devDependencies: {
|
|
2396
2396
|
"@faker-js/faker": "^10.2.0",
|
|
2397
|
-
"@prisma/adapter-better-sqlite3": "^
|
|
2398
|
-
"@prisma/adapter-pg": "^
|
|
2397
|
+
"@prisma/adapter-better-sqlite3": "^7.4.0",
|
|
2398
|
+
"@prisma/adapter-pg": "^7.4.0",
|
|
2399
2399
|
"@semantic-release/changelog": "^6.0.3",
|
|
2400
2400
|
"@semantic-release/git": "^10.0.1",
|
|
2401
2401
|
"@types/better-sqlite3": "^7.6.13",
|
|
@@ -2409,8 +2409,8 @@ var require_package = __commonJS({
|
|
|
2409
2409
|
tsx: "^4.21.0",
|
|
2410
2410
|
typescript: "^5.9.3",
|
|
2411
2411
|
vitest: "^4.0.18",
|
|
2412
|
-
"@prisma/client": "
|
|
2413
|
-
prisma: "
|
|
2412
|
+
"@prisma/client": "7.4.0",
|
|
2413
|
+
prisma: "7.4.0"
|
|
2414
2414
|
},
|
|
2415
2415
|
engines: {
|
|
2416
2416
|
node: ">=16.0.0"
|
|
@@ -2418,6 +2418,241 @@ var require_package = __commonJS({
|
|
|
2418
2418
|
};
|
|
2419
2419
|
}
|
|
2420
2420
|
});
|
|
2421
|
+
var MAX_DEPTH = 20;
|
|
2422
|
+
function normalizeValue(value, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
|
|
2423
|
+
if (depth > MAX_DEPTH) {
|
|
2424
|
+
throw new Error(`Max normalization depth exceeded (${MAX_DEPTH} levels)`);
|
|
2425
|
+
}
|
|
2426
|
+
if (value instanceof Date) {
|
|
2427
|
+
return normalizeDateValue(value);
|
|
2428
|
+
}
|
|
2429
|
+
if (typeof value === "bigint") {
|
|
2430
|
+
return value.toString();
|
|
2431
|
+
}
|
|
2432
|
+
if (Array.isArray(value)) {
|
|
2433
|
+
return normalizeArrayValue(value, seen, depth);
|
|
2434
|
+
}
|
|
2435
|
+
if (value && typeof value === "object") {
|
|
2436
|
+
return normalizeObjectValue(value, seen, depth);
|
|
2437
|
+
}
|
|
2438
|
+
return value;
|
|
2439
|
+
}
|
|
2440
|
+
function normalizeDateValue(date) {
|
|
2441
|
+
const t = date.getTime();
|
|
2442
|
+
if (!Number.isFinite(t)) {
|
|
2443
|
+
throw new Error("Invalid Date value in SQL params");
|
|
2444
|
+
}
|
|
2445
|
+
return date.toISOString();
|
|
2446
|
+
}
|
|
2447
|
+
function normalizeArrayValue(value, seen, depth) {
|
|
2448
|
+
const arrRef = value;
|
|
2449
|
+
if (seen.has(arrRef)) {
|
|
2450
|
+
throw new Error("Circular reference in SQL params");
|
|
2451
|
+
}
|
|
2452
|
+
seen.add(arrRef);
|
|
2453
|
+
const out = value.map((v) => normalizeValue(v, seen, depth + 1));
|
|
2454
|
+
seen.delete(arrRef);
|
|
2455
|
+
return out;
|
|
2456
|
+
}
|
|
2457
|
+
function normalizeObjectValue(value, seen, depth) {
|
|
2458
|
+
if (value instanceof Uint8Array) return value;
|
|
2459
|
+
if (typeof Buffer !== "undefined" && Buffer.isBuffer(value)) return value;
|
|
2460
|
+
const proto = Object.getPrototypeOf(value);
|
|
2461
|
+
const isPlain = proto === Object.prototype || proto === null;
|
|
2462
|
+
if (!isPlain) return value;
|
|
2463
|
+
const obj = value;
|
|
2464
|
+
if (seen.has(obj)) {
|
|
2465
|
+
throw new Error("Circular reference in SQL params");
|
|
2466
|
+
}
|
|
2467
|
+
seen.add(obj);
|
|
2468
|
+
const out = {};
|
|
2469
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
2470
|
+
out[k] = normalizeValue(v, seen, depth + 1);
|
|
2471
|
+
}
|
|
2472
|
+
seen.delete(obj);
|
|
2473
|
+
return out;
|
|
2474
|
+
}
|
|
2475
|
+
|
|
2476
|
+
// src/sql-builder-dialect.ts
|
|
2477
|
+
var globalDialect = "postgres";
|
|
2478
|
+
function setGlobalDialect(dialect) {
|
|
2479
|
+
if (dialect !== "postgres" && dialect !== "sqlite") {
|
|
2480
|
+
throw new Error(
|
|
2481
|
+
`Invalid dialect: ${dialect}. Must be 'postgres' or 'sqlite'`
|
|
2482
|
+
);
|
|
2483
|
+
}
|
|
2484
|
+
globalDialect = dialect;
|
|
2485
|
+
}
|
|
2486
|
+
function getGlobalDialect() {
|
|
2487
|
+
return globalDialect;
|
|
2488
|
+
}
|
|
2489
|
+
function assertNonEmpty(value, name) {
|
|
2490
|
+
if (!value || value.trim().length === 0) {
|
|
2491
|
+
throw new Error(`${name} is required and cannot be empty`);
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2494
|
+
function arrayContains(column, value, arrayType, dialect) {
|
|
2495
|
+
assertNonEmpty(column, "arrayContains column");
|
|
2496
|
+
assertNonEmpty(value, "arrayContains value");
|
|
2497
|
+
if (dialect === "postgres") {
|
|
2498
|
+
return `${column} @> ARRAY[${value}]::${arrayType}`;
|
|
2499
|
+
}
|
|
2500
|
+
return `EXISTS (SELECT 1 FROM json_each(${column}) WHERE value = ${value})`;
|
|
2501
|
+
}
|
|
2502
|
+
function arrayOverlaps(column, value, arrayType, dialect) {
|
|
2503
|
+
assertNonEmpty(column, "arrayOverlaps column");
|
|
2504
|
+
assertNonEmpty(value, "arrayOverlaps value");
|
|
2505
|
+
if (dialect === "postgres") {
|
|
2506
|
+
return `${column} && ${value}::${arrayType}`;
|
|
2507
|
+
}
|
|
2508
|
+
return `EXISTS (
|
|
2509
|
+
SELECT 1 FROM json_each(${column}) AS col
|
|
2510
|
+
JOIN json_each(${value}) AS val
|
|
2511
|
+
WHERE col.value = val.value
|
|
2512
|
+
)`;
|
|
2513
|
+
}
|
|
2514
|
+
function arrayContainsAll(column, value, arrayType, dialect) {
|
|
2515
|
+
assertNonEmpty(column, "arrayContainsAll column");
|
|
2516
|
+
assertNonEmpty(value, "arrayContainsAll value");
|
|
2517
|
+
if (dialect === "postgres") {
|
|
2518
|
+
return `${column} @> ${value}::${arrayType}`;
|
|
2519
|
+
}
|
|
2520
|
+
return `NOT EXISTS (
|
|
2521
|
+
SELECT 1 FROM json_each(${value}) AS val
|
|
2522
|
+
WHERE NOT EXISTS (
|
|
2523
|
+
SELECT 1 FROM json_each(${column}) AS col
|
|
2524
|
+
WHERE col.value = val.value
|
|
2525
|
+
)
|
|
2526
|
+
)`;
|
|
2527
|
+
}
|
|
2528
|
+
function arrayIsEmpty(column, dialect) {
|
|
2529
|
+
assertNonEmpty(column, "arrayIsEmpty column");
|
|
2530
|
+
if (dialect === "postgres") {
|
|
2531
|
+
return `(${column} IS NULL OR array_length(${column}, 1) IS NULL)`;
|
|
2532
|
+
}
|
|
2533
|
+
return `(${column} IS NULL OR json_array_length(${column}) = 0)`;
|
|
2534
|
+
}
|
|
2535
|
+
function arrayIsNotEmpty(column, dialect) {
|
|
2536
|
+
assertNonEmpty(column, "arrayIsNotEmpty column");
|
|
2537
|
+
if (dialect === "postgres") {
|
|
2538
|
+
return `(${column} IS NOT NULL AND array_length(${column}, 1) IS NOT NULL)`;
|
|
2539
|
+
}
|
|
2540
|
+
return `(${column} IS NOT NULL AND json_array_length(${column}) > 0)`;
|
|
2541
|
+
}
|
|
2542
|
+
function arrayEquals(column, value, arrayType, dialect) {
|
|
2543
|
+
assertNonEmpty(column, "arrayEquals column");
|
|
2544
|
+
assertNonEmpty(value, "arrayEquals value");
|
|
2545
|
+
if (dialect === "postgres") {
|
|
2546
|
+
return `${column} = ${value}::${arrayType}`;
|
|
2547
|
+
}
|
|
2548
|
+
return `json(${column}) = json(${value})`;
|
|
2549
|
+
}
|
|
2550
|
+
function caseInsensitiveLike(column, pattern, dialect) {
|
|
2551
|
+
assertNonEmpty(column, "caseInsensitiveLike column");
|
|
2552
|
+
assertNonEmpty(pattern, "caseInsensitiveLike pattern");
|
|
2553
|
+
if (dialect === "postgres") {
|
|
2554
|
+
return `${column} ILIKE ${pattern}`;
|
|
2555
|
+
}
|
|
2556
|
+
return `LOWER(${column}) LIKE LOWER(${pattern})`;
|
|
2557
|
+
}
|
|
2558
|
+
function caseInsensitiveEquals(column, value, dialect) {
|
|
2559
|
+
assertNonEmpty(column, "caseInsensitiveEquals column");
|
|
2560
|
+
assertNonEmpty(value, "caseInsensitiveEquals value");
|
|
2561
|
+
return `LOWER(${column}) = LOWER(${value})`;
|
|
2562
|
+
}
|
|
2563
|
+
function jsonExtractText(column, path, dialect) {
|
|
2564
|
+
assertNonEmpty(column, "jsonExtractText column");
|
|
2565
|
+
assertNonEmpty(path, "jsonExtractText path");
|
|
2566
|
+
if (dialect === "postgres") {
|
|
2567
|
+
const p = String(path).trim();
|
|
2568
|
+
const pathExpr = /^\$\d+$/.test(p) ? `${p}::text[]` : p;
|
|
2569
|
+
return `${column}#>>${pathExpr}`;
|
|
2570
|
+
}
|
|
2571
|
+
return `json_extract(${column}, ${path})`;
|
|
2572
|
+
}
|
|
2573
|
+
function jsonExtractNumeric(column, path, dialect) {
|
|
2574
|
+
assertNonEmpty(column, "jsonExtractNumeric column");
|
|
2575
|
+
assertNonEmpty(path, "jsonExtractNumeric path");
|
|
2576
|
+
if (dialect === "postgres") {
|
|
2577
|
+
const p = String(path).trim();
|
|
2578
|
+
const pathExpr = /^\$\d+$/.test(p) ? `${p}::text[]` : p;
|
|
2579
|
+
return `(${column}#>>${pathExpr})::numeric`;
|
|
2580
|
+
}
|
|
2581
|
+
return `CAST(json_extract(${column}, ${path}) AS REAL)`;
|
|
2582
|
+
}
|
|
2583
|
+
function jsonToText(column, dialect) {
|
|
2584
|
+
assertNonEmpty(column, "jsonToText column");
|
|
2585
|
+
if (dialect === "postgres") {
|
|
2586
|
+
return `${column}::text`;
|
|
2587
|
+
}
|
|
2588
|
+
return column;
|
|
2589
|
+
}
|
|
2590
|
+
function inArray(column, value, dialect) {
|
|
2591
|
+
assertNonEmpty(column, "inArray column");
|
|
2592
|
+
assertNonEmpty(value, "inArray value");
|
|
2593
|
+
if (dialect === "postgres") {
|
|
2594
|
+
return `${column} = ANY(${value})`;
|
|
2595
|
+
}
|
|
2596
|
+
return `${column} IN (SELECT value FROM json_each(${value}))`;
|
|
2597
|
+
}
|
|
2598
|
+
function notInArray(column, value, dialect) {
|
|
2599
|
+
assertNonEmpty(column, "notInArray column");
|
|
2600
|
+
assertNonEmpty(value, "notInArray value");
|
|
2601
|
+
if (dialect === "postgres") {
|
|
2602
|
+
return `${column} != ALL(${value})`;
|
|
2603
|
+
}
|
|
2604
|
+
return `${column} NOT IN (SELECT value FROM json_each(${value}))`;
|
|
2605
|
+
}
|
|
2606
|
+
function getArrayType(prismaType, dialect) {
|
|
2607
|
+
if (!prismaType || prismaType.length === 0) {
|
|
2608
|
+
return dialect === "sqlite" ? "TEXT" : "text[]";
|
|
2609
|
+
}
|
|
2610
|
+
if (dialect === "sqlite") {
|
|
2611
|
+
return "TEXT";
|
|
2612
|
+
}
|
|
2613
|
+
const baseType = prismaType.replace(/\[\]|\?/g, "");
|
|
2614
|
+
switch (baseType) {
|
|
2615
|
+
case "String":
|
|
2616
|
+
return "text[]";
|
|
2617
|
+
case "Int":
|
|
2618
|
+
return "integer[]";
|
|
2619
|
+
case "Float":
|
|
2620
|
+
return "double precision[]";
|
|
2621
|
+
case "Decimal":
|
|
2622
|
+
return "numeric[]";
|
|
2623
|
+
case "Boolean":
|
|
2624
|
+
return "boolean[]";
|
|
2625
|
+
case "BigInt":
|
|
2626
|
+
return "bigint[]";
|
|
2627
|
+
case "DateTime":
|
|
2628
|
+
return "timestamptz[]";
|
|
2629
|
+
default:
|
|
2630
|
+
return `"${baseType}"[]`;
|
|
2631
|
+
}
|
|
2632
|
+
}
|
|
2633
|
+
function jsonAgg(content, dialect) {
|
|
2634
|
+
assertNonEmpty(content, "jsonAgg content");
|
|
2635
|
+
if (dialect === "postgres") {
|
|
2636
|
+
return `json_agg(${content})`;
|
|
2637
|
+
}
|
|
2638
|
+
return `json_group_array(${content})`;
|
|
2639
|
+
}
|
|
2640
|
+
function jsonBuildObject(pairs, dialect) {
|
|
2641
|
+
const safePairs = (pairs != null ? pairs : "").trim();
|
|
2642
|
+
if (dialect === "postgres") {
|
|
2643
|
+
return safePairs.length > 0 ? `json_build_object(${safePairs})` : `json_build_object()`;
|
|
2644
|
+
}
|
|
2645
|
+
return safePairs.length > 0 ? `json_object(${safePairs})` : `json_object()`;
|
|
2646
|
+
}
|
|
2647
|
+
function prepareArrayParam(value, dialect) {
|
|
2648
|
+
if (!Array.isArray(value)) {
|
|
2649
|
+
throw new Error("prepareArrayParam requires array value");
|
|
2650
|
+
}
|
|
2651
|
+
if (dialect === "postgres") {
|
|
2652
|
+
return value.map((v) => normalizeValue(v));
|
|
2653
|
+
}
|
|
2654
|
+
return JSON.stringify(value.map((v) => normalizeValue(v)));
|
|
2655
|
+
}
|
|
2421
2656
|
|
|
2422
2657
|
// src/builder/shared/constants.ts
|
|
2423
2658
|
var IS_PRODUCTION = process.env.NODE_ENV === "production";
|
|
@@ -3243,241 +3478,6 @@ function joinCondition(field, parentModel, childModel, parentAlias, childAlias)
|
|
|
3243
3478
|
function getModelByName(schemas, name) {
|
|
3244
3479
|
return schemas.find((m) => m.name === name);
|
|
3245
3480
|
}
|
|
3246
|
-
var MAX_DEPTH = 20;
|
|
3247
|
-
function normalizeValue(value, seen = /* @__PURE__ */ new WeakSet(), depth = 0) {
|
|
3248
|
-
if (depth > MAX_DEPTH) {
|
|
3249
|
-
throw new Error(`Max normalization depth exceeded (${MAX_DEPTH} levels)`);
|
|
3250
|
-
}
|
|
3251
|
-
if (value instanceof Date) {
|
|
3252
|
-
return normalizeDateValue(value);
|
|
3253
|
-
}
|
|
3254
|
-
if (typeof value === "bigint") {
|
|
3255
|
-
return value.toString();
|
|
3256
|
-
}
|
|
3257
|
-
if (Array.isArray(value)) {
|
|
3258
|
-
return normalizeArrayValue(value, seen, depth);
|
|
3259
|
-
}
|
|
3260
|
-
if (value && typeof value === "object") {
|
|
3261
|
-
return normalizeObjectValue(value, seen, depth);
|
|
3262
|
-
}
|
|
3263
|
-
return value;
|
|
3264
|
-
}
|
|
3265
|
-
function normalizeDateValue(date) {
|
|
3266
|
-
const t = date.getTime();
|
|
3267
|
-
if (!Number.isFinite(t)) {
|
|
3268
|
-
throw new Error("Invalid Date value in SQL params");
|
|
3269
|
-
}
|
|
3270
|
-
return date.toISOString();
|
|
3271
|
-
}
|
|
3272
|
-
function normalizeArrayValue(value, seen, depth) {
|
|
3273
|
-
const arrRef = value;
|
|
3274
|
-
if (seen.has(arrRef)) {
|
|
3275
|
-
throw new Error("Circular reference in SQL params");
|
|
3276
|
-
}
|
|
3277
|
-
seen.add(arrRef);
|
|
3278
|
-
const out = value.map((v) => normalizeValue(v, seen, depth + 1));
|
|
3279
|
-
seen.delete(arrRef);
|
|
3280
|
-
return out;
|
|
3281
|
-
}
|
|
3282
|
-
function normalizeObjectValue(value, seen, depth) {
|
|
3283
|
-
if (value instanceof Uint8Array) return value;
|
|
3284
|
-
if (typeof Buffer !== "undefined" && Buffer.isBuffer(value)) return value;
|
|
3285
|
-
const proto = Object.getPrototypeOf(value);
|
|
3286
|
-
const isPlain = proto === Object.prototype || proto === null;
|
|
3287
|
-
if (!isPlain) return value;
|
|
3288
|
-
const obj = value;
|
|
3289
|
-
if (seen.has(obj)) {
|
|
3290
|
-
throw new Error("Circular reference in SQL params");
|
|
3291
|
-
}
|
|
3292
|
-
seen.add(obj);
|
|
3293
|
-
const out = {};
|
|
3294
|
-
for (const [k, v] of Object.entries(obj)) {
|
|
3295
|
-
out[k] = normalizeValue(v, seen, depth + 1);
|
|
3296
|
-
}
|
|
3297
|
-
seen.delete(obj);
|
|
3298
|
-
return out;
|
|
3299
|
-
}
|
|
3300
|
-
|
|
3301
|
-
// src/sql-builder-dialect.ts
|
|
3302
|
-
var globalDialect = "postgres";
|
|
3303
|
-
function setGlobalDialect(dialect) {
|
|
3304
|
-
if (dialect !== "postgres" && dialect !== "sqlite") {
|
|
3305
|
-
throw new Error(
|
|
3306
|
-
`Invalid dialect: ${dialect}. Must be 'postgres' or 'sqlite'`
|
|
3307
|
-
);
|
|
3308
|
-
}
|
|
3309
|
-
globalDialect = dialect;
|
|
3310
|
-
}
|
|
3311
|
-
function getGlobalDialect() {
|
|
3312
|
-
return globalDialect;
|
|
3313
|
-
}
|
|
3314
|
-
function assertNonEmpty(value, name) {
|
|
3315
|
-
if (!value || value.trim().length === 0) {
|
|
3316
|
-
throw new Error(`${name} is required and cannot be empty`);
|
|
3317
|
-
}
|
|
3318
|
-
}
|
|
3319
|
-
function arrayContains(column, value, arrayType, dialect) {
|
|
3320
|
-
assertNonEmpty(column, "arrayContains column");
|
|
3321
|
-
assertNonEmpty(value, "arrayContains value");
|
|
3322
|
-
if (dialect === "postgres") {
|
|
3323
|
-
return `${column} @> ARRAY[${value}]::${arrayType}`;
|
|
3324
|
-
}
|
|
3325
|
-
return `EXISTS (SELECT 1 FROM json_each(${column}) WHERE value = ${value})`;
|
|
3326
|
-
}
|
|
3327
|
-
function arrayOverlaps(column, value, arrayType, dialect) {
|
|
3328
|
-
assertNonEmpty(column, "arrayOverlaps column");
|
|
3329
|
-
assertNonEmpty(value, "arrayOverlaps value");
|
|
3330
|
-
if (dialect === "postgres") {
|
|
3331
|
-
return `${column} && ${value}::${arrayType}`;
|
|
3332
|
-
}
|
|
3333
|
-
return `EXISTS (
|
|
3334
|
-
SELECT 1 FROM json_each(${column}) AS col
|
|
3335
|
-
JOIN json_each(${value}) AS val
|
|
3336
|
-
WHERE col.value = val.value
|
|
3337
|
-
)`;
|
|
3338
|
-
}
|
|
3339
|
-
function arrayContainsAll(column, value, arrayType, dialect) {
|
|
3340
|
-
assertNonEmpty(column, "arrayContainsAll column");
|
|
3341
|
-
assertNonEmpty(value, "arrayContainsAll value");
|
|
3342
|
-
if (dialect === "postgres") {
|
|
3343
|
-
return `${column} @> ${value}::${arrayType}`;
|
|
3344
|
-
}
|
|
3345
|
-
return `NOT EXISTS (
|
|
3346
|
-
SELECT 1 FROM json_each(${value}) AS val
|
|
3347
|
-
WHERE NOT EXISTS (
|
|
3348
|
-
SELECT 1 FROM json_each(${column}) AS col
|
|
3349
|
-
WHERE col.value = val.value
|
|
3350
|
-
)
|
|
3351
|
-
)`;
|
|
3352
|
-
}
|
|
3353
|
-
function arrayIsEmpty(column, dialect) {
|
|
3354
|
-
assertNonEmpty(column, "arrayIsEmpty column");
|
|
3355
|
-
if (dialect === "postgres") {
|
|
3356
|
-
return `(${column} IS NULL OR array_length(${column}, 1) IS NULL)`;
|
|
3357
|
-
}
|
|
3358
|
-
return `(${column} IS NULL OR json_array_length(${column}) = 0)`;
|
|
3359
|
-
}
|
|
3360
|
-
function arrayIsNotEmpty(column, dialect) {
|
|
3361
|
-
assertNonEmpty(column, "arrayIsNotEmpty column");
|
|
3362
|
-
if (dialect === "postgres") {
|
|
3363
|
-
return `(${column} IS NOT NULL AND array_length(${column}, 1) IS NOT NULL)`;
|
|
3364
|
-
}
|
|
3365
|
-
return `(${column} IS NOT NULL AND json_array_length(${column}) > 0)`;
|
|
3366
|
-
}
|
|
3367
|
-
function arrayEquals(column, value, arrayType, dialect) {
|
|
3368
|
-
assertNonEmpty(column, "arrayEquals column");
|
|
3369
|
-
assertNonEmpty(value, "arrayEquals value");
|
|
3370
|
-
if (dialect === "postgres") {
|
|
3371
|
-
return `${column} = ${value}::${arrayType}`;
|
|
3372
|
-
}
|
|
3373
|
-
return `json(${column}) = json(${value})`;
|
|
3374
|
-
}
|
|
3375
|
-
function caseInsensitiveLike(column, pattern, dialect) {
|
|
3376
|
-
assertNonEmpty(column, "caseInsensitiveLike column");
|
|
3377
|
-
assertNonEmpty(pattern, "caseInsensitiveLike pattern");
|
|
3378
|
-
if (dialect === "postgres") {
|
|
3379
|
-
return `${column} ILIKE ${pattern}`;
|
|
3380
|
-
}
|
|
3381
|
-
return `LOWER(${column}) LIKE LOWER(${pattern})`;
|
|
3382
|
-
}
|
|
3383
|
-
function caseInsensitiveEquals(column, value, dialect) {
|
|
3384
|
-
assertNonEmpty(column, "caseInsensitiveEquals column");
|
|
3385
|
-
assertNonEmpty(value, "caseInsensitiveEquals value");
|
|
3386
|
-
return `LOWER(${column}) = LOWER(${value})`;
|
|
3387
|
-
}
|
|
3388
|
-
function jsonExtractText(column, path, dialect) {
|
|
3389
|
-
assertNonEmpty(column, "jsonExtractText column");
|
|
3390
|
-
assertNonEmpty(path, "jsonExtractText path");
|
|
3391
|
-
if (dialect === "postgres") {
|
|
3392
|
-
const p = String(path).trim();
|
|
3393
|
-
const pathExpr = /^\$\d+$/.test(p) ? `${p}::text[]` : p;
|
|
3394
|
-
return `${column}#>>${pathExpr}`;
|
|
3395
|
-
}
|
|
3396
|
-
return `json_extract(${column}, ${path})`;
|
|
3397
|
-
}
|
|
3398
|
-
function jsonExtractNumeric(column, path, dialect) {
|
|
3399
|
-
assertNonEmpty(column, "jsonExtractNumeric column");
|
|
3400
|
-
assertNonEmpty(path, "jsonExtractNumeric path");
|
|
3401
|
-
if (dialect === "postgres") {
|
|
3402
|
-
const p = String(path).trim();
|
|
3403
|
-
const pathExpr = /^\$\d+$/.test(p) ? `${p}::text[]` : p;
|
|
3404
|
-
return `(${column}#>>${pathExpr})::numeric`;
|
|
3405
|
-
}
|
|
3406
|
-
return `CAST(json_extract(${column}, ${path}) AS REAL)`;
|
|
3407
|
-
}
|
|
3408
|
-
function jsonToText(column, dialect) {
|
|
3409
|
-
assertNonEmpty(column, "jsonToText column");
|
|
3410
|
-
if (dialect === "postgres") {
|
|
3411
|
-
return `${column}::text`;
|
|
3412
|
-
}
|
|
3413
|
-
return column;
|
|
3414
|
-
}
|
|
3415
|
-
function inArray(column, value, dialect) {
|
|
3416
|
-
assertNonEmpty(column, "inArray column");
|
|
3417
|
-
assertNonEmpty(value, "inArray value");
|
|
3418
|
-
if (dialect === "postgres") {
|
|
3419
|
-
return `${column} = ANY(${value})`;
|
|
3420
|
-
}
|
|
3421
|
-
return `${column} IN (SELECT value FROM json_each(${value}))`;
|
|
3422
|
-
}
|
|
3423
|
-
function notInArray(column, value, dialect) {
|
|
3424
|
-
assertNonEmpty(column, "notInArray column");
|
|
3425
|
-
assertNonEmpty(value, "notInArray value");
|
|
3426
|
-
if (dialect === "postgres") {
|
|
3427
|
-
return `${column} != ALL(${value})`;
|
|
3428
|
-
}
|
|
3429
|
-
return `${column} NOT IN (SELECT value FROM json_each(${value}))`;
|
|
3430
|
-
}
|
|
3431
|
-
function getArrayType(prismaType, dialect) {
|
|
3432
|
-
if (!prismaType || prismaType.length === 0) {
|
|
3433
|
-
return dialect === "sqlite" ? "TEXT" : "text[]";
|
|
3434
|
-
}
|
|
3435
|
-
if (dialect === "sqlite") {
|
|
3436
|
-
return "TEXT";
|
|
3437
|
-
}
|
|
3438
|
-
const baseType = prismaType.replace(/\[\]|\?/g, "");
|
|
3439
|
-
switch (baseType) {
|
|
3440
|
-
case "String":
|
|
3441
|
-
return "text[]";
|
|
3442
|
-
case "Int":
|
|
3443
|
-
return "integer[]";
|
|
3444
|
-
case "Float":
|
|
3445
|
-
return "double precision[]";
|
|
3446
|
-
case "Decimal":
|
|
3447
|
-
return "numeric[]";
|
|
3448
|
-
case "Boolean":
|
|
3449
|
-
return "boolean[]";
|
|
3450
|
-
case "BigInt":
|
|
3451
|
-
return "bigint[]";
|
|
3452
|
-
case "DateTime":
|
|
3453
|
-
return "timestamptz[]";
|
|
3454
|
-
default:
|
|
3455
|
-
return `"${baseType}"[]`;
|
|
3456
|
-
}
|
|
3457
|
-
}
|
|
3458
|
-
function jsonAgg(content, dialect) {
|
|
3459
|
-
assertNonEmpty(content, "jsonAgg content");
|
|
3460
|
-
if (dialect === "postgres") {
|
|
3461
|
-
return `json_agg(${content})`;
|
|
3462
|
-
}
|
|
3463
|
-
return `json_group_array(${content})`;
|
|
3464
|
-
}
|
|
3465
|
-
function jsonBuildObject(pairs, dialect) {
|
|
3466
|
-
const safePairs = (pairs != null ? pairs : "").trim();
|
|
3467
|
-
if (dialect === "postgres") {
|
|
3468
|
-
return safePairs.length > 0 ? `json_build_object(${safePairs})` : `json_build_object()`;
|
|
3469
|
-
}
|
|
3470
|
-
return safePairs.length > 0 ? `json_object(${safePairs})` : `json_object()`;
|
|
3471
|
-
}
|
|
3472
|
-
function prepareArrayParam(value, dialect) {
|
|
3473
|
-
if (!Array.isArray(value)) {
|
|
3474
|
-
throw new Error("prepareArrayParam requires array value");
|
|
3475
|
-
}
|
|
3476
|
-
if (dialect === "postgres") {
|
|
3477
|
-
return value.map((v) => normalizeValue(v));
|
|
3478
|
-
}
|
|
3479
|
-
return JSON.stringify(value.map((v) => normalizeValue(v)));
|
|
3480
|
-
}
|
|
3481
3481
|
function normalizeIntLike(name, v, opts = {}) {
|
|
3482
3482
|
var _a3, _b;
|
|
3483
3483
|
if (!isNotNullish(v)) return void 0;
|
|
@@ -7164,7 +7164,6 @@ var DEFAULT_SELECT_CACHE = /* @__PURE__ */ new WeakMap();
|
|
|
7164
7164
|
function toSelectEntries(select2) {
|
|
7165
7165
|
const out = [];
|
|
7166
7166
|
for (const [k, v] of Object.entries(select2)) {
|
|
7167
|
-
if (k === "_count") continue;
|
|
7168
7167
|
if (v !== false && v !== void 0) out.push([k, v]);
|
|
7169
7168
|
}
|
|
7170
7169
|
return out;
|
|
@@ -7257,7 +7256,9 @@ function validateFieldKeys(entries, scalarSet, relationSet, allowCount = false)
|
|
|
7257
7256
|
if (!scalarSet.has(k) && !relationSet.has(k)) unknown.push(k);
|
|
7258
7257
|
}
|
|
7259
7258
|
if (unknown.length > 0) {
|
|
7260
|
-
throw new Error(
|
|
7259
|
+
throw new Error(
|
|
7260
|
+
`Unknown field '${unknown.join("', '")}' does not exist on this model`
|
|
7261
|
+
);
|
|
7261
7262
|
}
|
|
7262
7263
|
}
|
|
7263
7264
|
function buildSelectedScalarParts(entries, scalarNames, alias, model) {
|
|
@@ -7438,23 +7439,56 @@ function buildNestedToOneJoins(relations, baseAlias, baseModel, aliasGen, dialec
|
|
|
7438
7439
|
}
|
|
7439
7440
|
return { joins, aliasMap };
|
|
7440
7441
|
}
|
|
7441
|
-
function buildNestedToOneSelects(relations, aliasMap) {
|
|
7442
|
+
function buildNestedToOneSelects(relations, aliasMap, dialect) {
|
|
7442
7443
|
const selects = [];
|
|
7443
7444
|
for (const rel of relations) {
|
|
7444
7445
|
const relAlias = aliasMap.get(rel.name);
|
|
7445
7446
|
if (!relAlias) continue;
|
|
7446
7447
|
const relSelect = buildRelationSelect(rel.args, rel.model, relAlias);
|
|
7447
7448
|
if (!relSelect || relSelect.trim().length === 0) continue;
|
|
7448
|
-
|
|
7449
|
+
const jsonExpr = jsonBuildObject(relSelect, dialect);
|
|
7450
|
+
const pkField = getPrimaryKeyField(rel.model);
|
|
7451
|
+
const pkCol = `${relAlias}.${quoteColumn(rel.model, pkField)}`;
|
|
7452
|
+
const nullSafeExpr = `CASE WHEN ${pkCol} IS NOT NULL THEN ${jsonExpr} ELSE NULL END`;
|
|
7453
|
+
selects.push(`${sqlStringLiteral(rel.name)}, ${nullSafeExpr}`);
|
|
7449
7454
|
}
|
|
7450
7455
|
return selects;
|
|
7451
7456
|
}
|
|
7457
|
+
function extractCountSelectFromRelArgs(relArgs) {
|
|
7458
|
+
if (!isPlainObject(relArgs)) return null;
|
|
7459
|
+
const obj = relArgs;
|
|
7460
|
+
if (!isPlainObject(obj.select)) return null;
|
|
7461
|
+
const sel = obj.select;
|
|
7462
|
+
const countRaw = sel["_count"];
|
|
7463
|
+
if (!countRaw) return null;
|
|
7464
|
+
if (isPlainObject(countRaw) && "select" in countRaw) {
|
|
7465
|
+
return countRaw.select;
|
|
7466
|
+
}
|
|
7467
|
+
return null;
|
|
7468
|
+
}
|
|
7452
7469
|
function buildSelectWithNestedIncludes(relArgs, relModel, relAlias, ctx) {
|
|
7453
7470
|
const nestedToOnes = extractNestedToOneRelations(
|
|
7454
7471
|
relArgs,
|
|
7455
7472
|
relModel,
|
|
7456
7473
|
ctx.schemaByName
|
|
7457
7474
|
);
|
|
7475
|
+
const countSelect = extractCountSelectFromRelArgs(relArgs);
|
|
7476
|
+
const countJoins = [];
|
|
7477
|
+
function appendCountToSelect(baseSelect2) {
|
|
7478
|
+
if (!countSelect || Object.keys(countSelect).length === 0) return baseSelect2;
|
|
7479
|
+
const countBuild = buildRelationCountSql(
|
|
7480
|
+
countSelect,
|
|
7481
|
+
relModel,
|
|
7482
|
+
ctx.schemas,
|
|
7483
|
+
relAlias,
|
|
7484
|
+
ctx.params,
|
|
7485
|
+
ctx.dialect
|
|
7486
|
+
);
|
|
7487
|
+
if (!countBuild.jsonPairs) return baseSelect2;
|
|
7488
|
+
countJoins.push(...countBuild.joins);
|
|
7489
|
+
const countExpr = `'_count', ${jsonBuildObject(countBuild.jsonPairs, ctx.dialect)}`;
|
|
7490
|
+
return baseSelect2 ? `${baseSelect2}${SQL_SEPARATORS.FIELD_LIST}${countExpr}` : countExpr;
|
|
7491
|
+
}
|
|
7458
7492
|
if (nestedToOnes.length === 0) {
|
|
7459
7493
|
let relSelect = buildRelationSelect(relArgs, relModel, relAlias);
|
|
7460
7494
|
let nestedIncludes = [];
|
|
@@ -7483,7 +7517,8 @@ function buildSelectWithNestedIncludes(relArgs, relModel, relAlias, ctx) {
|
|
|
7483
7517
|
).join(SQL_SEPARATORS.FIELD_LIST);
|
|
7484
7518
|
relSelect = isNotNullish(relSelect) && relSelect.trim().length > 0 ? `${relSelect}${SQL_SEPARATORS.FIELD_LIST}${nestedSelects2}` : nestedSelects2;
|
|
7485
7519
|
}
|
|
7486
|
-
|
|
7520
|
+
relSelect = appendCountToSelect(relSelect);
|
|
7521
|
+
return { select: relSelect, nestedJoins: countJoins };
|
|
7487
7522
|
}
|
|
7488
7523
|
const { joins, aliasMap } = buildNestedToOneJoins(
|
|
7489
7524
|
nestedToOnes,
|
|
@@ -7493,7 +7528,11 @@ function buildSelectWithNestedIncludes(relArgs, relModel, relAlias, ctx) {
|
|
|
7493
7528
|
ctx.dialect
|
|
7494
7529
|
);
|
|
7495
7530
|
const baseSelect = buildRelationSelect(relArgs, relModel, relAlias);
|
|
7496
|
-
const nestedSelects = buildNestedToOneSelects(
|
|
7531
|
+
const nestedSelects = buildNestedToOneSelects(
|
|
7532
|
+
nestedToOnes,
|
|
7533
|
+
aliasMap,
|
|
7534
|
+
ctx.dialect
|
|
7535
|
+
);
|
|
7497
7536
|
const allParts = [];
|
|
7498
7537
|
if (baseSelect && baseSelect.trim().length > 0) {
|
|
7499
7538
|
allParts.push(baseSelect);
|
|
@@ -7501,9 +7540,11 @@ function buildSelectWithNestedIncludes(relArgs, relModel, relAlias, ctx) {
|
|
|
7501
7540
|
for (const ns of nestedSelects) {
|
|
7502
7541
|
allParts.push(ns);
|
|
7503
7542
|
}
|
|
7543
|
+
let finalSelect = allParts.join(SQL_SEPARATORS.FIELD_LIST);
|
|
7544
|
+
finalSelect = appendCountToSelect(finalSelect);
|
|
7504
7545
|
return {
|
|
7505
|
-
select:
|
|
7506
|
-
nestedJoins: joins
|
|
7546
|
+
select: finalSelect,
|
|
7547
|
+
nestedJoins: [...joins, ...countJoins]
|
|
7507
7548
|
};
|
|
7508
7549
|
}
|
|
7509
7550
|
function buildWhereParts(whereInput, relModel, relAlias, ctx) {
|
|
@@ -7885,7 +7926,7 @@ function validateDistinct(model, distinct) {
|
|
|
7885
7926
|
const relationSet = getRelationFieldSet(model);
|
|
7886
7927
|
if (relationSet.has(f)) {
|
|
7887
7928
|
throw new Error(
|
|
7888
|
-
`distinct field '${f}' is a relation. Only scalar fields are allowed.
|
|
7929
|
+
`distinct field '${f}' is a relation field. Only scalar fields are allowed.
|
|
7889
7930
|
Available scalar fields: ${[...scalarSet].join(", ")}`
|
|
7890
7931
|
);
|
|
7891
7932
|
}
|
|
@@ -7923,7 +7964,7 @@ function validateOrderBy(model, orderBy) {
|
|
|
7923
7964
|
if (!scalarSet.has(f)) {
|
|
7924
7965
|
if (relationSet.has(f)) {
|
|
7925
7966
|
throw new Error(
|
|
7926
|
-
`orderBy field '${f}' is a relation. Only scalar fields are allowed.
|
|
7967
|
+
`orderBy field '${f}' is a relation field. Only scalar fields are allowed.
|
|
7927
7968
|
Available scalar fields: ${[...scalarSet].join(", ")}`
|
|
7928
7969
|
);
|
|
7929
7970
|
}
|