UNPKG

jsonblade

Version:

A powerful and modular JSON template engine with extensible filters

134 lines 6.04 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.initializeFilters = initializeFilters; exports.compileJSONTemplateAsync = compileJSONTemplateAsync; exports.evaluateExpressionAsync = evaluateExpressionAsync; const filter_registry_1 = require("./filter-registry"); const async_filter_registry_1 = require("./async-filter-registry"); const string_filters_1 = require("./filters/string-filters"); const array_filters_1 = require("./filters/array-filters"); const object_filters_1 = require("./filters/object-filters"); const logic_filters_1 = require("./filters/logic-filters"); const date_filters_1 = require("./filters/date-filters"); const number_filters_1 = require("./filters/number-filters"); const validation_filters_1 = require("./filters/validation-filters"); const template_config_1 = require("./template-config"); const json_template_utils_1 = require("./json-template.utils"); let filtersInitialized = false; function initializeFilters() { if (filtersInitialized) return; (0, string_filters_1.registerStringFilters)(); (0, array_filters_1.registerArrayFilters)(); (0, object_filters_1.registerObjectFilters)(); (0, logic_filters_1.registerLogicFilters)(); (0, date_filters_1.registerDateFilters)(); (0, number_filters_1.registerNumberFilters)(); (0, validation_filters_1.registerValidationFilters)(); // Initialize async filters const { registerAsyncFilters } = require("./filters/async-filters"); registerAsyncFilters(); filtersInitialized = true; } async function compileJSONTemplateAsync(template, data) { initializeFilters(); const stringInterpolated = await processStringInterpolations(template, data); const fullyInterpolated = await processDirectInterpolations(stringInterpolated, data); return fullyInterpolated; } async function processStringInterpolations(template, data) { const stringMatches = Array.from(template.matchAll(/"([^"]*)"/g)); let result = template; for (const match of stringMatches) { const [fullMatch, content] = match; if (!content.includes("{{")) { continue; } const interpolated = await processInterpolationsInString(content, data); result = result.replace(fullMatch, `"${interpolated}"`); } return result; } async function processInterpolationsInString(content, data) { const expressionMatches = Array.from(content.matchAll(/{{\s*([^}]+)\s*}}/g)); let result = content; for (const match of expressionMatches) { const [fullMatch, expr] = match; const value = await evaluateExpressionAsync(expr.trim(), data); const stringValue = value == null ? "" : String(value); result = result.replace(fullMatch, stringValue); } return result; } async function processDirectInterpolations(template, data) { const expressionMatches = Array.from(template.matchAll(/{{\s*([^}]+)\s*}}/g)); let result = template; for (const match of expressionMatches) { const [fullMatch, expr] = match; const value = await evaluateExpressionAsync(expr.trim(), data); const jsonValue = JSON.stringify(value ?? null); result = result.replace(fullMatch, jsonValue); } return result; } async function evaluateExpressionAsync(expr, data) { // Make sure filters are initialized initializeFilters(); const parts = expr.split("|").map((p) => p.trim()); const [rawPath, ...filterParts] = parts; let value = (0, json_template_utils_1.getObjectPath)(rawPath, data); for (const part of filterParts) { const match = part.match(/^(\w+)(?:\((.*?)\))?$/); if (!match) continue; const [, name, argsString] = match; // Check if it's an async filter first if ((0, async_filter_registry_1.hasAsyncFilter)(name)) { const asyncFn = (0, async_filter_registry_1.getAsyncFilter)(name); if (asyncFn) { try { let args = []; if (argsString) { args = parseFilterArguments(argsString, data); } value = await asyncFn(value, ...args); continue; } catch (error) { const config = (0, template_config_1.getTemplateConfig)(); const templateError = (0, template_config_1.createTemplateError)("FILTER_ERROR", `Async filter '${name}' failed: ${error instanceof Error ? error.message : "Unknown error"}`, { filter: name, expression: expr }); (0, template_config_1.handleTemplateError)(templateError, config); continue; } } } // Otherwise, use regular filter const fn = (0, filter_registry_1.getFilter)(name); if (!fn) { const config = (0, template_config_1.getTemplateConfig)(); const error = (0, template_config_1.createTemplateError)("UNKNOWN_FILTER", `Unknown filter: ${name}`, { filter: name, expression: expr }); (0, template_config_1.handleTemplateError)(error, config); continue; } let args = []; if (argsString) { args = parseFilterArguments(argsString, data); } value = fn(value, ...args); } return value; } function parseFilterArguments(argsString, data) { const { getObjectPath } = require("./json-template.utils"); return argsString.split(",").map((arg) => { const trimmed = arg.trim(); if ((trimmed.startsWith('"') && trimmed.endsWith('"')) || (trimmed.startsWith("'") && trimmed.endsWith("'"))) { return trimmed.slice(1, -1); } // Try to resolve as data path first, fallback to literal string const pathValue = getObjectPath(trimmed, data); return pathValue !== null && pathValue !== undefined ? pathValue : trimmed; }); } //# sourceMappingURL=async-json-template.utils.js.map