agnostic-query
Version:
Type-safe fluent builder for portable query schemas. Runtime-agnostic, database-agnostic — the same QuerySchema drives Drizzle, Kysely, db0, or raw SQL.
54 lines (53 loc) • 1.64 kB
JavaScript
import { isComparisonWhere } from "../core/where.js";
import { fieldToStr } from "../sql/pg.js";
import { sql } from "kysely";
//#region src/kysely/pg.ts
const kyselyOpMap = {
"=": "=",
">": ">",
">=": ">=",
"<": "<",
"<=": "<=",
like: "like",
ilike: "ilike",
"<@": "<@",
"@>": "@>",
"&&": "&&"
};
const emptyExp = (exp) => exp.and([]);
const build = (where, exp) => {
if (where.op === "not") {
const inner = build(where.condition, exp);
if (!inner) return emptyExp(exp);
return exp.not(inner);
}
if (where.op === "and" || where.op === "or") {
const parts = where.conditions.map((c) => build(c, exp)).filter((c) => c !== void 0);
if (parts.length === 0) return emptyExp(exp);
return where.op === "and" ? exp.and(parts) : exp.or(parts);
}
if (!isComparisonWhere(where)) return emptyExp(exp);
const target = sql.raw(fieldToStr(where.field));
if (where.op === "is null") return exp.eb(target, "is", null);
if (where.op === "in") return exp.eb(target, "in", where.values);
const op = kyselyOpMap[where.op];
if (where.op === "like" || where.op === "ilike") return exp.eb(target, op, where.value);
return exp.eb(target, op, where.value);
};
const toKyselyWhere = (where) => {
return (exp) => {
if (!where) return emptyExp(exp);
return build(where, exp);
};
};
const toKyselyOrderBy = (q, orderBy) => {
if (!orderBy || orderBy.length === 0) return q;
let currentQuery = q;
for (const order of orderBy) {
const sqlTarget = fieldToStr(order.field);
currentQuery = currentQuery.orderBy(sql.raw(sqlTarget), order.direction);
}
return currentQuery;
};
//#endregion
export { toKyselyOrderBy, toKyselyWhere };