UNPKG

@naturalcycles/js-lib

Version:

Standard library for universal (browser + Node.js) javascript

56 lines (51 loc) 1.92 kB
/* Vendored: https://github.com/sindresorhus/pupa (c) Sindre Sorhus Reasons: 1. Stable enough to be included in "core" js-lib 2. ESM-only */ import { htmlEscape } from './escape.js'; export class MissingValueError extends Error { key; constructor(key) { super(`Missing a value for ${key ? `the placeholder: ${key}` : 'a placeholder'}`); this.key = key; this.name = 'MissingValueError'; } } /** * API: https://github.com/sindresorhus/pupa */ export function pupa(template, data, opt = {}) { if (typeof template !== 'string') { throw new TypeError(`Expected a \`string\` in the first argument, got \`${typeof template}\``); } if (typeof data !== 'object') { throw new TypeError(`Expected an \`object\` or \`Array\` in the second argument, got \`${typeof data}\``); } const { ignoreMissing = false, transform = ({ value }) => value } = opt; const replace = (placeholder, key) => { let value = data; for (const property of key.split('.')) { value = value ? value[property] : undefined; } const transformedValue = transform({ value, key }); if (transformedValue === undefined) { if (ignoreMissing) { return placeholder; } throw new MissingValueError(key); } return String(transformedValue); }; const composeHtmlEscape = (replacer) => (...args) => htmlEscape(replacer(...args)); // The regex tries to match either a number inside `{{ }}` or a valid JS identifier or key path. const doubleBraceRegex = /{{(\d+|[a-z$_][\w\-$]*?(?:\.[\w\-$]*?)*?)}}/gi; if (doubleBraceRegex.test(template)) { template = template.replaceAll(doubleBraceRegex, composeHtmlEscape(replace)); } const braceRegex = /{(\d+|[a-z$_][\w\-$]*?(?:\.[\w\-$]*?)*?)}/gi; return template.replaceAll(braceRegex, replace); }