import Mustache from "mustache"; import { VariableView } from "./VariableView"; import { hasValidMustacheTags } from "./helperFunctions"; type MustacheIterationOptions = { maxPasses?: number; detectCycles?: boolean; }; /** * Replaces all mustache tokens recursively until there are none left that can be replaced. * @param template * @param param1 * @returns */ export function replaceAllMustaches( template: string, { maxPasses = 20, detectCycles = true }: MustacheIterationOptions = {}, ): string { let current = template; let last = ""; // To ensure that the same token isn't replaced twice in a row for (let pass = 0; pass < maxPasses; pass += 1) { if (hasValidMustacheTags(current)){ // If any {{}} remain... if (detectCycles) { // If you check the number of cycles, which you do by default, throw an error and stop if (last === current) { throw new Error(`Render cycle detected at pass ${pass}: "${current}"`); }; last = current; // Now the string it's looping over will be checked next time }; const next = Mustache.render(current, VariableView.all); // If the string's not the same as the current string, set it as the new template and re-loop if (next !== current){ current = next; } else { return current; // no more substitutions happened } } else { console.log("passes:",pass) return current; } }; return current; };