UNPKG

@ffsm/serialize

Version:
176 lines (175 loc) 6.68 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import Nullish from '@ffsm/nullish'; import { get } from './get'; /** * Asynchronously replaces variable placeholders in a string with corresponding values. * * This function takes a template string with variable placeholders in the format * `{variableName}` and replaces them with values from the provided params object. * It supports deep property access using dot notation and asynchronous formatting. * * @param text - The template string containing variables in the format `{variableName}` * @param options - Configuration options including parameters and formatters * @param options.params - An object containing values to replace variables * @param options.format - An object mapping variable names to formatter functions (can be async) * @returns A Promise resolving to the text with all variables replaced * * @example * ```typescript * // Basic usage * await variableAsync('Hello, {name}!', { * params: { name: 'John' } * }); * // 'Hello, John!' * * // Deep property access * await variableAsync('User: {user.profile.name}, Age: {user.profile.age}', { * params: { * user: { * profile: { * name: 'Alice', * age: 30 * } * } * } * }); * // 'User: Alice, Age: 30' * * // With async formatters * await variableAsync('User status: {userId}', { * params: { userId: 1234 }, * format: { * userId: async (id) => { * const response = await fetch(`/api/users/${id}`); * const user = await response.json(); * return `${user.name} (${user.status})`; * } * } * }); * // 'User status: John Doe (active)' * * // Parallel processing of multiple variables * await variableAsync('Weather: {city1}, {city2}, {city3}', { * params: { city1: 'New York', city2: 'London', city3: 'Tokyo' }, * format: { * city1: async (city) => await getWeather(city), * city2: async (city) => await getWeather(city), * city3: async (city) => await getWeather(city) * } * }); * // Processes all weather requests in parallel * ``` * * @see variable - Synchronous version for simpler use cases */ export function variableAsync(text_1) { return __awaiter(this, arguments, void 0, function* (text, options = {}) { if (Nullish.isNullishOrEmpty(text)) { return ''; } const params = Nullish.nullish(options.params, {}); const matches = Array.from(Nullish.nullish(text.match(/{\s*[\w._-]+\s*}/g), [])); if (Nullish.isNullishOrEmpty(matches)) { return Promise.resolve(text); } const serialized = yield Promise.all(matches.map((match) => __awaiter(this, void 0, void 0, function* () { var _a; const key = match.replace(/[{}]/g, '').trim(); let value = Nullish.nullish(get(params, key), ''); if (!Nullish.isNullishOrEmpty((_a = options.format) === null || _a === void 0 ? void 0 : _a[key])) { value = yield options.format[key](value); } return { key, match, value: Nullish.nullish(value === null || value === void 0 ? void 0 : value.toString(), ''), }; }))); serialized.forEach((item) => (text = text.replace(new RegExp(`\\{\\s*${item.key}\\s*\\}`, 'g'), item.value))); return text; }); } /** * Replaces variable placeholders in a string with corresponding values. * * This function takes a template string with variable placeholders in the format * `{variableName}` and replaces them with values from the provided params object. * It supports deep property access using dot notation and synchronous formatting. * * @param text - The template string containing variables in the format `{variableName}` * @param options - Configuration options including parameters and formatters * @param options.params - An object containing values to replace variables * @param options.format - An object mapping variable names to synchronous formatter functions * @returns The text with all variables replaced * * @example * ```typescript * // Basic usage * variable('Hello, {name}!', { * params: { name: 'John' } * }); * // 'Hello, John!' * * // Deep property access * variable('User: {user.profile.name}, Age: {user.profile.age}', { * params: { * user: { * profile: { * name: 'Alice', * age: 30 * } * } * } * }); * // 'User: Alice, Age: 30' * * // With formatters * variable('Created: {date}', { * params: { date: '2023-04-15' }, * format: { * date: (value) => new Date(value).toLocaleDateString() * } * }); * // 'Created: 4/15/2023' (format depends on locale) * * // Multiple occurrences of the same variable * variable('Welcome, {username}! Your username is {username}.', { * params: { username: 'user123' } * }); * // 'Welcome, user123! Your username is user123.' * * // Missing variables are replaced with empty string * variable('Hello, {name}!', { params: {} }); * // 'Hello, !' * ``` * * @see variableAsync - Asynchronous version that supports async formatters */ export function variable(text, options = {}) { if (Nullish.isNullishOrEmpty(text)) { return ''; } const params = Nullish.nullish(options.params, {}); const matches = Array.from(Nullish.nullish(text.match(/{\s*[\w._-]+\s*}/g), [])); if (Nullish.isNullishOrEmpty(matches)) { return text; } matches.forEach((match) => { var _a, _b; const key = match.replace(/[{}]/g, '').trim(); let value = Nullish.nullish(get(params, key), ''); if (!Nullish.isNullishOrEmpty((_a = options.format) === null || _a === void 0 ? void 0 : _a[key])) { value = options.format[key](value); } text = text.replace(new RegExp(`\\{\\s*${key}\\s*\\}`, 'g'), (_b = value === null || value === void 0 ? void 0 : value.toString()) !== null && _b !== void 0 ? _b : ''); }); return text; }