UNPKG

@minatojs/sql-utils

Version:
574 lines (572 loc) 26.2 kB
var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); // src/index.ts import { isNullable } from "cosmokit"; import { Eval, Field, flatten, isAggrExpr, isComparable, isEvalExpr, isFlat, randomId, Selection, Type, unravel } from "minato"; function escapeId(value) { return "`" + value + "`"; } __name(escapeId, "escapeId"); function isBracketed(value) { return value.startsWith("(") && value.endsWith(")"); } __name(isBracketed, "isBracketed"); function isSqlJson(type) { return type ? type.type === "json" || !!type.inner : false; } __name(isSqlJson, "isSqlJson"); var Builder = class { constructor(driver, tables) { this.driver = driver; this.state.tables = tables; this.queryOperators = { // logical $or: /* @__PURE__ */ __name((key, value) => this.logicalOr(value.map((value2) => this.parseFieldQuery(key, value2))), "$or"), $and: /* @__PURE__ */ __name((key, value) => this.logicalAnd(value.map((value2) => this.parseFieldQuery(key, value2))), "$and"), $not: /* @__PURE__ */ __name((key, value) => this.logicalNot(this.parseFieldQuery(key, value)), "$not"), // existence $exists: /* @__PURE__ */ __name((key, value) => this.createNullQuery(key, value), "$exists"), // comparison $eq: this.createEqualQuery, $ne: this.comparator("!="), $gt: this.comparator(">"), $gte: this.comparator(">="), $lt: this.comparator("<"), $lte: this.comparator("<="), // membership $in: /* @__PURE__ */ __name((key, value) => this.createMemberQuery(key, value, ""), "$in"), $nin: /* @__PURE__ */ __name((key, value) => this.createMemberQuery(key, value, " NOT"), "$nin"), // regexp $regex: /* @__PURE__ */ __name((key, value) => this.createRegExpQuery(key, value), "$regex"), $regexFor: /* @__PURE__ */ __name((key, value) => typeof value === "string" ? `${this.escape(value)} collate utf8mb4_bin regexp ${key}` : `${this.escape(value.input)} ${value.flags?.includes("i") ? "regexp" : "collate utf8mb4_bin regexp"} ${key}`, "$regexFor"), // bitwise $bitsAllSet: /* @__PURE__ */ __name((key, value) => `${key} & ${this.escape(value)} = ${this.escape(value)}`, "$bitsAllSet"), $bitsAllClear: /* @__PURE__ */ __name((key, value) => `${key} & ${this.escape(value)} = 0`, "$bitsAllClear"), $bitsAnySet: /* @__PURE__ */ __name((key, value) => `${key} & ${this.escape(value)} != 0`, "$bitsAnySet"), $bitsAnyClear: /* @__PURE__ */ __name((key, value) => `${key} & ${this.escape(value)} != ${this.escape(value)}`, "$bitsAnyClear"), // list $el: /* @__PURE__ */ __name((key, value) => { if (Array.isArray(value)) { return this.logicalOr(value.map((value2) => this.createElementQuery(key, value2))); } else if (typeof value !== "number" && typeof value !== "string") { throw new TypeError("query expr under $el is not supported"); } else { return this.createElementQuery(key, value); } }, "$el"), $size: /* @__PURE__ */ __name((key, value) => { if (this.isJsonQuery(key)) { return `${this.jsonLength(key)} = ${this.escape(value)}`; } else { if (!value) return this.logicalNot(key); return `${key} AND LENGTH(${key}) - LENGTH(REPLACE(${key}, ${this.escape(",")}, ${this.escape("")})) = ${this.escape(value)} - 1`; } }, "$size") }; this.evalOperators = { // universal $: /* @__PURE__ */ __name((key) => this.getRecursive(key), "$"), $select: /* @__PURE__ */ __name((args) => `${args.map((arg) => this.parseEval(arg)).join(", ")}`, "$select"), $if: /* @__PURE__ */ __name((args) => `if(${args.map((arg) => this.parseEval(arg)).join(", ")})`, "$if"), $ifNull: /* @__PURE__ */ __name((args) => `ifnull(${args.map((arg) => this.parseEval(arg)).join(", ")})`, "$ifNull"), // number $add: /* @__PURE__ */ __name((args) => `(${args.map((arg) => this.parseEval(arg)).join(" + ")})`, "$add"), $multiply: /* @__PURE__ */ __name((args) => `(${args.map((arg) => this.parseEval(arg)).join(" * ")})`, "$multiply"), $subtract: this.binary("-"), $divide: this.binary("/"), $modulo: this.binary("%"), // mathemetic $abs: /* @__PURE__ */ __name((arg) => `abs(${this.parseEval(arg)})`, "$abs"), $floor: /* @__PURE__ */ __name((arg) => `floor(${this.parseEval(arg)})`, "$floor"), $ceil: /* @__PURE__ */ __name((arg) => `ceil(${this.parseEval(arg)})`, "$ceil"), $round: /* @__PURE__ */ __name((arg) => `round(${this.parseEval(arg)})`, "$round"), $exp: /* @__PURE__ */ __name((arg) => `exp(${this.parseEval(arg)})`, "$exp"), $log: /* @__PURE__ */ __name((args) => `log(${args.filter((x) => !isNullable(x)).map((arg) => this.parseEval(arg)).reverse().join(", ")})`, "$log"), $power: /* @__PURE__ */ __name((args) => `power(${args.map((arg) => this.parseEval(arg)).join(", ")})`, "$power"), $random: /* @__PURE__ */ __name(() => `rand()`, "$random"), // string $concat: /* @__PURE__ */ __name((args) => `concat(${args.map((arg) => this.parseEval(arg)).join(", ")})`, "$concat"), $regex: /* @__PURE__ */ __name(([key, value, flags]) => `(${this.parseEval(key)} ${flags?.includes("i") || value instanceof RegExp && value.flags.includes("i") ? "regexp" : "collate utf8mb4_bin regexp"} ${this.parseEval(value)})`, "$regex"), // logical / bitwise $or: /* @__PURE__ */ __name((args) => { const type = Type.fromTerm(this.state.expr, Type.Boolean); if (Field.boolean.includes(type.type)) return this.logicalOr(args.map((arg) => this.parseEval(arg))); else return `(${args.map((arg) => this.parseEval(arg)).join(" | ")})`; }, "$or"), $and: /* @__PURE__ */ __name((args) => { const type = Type.fromTerm(this.state.expr, Type.Boolean); if (Field.boolean.includes(type.type)) return this.logicalAnd(args.map((arg) => this.parseEval(arg))); else return `(${args.map((arg) => this.parseEval(arg)).join(" & ")})`; }, "$and"), $not: /* @__PURE__ */ __name((arg) => { const type = Type.fromTerm(this.state.expr, Type.Boolean); if (Field.boolean.includes(type.type)) return this.logicalNot(this.parseEval(arg)); else return `(~(${this.parseEval(arg)}))`; }, "$not"), // boolean $eq: this.binary("="), $ne: this.binary("!="), $gt: this.binary(">"), $gte: this.binary(">="), $lt: this.binary("<"), $lte: this.binary("<="), // membership $in: /* @__PURE__ */ __name(([key, value]) => this.asEncoded(this.createMemberQuery(this.parseEval(key, false), value, ""), false), "$in"), $nin: /* @__PURE__ */ __name(([key, value]) => this.asEncoded(this.createMemberQuery(this.parseEval(key, false), value, " NOT"), false), "$nin"), // typecast $literal: /* @__PURE__ */ __name(([value, type]) => this.escape(value, type), "$literal"), // aggregation $sum: /* @__PURE__ */ __name((expr) => this.createAggr(expr, (value) => `ifnull(sum(${value}), 0)`), "$sum"), $avg: /* @__PURE__ */ __name((expr) => this.createAggr(expr, (value) => `avg(${value})`), "$avg"), $min: /* @__PURE__ */ __name((expr) => this.createAggr(expr, (value) => `min(${value})`), "$min"), $max: /* @__PURE__ */ __name((expr) => this.createAggr(expr, (value) => `max(${value})`), "$max"), $count: /* @__PURE__ */ __name((expr) => this.createAggr(expr, (value) => `count(distinct ${value})`), "$count"), $length: /* @__PURE__ */ __name((expr) => this.createAggr(expr, (value) => `count(${value})`, (value) => this.isEncoded() ? this.jsonLength(value) : this.asEncoded(`if(${value}, LENGTH(${value}) - LENGTH(REPLACE(${value}, ${this.escape(",")}, ${this.escape("")})) + 1, 0)`, false)), "$length"), $object: /* @__PURE__ */ __name((fields) => this.groupObject(fields), "$object"), $array: /* @__PURE__ */ __name((expr) => this.groupArray(this.transform(this.parseEval(expr, false), expr, "encode")), "$array"), $get: /* @__PURE__ */ __name(([x, key]) => typeof key === "string" ? this.asEncoded(`json_extract(${this.parseEval(x, false)}, '$.${key}')`, true) : this.asEncoded(`json_extract(${this.parseEval(x, false)}, concat('$[', ${this.parseEval(key)}, ']'))`, true), "$get"), $exec: /* @__PURE__ */ __name((sel) => this.parseSelection(sel), "$exec") }; } static { __name(this, "Builder"); } escapeMap = {}; escapeRegExp; createEqualQuery = this.comparator("="); queryOperators; evalOperators; state = {}; $true = "1"; $false = "0"; modifiedTable; transformers = /* @__PURE__ */ Object.create(null); createNullQuery(key, value) { return `${key} is ${value ? "not " : ""}null`; } createMemberQuery(key, value, notStr = "") { if (Array.isArray(value)) { if (!value.length) return notStr ? this.$true : this.$false; if (Array.isArray(value[0])) { return `(${key})${notStr} in (${value.map((val) => `(${val.map((x) => this.escape(x)).join(", ")})`).join(", ")})`; } return `${key}${notStr} in (${value.map((val) => this.escape(val)).join(", ")})`; } else if (value.$exec) { return `(${key})${notStr} in ${this.parseSelection(value.$exec, true)}`; } else if (Type.fromTerm(value)?.type === "list") { const res = this.listContains(this.parseEval(value), key); return notStr ? this.logicalNot(res) : res; } else { const res = this.jsonContains(this.parseEval(value, false), this.encode(key, true, true)); return notStr ? this.logicalNot(res) : res; } } createRegExpQuery(key, value) { if (typeof value !== "string" && value.flags?.includes("i")) { return `${key} regexp ${this.escape(value.source)}`; } else { return `${key} collate utf8mb4_bin regexp ${this.escape(typeof value === "string" ? value : value.source)}`; } } listContains(list, value) { return `find_in_set(${value}, ${list})`; } createElementQuery(key, value) { if (this.isJsonQuery(key)) { return this.jsonContains(key, this.encode(this.escape(value), true, true)); } else { return `find_in_set(${this.escape(value)}, ${key})`; } } isJsonQuery(key) { return Type.fromTerm(this.state.expr)?.type === "json" || this.isEncoded(key); } comparator(operator) { return (key, value) => { return `${key} ${operator} ${this.escape(value)}`; }; } binary(operator) { return ([left, right]) => { return `(${this.parseEval(left)} ${operator} ${this.parseEval(right)})`; }; } logicalAnd(conditions) { if (!conditions.length) return this.$true; if (conditions.includes(this.$false)) return this.$false; return conditions.join(" AND "); } logicalOr(conditions) { if (!conditions.length) return this.$false; if (conditions.includes(this.$true)) return this.$true; return `(${conditions.join(" OR ")})`; } logicalNot(condition) { return `NOT(${condition})`; } parseSelection(sel, inline = false) { const { args: [expr], ref, table, tables } = sel; const restore = this.saveState({ tables }); const inner = this.get(table, true, true); const output = this.parseEval(expr, false); const fields = expr["$select"]?.map((x) => this.getRecursive(x["$"])); const where = fields && this.logicalAnd(fields.map((x) => `(${x} is not null)`)); restore(); if (inline || !isAggrExpr(expr)) { return `(SELECT ${output} FROM ${inner} ${isBracketed(inner) ? ref : ""}${where ? ` WHERE ${where}` : ""})`; } else { return [ `(ifnull((SELECT ${this.groupArray(this.transform(output, Type.getInner(Type.fromTerm(expr)), "encode"))}`, `FROM ${inner} ${isBracketed(inner) ? ref : ""}), json_array()))` ].join(" "); } } jsonLength(value) { return this.asEncoded(`json_length(${value})`, false); } jsonContains(obj, value) { return this.asEncoded(`json_contains(${obj}, ${value})`, false); } asEncoded(value, encoded) { if (encoded !== void 0) this.state.encoded = encoded; return value; } encode(value, encoded, pure = false, type) { return this.asEncoded(encoded === this.isEncoded() && !pure ? value : encoded ? `cast(${this.transform(value, type, "encode")} as json)` : this.transform(`json_unquote(${value})`, type, "decode"), pure ? void 0 : encoded); } isEncoded(key) { return key ? this.state.encodedMap?.[key] : this.state.encoded; } createAggr(expr, aggr, nonaggr) { if (this.state.group) { this.state.group = false; const value = aggr(this.parseEval(expr, false)); this.state.group = true; return value; } else { const value = this.parseEval(expr, false); const res = nonaggr ? nonaggr(value) : `(select ${aggr(`json_unquote(${this.escapeId("value")})`)} from json_table(${value}, '$[*]' columns (value json path '$')) ${randomId()})`; return res; } } /** * Convert value from SQL field to JSON field */ transform(value, type, method, miss) { type = Type.isType(type) ? type : Type.fromTerm(type); const transformer = this.transformers[type.type] ?? this.transformers[this.driver.database.types[type.type]?.type]; return transformer?.[method] ? transformer[method](value) : miss ?? value; } groupObject(_fields) { const _groupObject = /* @__PURE__ */ __name((fields, type, prefix = "") => { const parse = /* @__PURE__ */ __name((expr, key) => { const value = !_fields[`${prefix}${key}`] && type && Type.getInner(type, key)?.inner ? _groupObject(expr, Type.getInner(type, key), `${prefix}${key}.`) : this.parseEval(expr, false); return this.isEncoded() ? `json_extract(${value}, '$')` : this.transform(value, expr, "encode"); }, "parse"); return `json_object(` + Object.entries(fields).map(([key, expr]) => `'${key}', ${parse(expr, key)}`).join(",") + `)`; }, "_groupObject"); return this.asEncoded(_groupObject(unravel(_fields), Type.fromTerm(this.state.expr), ""), true); } groupArray(value) { return this.asEncoded(`ifnull(json_arrayagg(${value}), json_array())`, true); } parseFieldQuery(key, query) { const conditions = []; if (Array.isArray(query)) { conditions.push(this.createMemberQuery(key, query)); } else if (query instanceof RegExp) { conditions.push(this.createRegExpQuery(key, query)); } else if (isComparable(query)) { conditions.push(this.createEqualQuery(key, query)); } else if (isNullable(query)) { conditions.push(this.createNullQuery(key, false)); } else { for (const prop in query) { if (prop in this.queryOperators) { conditions.push(this.queryOperators[prop](key, query[prop])); } } } return this.logicalAnd(conditions); } parseQuery(query) { const conditions = []; for (const key in query) { if (key === "$not") { conditions.push(this.logicalNot(this.parseQuery(query.$not))); } else if (key === "$and") { conditions.push(this.logicalAnd(query.$and.map(this.parseQuery.bind(this)))); } else if (key === "$or") { conditions.push(this.logicalOr(query.$or.map(this.parseQuery.bind(this)))); } else if (key === "$expr") { conditions.push(this.parseEval(query.$expr)); } else { const flattenQuery = isFlat(query[key]) ? { [key]: query[key] } : flatten(query[key], `${key}.`); for (const key2 in flattenQuery) { const model = this.state.tables[this.state.table] ?? Object.values(this.state.tables)[0]; const expr = Eval("", [this.state.table ?? Object.keys(this.state.tables)[0], key2], model.getType(key2)); conditions.push(this.parseFieldQuery(this.parseEval(expr), flattenQuery[key2])); } } } return this.logicalAnd(conditions); } parseEvalExpr(expr) { this.state.encoded = false; for (const key in expr) { if (key in this.evalOperators) { this.state.expr = expr; return this.evalOperators[key](expr[key]); } } return this.escape(expr); } transformJsonField(obj, path) { return this.asEncoded(`json_extract(${obj}, '$${path}')`, true); } transformKey(key, fields, prefix) { if (key in fields || !key.includes(".")) { return this.asEncoded(prefix + this.escapeId(key), this.isEncoded(key) ?? isSqlJson(fields[key]?.type)); } const field = Object.keys(fields).find((k) => key.startsWith(k + ".")) || key.split(".")[0]; const rest = key.slice(field.length + 1).split("."); return this.transformJsonField(`${prefix}${this.escapeId(field)}`, rest.map((key2) => `.${this.escapeKey(key2)}`).join("")); } getRecursive(args) { if (typeof args === "string") { return this.getRecursive(["_", args]); } const [table, key] = args; const fields = this.state.tables?.[table]?.fields || {}; const fkey = Object.keys(fields).find((field) => key === field || key.startsWith(field + ".")); if (fkey && fields[fkey]?.expr) { if (key === fkey) { return this.parseEvalExpr(fields[fkey]?.expr); } else { const field = this.parseEvalExpr(fields[fkey]?.expr); const rest = key.slice(fkey.length + 1).split("."); return this.transformJsonField(`${field}`, rest.map((key2) => `.${this.escapeKey(key2)}`).join("")); } } const prefix = this.modifiedTable ? `${this.escapeId(this.state.tables?.[table]?.name ?? this.modifiedTable)}.` : !this.state.tables || table === "_" || key in fields || table in this.state.tables ? "" : `${this.escapeId(table)}.`; if (!(table in (this.state.tables || {})) && table in (this.state.innerTables || {})) { const fields2 = this.state.innerTables?.[table]?.fields || {}; const res = fields2[key]?.expr ? this.parseEvalExpr(fields2[key]?.expr) : this.transformKey(key, fields2, `${this.escapeId(table)}.`); return res; } if (!(table in (this.state.tables || {})) && table in (this.state.refTables || {})) { const fields2 = this.state.refTables?.[table]?.fields || {}; const res = fields2[key]?.expr ? this.parseEvalExpr(fields2[key]?.expr) : this.transformKey(key, fields2, `${this.escapeId(table)}.`); if (this.state.wrappedSubquery) { if (res in (this.state.refFields ?? {})) return this.state.refFields[res]; const key2 = `minato_tvar_${randomId()}`; (this.state.refFields ??= {})[res] = key2; return this.asEncoded(this.escapeId(key2), true); } else return res; } return this.transformKey(key, fields, prefix); } parseEval(expr, unquote = true) { this.state.encoded = false; if (typeof expr === "string" || typeof expr === "number" || typeof expr === "boolean" || expr instanceof Date || expr instanceof RegExp) { return this.escape(expr); } return unquote ? this.encode(this.parseEvalExpr(expr), false, false, Type.fromTerm(expr)) : this.parseEvalExpr(expr); } saveState(extra = {}) { const thisState = this.state; this.state = { refTables: { ...this.state.refTables || {}, ...this.state.tables || {} }, ...extra }; return () => { thisState.encoded = this.state.encoded; this.state = thisState; }; } suffix(modifier) { const { limit, offset, sort, group, having } = modifier; let sql = ""; if (group?.length) { sql += ` GROUP BY ${group.map(this.escapeId).join(", ")}`; const filter = this.parseEval(having); if (filter !== this.$true) sql += ` HAVING ${filter}`; } if (sort.length) { sql += " ORDER BY " + sort.map(([expr, dir]) => { return `${this.parseEval(expr)} ${dir.toUpperCase()}`; }).join(", "); } if (limit < Infinity) sql += " LIMIT " + limit; if (offset > 0) sql += " OFFSET " + offset; return sql; } get(sel, inline = false, group = false, addref = true) { const { args, table, query, ref, model } = sel; this.state.table = ref; let prefix; if (typeof table === "string") { prefix = this.escapeId(table); } else if (Selection.is(table)) { prefix = this.get(table, true); if (!prefix) return; } else { this.state.innerTables = Object.fromEntries(Object.values(table).map((t) => [t.ref, t.model])); const joins = Object.entries(table).map(([key, table2]) => { const restore = this.saveState({ tables: { ...table2.tables } }); const t = `${this.get(table2, true, false, false)} AS ${this.escapeId(table2.ref)}`; restore(); return [key, t]; }); prefix = [ // the leading space is to prevent from being parsed as bracketed and added ref " ", joins[0][1], ...joins.slice(1, -1).map(([key, join]) => `${args[0].optional?.[key] ? "LEFT" : ""} JOIN ${join} ON ${this.$true}`), `${args[0].optional?.[joins.at(-1)[0]] ? "LEFT " : ""}JOIN`, joins.at(-1)[1] ].join(" "); const filter2 = this.parseEval(args[0].having); prefix += ` ON ${filter2}`; } const filter = this.parseQuery(query); if (filter === this.$false) return; this.state.group = group || !!args[0].group; const encodedMap = {}; const fields = args[0].fields ?? Object.fromEntries(Object.entries(model.fields).filter(([, field]) => Field.available(field)).map(([key, field]) => [key, field.expr ? field.expr : Eval("", [ref, key], Type.fromField(field))])); const keys = Object.entries(fields).map(([key, value]) => { value = this.parseEval(value, false); encodedMap[key] = this.state.encoded; return this.escapeId(key) === value ? this.escapeId(key) : `${value} AS ${this.escapeId(key)}`; }).join(", "); let suffix = this.suffix(args[0]); this.state.encodedMap = encodedMap; if (filter !== this.$true) { suffix = ` WHERE ${filter}` + suffix; } if (inline && !args[0].fields && !suffix && (typeof table === "string" || Selection.is(table))) { return addref && isBracketed(prefix) ? `${prefix} ${ref}` : prefix; } if (!prefix.includes(" ") || isBracketed(prefix)) { suffix = ` ${ref}` + suffix; } const result = `SELECT ${keys} FROM ${prefix}${suffix}`; return inline ? `(${result})` : result; } /** * Convert value from Type to Field.Type. * @param root indicate whether the context is inside json */ dump(value, type, root = true) { if (!type) return value; if (Type.isType(type) || isEvalExpr(type)) { type = Type.isType(type) ? type : Type.fromTerm(type); const converter = type.inner || type.type === "json" ? root ? this.driver.types["json"] : void 0 : this.driver.types[type.type]; if (type.inner || type.type === "json") root = false; let res = value; res = Type.transform(res, type, (value2, type2) => this.dump(value2, type2, root)); res = converter?.dump ? converter.dump(res) : res; const ancestor = this.driver.database.types[type.type]?.type; if (!root && !ancestor) res = this.transform(res, type, "dump"); res = this.dump(res, ancestor ? Type.fromField(ancestor) : void 0, root); return res; } value = type.format(value); const result = {}; for (const key in value) { const { type: ftype } = type.fields[key]; result[key] = this.dump(value[key], ftype); } return result; } /** * Convert value from Field.Type to Type. */ load(value, type, root = true) { if (!type) return value; if (Type.isType(type) || isEvalExpr(type)) { type = Type.isType(type) ? type : Type.fromTerm(type); const converter = this.driver.types[root && value && type.type === "json" ? "json" : type.type]; const ancestor = this.driver.database.types[type.type]?.type; let res = this.load(value, ancestor ? Type.fromField(ancestor) : void 0, root); res = this.transform(res, type, "load"); res = converter?.load ? converter.load(res) : res; res = Type.transform(res, type, (value2, type2) => this.load(value2, type2, false)); return !isNullable(res) && type.inner && !Type.isArray(type) ? unravel(res) : res; } const result = {}; for (const key in value) { if (!(key in type.fields)) continue; result[key] = value[key]; let subroot = root; if (subroot && result[key] && this.isEncoded(key)) { subroot = false; result[key] = this.driver.types["json"].load(result[key]); } result[key] = this.load(result[key], type.fields[key].type, subroot); } return type.parse(result); } /** * Convert value from Type to SQL. */ escape(value, type) { type &&= Type.fromField(type); return this.escapePrimitive(type ? this.dump(value, type) : value, type); } /** * Convert value from Field.Type to SQL. */ escapePrimitive(value, type) { if (isNullable(value)) return "NULL"; switch (typeof value) { case "boolean": case "number": case "bigint": return value + ""; case "object": return this.quote(JSON.stringify(value)); default: return this.quote(value); } } escapeId(value) { return escapeId(value); } escapeKey(value) { return `"${value}"`; } quote(value) { this.escapeRegExp ??= new RegExp(`[${Object.values(this.escapeMap).join("")}]`, "g"); let chunkIndex = this.escapeRegExp.lastIndex = 0; let escapedVal = ""; let match; while (match = this.escapeRegExp.exec(value)) { escapedVal += value.slice(chunkIndex, match.index) + this.escapeMap[match[0]]; chunkIndex = this.escapeRegExp.lastIndex; } if (chunkIndex === 0) { return "'" + value + "'"; } if (chunkIndex < value.length) { return "'" + escapedVal + value.slice(chunkIndex) + "'"; } return "'" + escapedVal + "'"; } }; export { Builder, escapeId, isBracketed, isSqlJson }; //# sourceMappingURL=index.mjs.map