prisma-sql 1.71.0 → 1.72.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 +282 -249
- package/dist/generator.cjs.map +1 -1
- package/dist/generator.js +282 -249
- package/dist/generator.js.map +1 -1
- package/dist/index.cjs +456 -394
- 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 +456 -395
- 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.72.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) {
|
|
@@ -7449,12 +7450,41 @@ function buildNestedToOneSelects(relations, aliasMap) {
|
|
|
7449
7450
|
}
|
|
7450
7451
|
return selects;
|
|
7451
7452
|
}
|
|
7453
|
+
function extractCountSelectFromRelArgs(relArgs) {
|
|
7454
|
+
if (!isPlainObject(relArgs)) return null;
|
|
7455
|
+
const obj = relArgs;
|
|
7456
|
+
if (!isPlainObject(obj.select)) return null;
|
|
7457
|
+
const sel = obj.select;
|
|
7458
|
+
const countRaw = sel["_count"];
|
|
7459
|
+
if (!countRaw) return null;
|
|
7460
|
+
if (isPlainObject(countRaw) && "select" in countRaw) {
|
|
7461
|
+
return countRaw.select;
|
|
7462
|
+
}
|
|
7463
|
+
return null;
|
|
7464
|
+
}
|
|
7452
7465
|
function buildSelectWithNestedIncludes(relArgs, relModel, relAlias, ctx) {
|
|
7453
7466
|
const nestedToOnes = extractNestedToOneRelations(
|
|
7454
7467
|
relArgs,
|
|
7455
7468
|
relModel,
|
|
7456
7469
|
ctx.schemaByName
|
|
7457
7470
|
);
|
|
7471
|
+
const countSelect = extractCountSelectFromRelArgs(relArgs);
|
|
7472
|
+
const countJoins = [];
|
|
7473
|
+
function appendCountToSelect(baseSelect2) {
|
|
7474
|
+
if (!countSelect || Object.keys(countSelect).length === 0) return baseSelect2;
|
|
7475
|
+
const countBuild = buildRelationCountSql(
|
|
7476
|
+
countSelect,
|
|
7477
|
+
relModel,
|
|
7478
|
+
ctx.schemas,
|
|
7479
|
+
relAlias,
|
|
7480
|
+
ctx.params,
|
|
7481
|
+
ctx.dialect
|
|
7482
|
+
);
|
|
7483
|
+
if (!countBuild.jsonPairs) return baseSelect2;
|
|
7484
|
+
countJoins.push(...countBuild.joins);
|
|
7485
|
+
const countExpr = `'_count', ${jsonBuildObject(countBuild.jsonPairs, ctx.dialect)}`;
|
|
7486
|
+
return baseSelect2 ? `${baseSelect2}${SQL_SEPARATORS.FIELD_LIST}${countExpr}` : countExpr;
|
|
7487
|
+
}
|
|
7458
7488
|
if (nestedToOnes.length === 0) {
|
|
7459
7489
|
let relSelect = buildRelationSelect(relArgs, relModel, relAlias);
|
|
7460
7490
|
let nestedIncludes = [];
|
|
@@ -7483,7 +7513,8 @@ function buildSelectWithNestedIncludes(relArgs, relModel, relAlias, ctx) {
|
|
|
7483
7513
|
).join(SQL_SEPARATORS.FIELD_LIST);
|
|
7484
7514
|
relSelect = isNotNullish(relSelect) && relSelect.trim().length > 0 ? `${relSelect}${SQL_SEPARATORS.FIELD_LIST}${nestedSelects2}` : nestedSelects2;
|
|
7485
7515
|
}
|
|
7486
|
-
|
|
7516
|
+
relSelect = appendCountToSelect(relSelect);
|
|
7517
|
+
return { select: relSelect, nestedJoins: countJoins };
|
|
7487
7518
|
}
|
|
7488
7519
|
const { joins, aliasMap } = buildNestedToOneJoins(
|
|
7489
7520
|
nestedToOnes,
|
|
@@ -7501,9 +7532,11 @@ function buildSelectWithNestedIncludes(relArgs, relModel, relAlias, ctx) {
|
|
|
7501
7532
|
for (const ns of nestedSelects) {
|
|
7502
7533
|
allParts.push(ns);
|
|
7503
7534
|
}
|
|
7535
|
+
let finalSelect = allParts.join(SQL_SEPARATORS.FIELD_LIST);
|
|
7536
|
+
finalSelect = appendCountToSelect(finalSelect);
|
|
7504
7537
|
return {
|
|
7505
|
-
select:
|
|
7506
|
-
nestedJoins: joins
|
|
7538
|
+
select: finalSelect,
|
|
7539
|
+
nestedJoins: [...joins, ...countJoins]
|
|
7507
7540
|
};
|
|
7508
7541
|
}
|
|
7509
7542
|
function buildWhereParts(whereInput, relModel, relAlias, ctx) {
|
|
@@ -7885,7 +7918,7 @@ function validateDistinct(model, distinct) {
|
|
|
7885
7918
|
const relationSet = getRelationFieldSet(model);
|
|
7886
7919
|
if (relationSet.has(f)) {
|
|
7887
7920
|
throw new Error(
|
|
7888
|
-
`distinct field '${f}' is a relation. Only scalar fields are allowed.
|
|
7921
|
+
`distinct field '${f}' is a relation field. Only scalar fields are allowed.
|
|
7889
7922
|
Available scalar fields: ${[...scalarSet].join(", ")}`
|
|
7890
7923
|
);
|
|
7891
7924
|
}
|
|
@@ -7923,7 +7956,7 @@ function validateOrderBy(model, orderBy) {
|
|
|
7923
7956
|
if (!scalarSet.has(f)) {
|
|
7924
7957
|
if (relationSet.has(f)) {
|
|
7925
7958
|
throw new Error(
|
|
7926
|
-
`orderBy field '${f}' is a relation. Only scalar fields are allowed.
|
|
7959
|
+
`orderBy field '${f}' is a relation field. Only scalar fields are allowed.
|
|
7927
7960
|
Available scalar fields: ${[...scalarSet].join(", ")}`
|
|
7928
7961
|
);
|
|
7929
7962
|
}
|