UNPKG

@beignet/core

Version:

Core framework primitives for Beignet

110 lines 3.77 kB
const QUERY_VALUE_PREFIX = "~beignet-query:"; function encodeStructuredValue(value, ancestors) { if (value === null) return { type: "null" }; if (typeof value === "string") return { type: "string", value }; if (typeof value === "number" && Number.isFinite(value)) { return { type: "number", value }; } if (typeof value === "boolean") return { type: "boolean", value }; if (value instanceof Date && Number.isFinite(value.getTime())) { return { type: "date", value: value.toISOString() }; } if (typeof value !== "object" || value === null) { throw new TypeError("Query value is not serializable."); } if (ancestors.has(value)) { throw new TypeError("Query value contains a circular reference."); } ancestors.add(value); try { if (Array.isArray(value)) { return { type: "array", value: value.map((entry) => encodeStructuredValue(entry, ancestors)), }; } const prototype = Object.getPrototypeOf(value); if (prototype !== Object.prototype && prototype !== null) { throw new TypeError("Query value contains a non-plain object."); } return { type: "object", value: Object.fromEntries(Object.entries(value) .filter(([, entry]) => entry !== undefined) .map(([key, entry]) => [ key, encodeStructuredValue(entry, ancestors), ])), }; } finally { ancestors.delete(value); } } function decodeStructuredValue(value) { if (typeof value !== "object" || value === null || !("type" in value)) { throw new TypeError("Invalid encoded query value."); } const encoded = value; switch (encoded.type) { case "null": return null; case "string": if (typeof encoded.value === "string") return encoded.value; break; case "number": if (typeof encoded.value === "number" && Number.isFinite(encoded.value)) { return encoded.value; } break; case "boolean": if (typeof encoded.value === "boolean") return encoded.value; break; case "date": { if (typeof encoded.value !== "string") break; const date = new Date(encoded.value); if (Number.isFinite(date.getTime())) return date; break; } case "array": if (Array.isArray(encoded.value)) { return encoded.value.map(decodeStructuredValue); } break; case "object": if (typeof encoded.value === "object" && encoded.value !== null && !Array.isArray(encoded.value)) { return Object.fromEntries(Object.entries(encoded.value).map(([key, entry]) => [ key, decodeStructuredValue(entry), ])); } break; } throw new TypeError("Invalid encoded query value."); } export function encodeQueryValue(value) { if (typeof value === "string" && !value.startsWith(QUERY_VALUE_PREFIX)) { return value; } return `${QUERY_VALUE_PREFIX}${JSON.stringify(encodeStructuredValue(value, new Set()))}`; } export function decodeQueryValue(value) { if (!value.startsWith(QUERY_VALUE_PREFIX)) return value; try { return decodeStructuredValue(JSON.parse(value.slice(QUERY_VALUE_PREFIX.length))); } catch { return value; } } //# sourceMappingURL=query-codec.js.map