UNPKG

@ydbjs/query

Version:

High-level, type-safe YQL query and transaction client for YDB. Supports tagged template syntax, parameter binding, transactions, and statistics.

69 lines 2.65 kB
import { fromJs } from "@ydbjs/value"; const SymbolUnsafe = Symbol("unsafe"); function isObject(value) { return typeof value === 'object' && value !== null && !Array.isArray(value); } // Enhanced validation with detailed error messages for better debugging function validateValue(value, index) { if (value === undefined) { throw new Error(`❌ Undefined value at position ${index} in yql template. ` + `This usually means:\n` + ` • A variable wasn't initialized\n` + ` • A function returned undefined\n` + ` • An object property doesn't exist\n` + `For intentional null database values, use YDB Optional type.`); } if (value === null) { throw new Error(`❌ Null value at position ${index} in yql template. ` + `JavaScript null is not directly supported in YDB queries.\n` + `For null database values, use YDB Optional type instead.`); } } export class UnsafeString extends String { [SymbolUnsafe] = true; } export function yql(strings, ...values) { let text = ''; let params = Object.assign({}, null); // Handle simple string case if (typeof strings === 'string') { return { text: strings, params }; } // Handle template literal case if (Array.isArray(strings)) { let skipCount = 0; // Process parameters first to build params object and count skipped values values.forEach((value, i) => { // Enhanced validation with position info validateValue(value, i); if (value[SymbolUnsafe]) { skipCount++; return; } let ydbValue = isObject(value) && 'type' in value && 'kind' in value['type'] ? value : fromJs(value); params[`$p${i - skipCount}`] = ydbValue; }); // Build text with proper parameter references skipCount = 0; text = strings.reduce((prev, curr, i) => { let value = values[i]; // This should never happen due to validation above, but keep for safety if (value === undefined || value === null) { return prev + curr; } if (value[SymbolUnsafe]) { skipCount++; return prev + curr + value.toString(); } return prev + curr + `$p${i - skipCount}`; }, ''); } return { text, params }; } export function unsafe(value) { return new UnsafeString(value.toString()); } export function identifier(path) { return unsafe("`" + path + "`"); } //# sourceMappingURL=yql.js.map