@planetscale/database
Version:
A Fetch API-compatible PlanetScale database driver
74 lines (73 loc) • 1.93 kB
JavaScript
import { uint8ArrayToHex } from './text.js';
export function format(query, values) {
return Array.isArray(values) ? replacePosition(query, values) : replaceNamed(query, values);
}
function replacePosition(query, values) {
let index = 0;
return query.replace(/\?/g, (match) => {
return index < values.length ? sanitize(values[index++]) : match;
});
}
function replaceNamed(query, values) {
return query.replace(/:(\w+)/g, (match, name) => {
return hasOwn(values, name) ? sanitize(values[name]) : match;
});
}
function hasOwn(obj, name) {
return Object.prototype.hasOwnProperty.call(obj, name);
}
function sanitize(value) {
if (value == null) {
return 'null';
}
if (['number', 'bigint'].includes(typeof value)) {
return String(value);
}
if (typeof value === 'boolean') {
return value ? 'true' : 'false';
}
if (typeof value === 'string') {
return quote(value);
}
if (Array.isArray(value)) {
return value.map(sanitize).join(', ');
}
if (value instanceof Date) {
return quote(value.toISOString().slice(0, -1));
}
if (value instanceof Uint8Array) {
return uint8ArrayToHex(value);
}
return quote(value.toString());
}
function quote(text) {
return `'${escape(text)}'`;
}
const re = /[\0\b\n\r\t\x1a\\"']/g;
function escape(text) {
return text.replace(re, replacement);
}
function replacement(text) {
switch (text) {
case '"':
return '\\"';
case "'":
return "\\'";
case '\n':
return '\\n';
case '\r':
return '\\r';
case '\t':
return '\\t';
case '\\':
return '\\\\';
case '\0':
return '\\0';
case '\b':
return '\\b';
case '\x1a':
return '\\Z';
default:
return '';
}
}