UNPKG

sqlite-prepare

Version:

A type-safe SQL query builder for Cloudflare D1

112 lines (111 loc) 3.98 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.raw = raw; exports.build = build; exports.prepare = prepare; function raw(stringsOrValue, ...values) { // Handle tagged template literal case if (typeof stringsOrValue !== 'string') { let result = ''; stringsOrValue.forEach((str, i) => { result += str + (values[i] !== undefined ? values[i] : ''); }); return { __raw: true, value: result }; } // Handle regular function call case return { __raw: true, value: stringsOrValue }; } /** * Builds a SQL query with parameterized values * * @param strings - SQL query string with placeholders or template strings array * @param values - Values to interpolate into the query * @returns A SQLQuery object with the query string and parameters * * @example * // Using a template literal * const userId = 123; * const query = build`SELECT * FROM users WHERE id = ${userId}`; * * @example * // Using an array for IN clause * const roleIds = [1, 2, 3]; * const query = build`SELECT * FROM users WHERE role_id IN ${roleIds}`; * * @example * // Using a raw SQL fragment * const query = build`SELECT * FROM users WHERE ${raw('created_at > NOW()')}`; * * @example * // Using a subquery * const subquery = build`SELECT id FROM active_users`; * const query = build`SELECT * FROM users WHERE id IN ${subquery}`; */ function build(strings, ...values) { let query; let params = []; // Handle regular string with question marks if (typeof strings === 'string') { query = strings; params = values; } else { // Handle template literals case query = ''; for (let i = 0; i < strings.length; i++) { query += strings[i]; if (i < values.length) { const value = values[i]; // Check for various formats if (Array.isArray(value)) { // Handle arrays for IN clauses if (value.length === 0) { // Empty IN clause is usually a logical error, but can be handled query += '(NULL)'; } else { query += '(' + value.map(() => '?').join(', ') + ')'; params.push(...value); } } else if (value && typeof value === 'object') { if ('__raw' in value && value.__raw === true) { // Raw SQL query += value.value; } else if ('query' in value && 'params' in value) { // Handle nested SQLQuery objects (subqueries) query += '(' + value.query + ')'; params.push(...value.params); } else if (value instanceof Date) { // Handle Date objects specially query += '?'; params.push(value); } else if (value instanceof Uint8Array || value instanceof ArrayBuffer) { // Handle binary data specially query += '?'; params.push(value); } else { // Regular object - stringify for JSON storage query += '?'; params.push(JSON.stringify(value)); } } else { // Regular value query += '?'; params.push(value); } } } } return { query, params }; } ; function prepare(db, stringOrStrings, ...values) { const q = build(stringOrStrings, ...values); return db.prepare(q.query).bind(...(q.params)); }