import { log } from "console" /** * Flattens an object into a 1 level deep object. * { a: { b: 1, c: 2 } } --> { "a.b": 1, "a.c": 2 } * @param {Object} object * @return {Object} */ function flattenObject(object) { let finalObject = {} for (const key in object) { // Skip if key isn't own. if (!Object.prototype.hasOwnProperty.call(object, key)) continue if (typeof object[key] === "object" && object[key] !== null) { const flattenedObject = flattenObject(object[key]) for (const innerKey in flattenedObject) { // Skip if key isn't own. if (!Object.prototype.hasOwnProperty.call(flattenedObject, innerKey)) continue finalObject[`${key}.${innerKey}`] = flattenedObject[innerKey] } } else { finalObject[key] = object[key] } } return finalObject } export default function parseTemplate(template, data) { const flattenedData = flattenObject(data) if (process.env.NODE_ENV === "debug") log(flattenedData) return template // Syntax: {{ variableName }} // Does: Inserts a variable, if it exists. .replace( /{{\s*(\S+?)\s*}}/gm, (match, variableName) => { if (flattenedData[variableName] === undefined || flattenedData[variableName] === null) { throw new Error(`Error: "${variableName}" is not defined`) } return flattenedData[variableName] } ) // Syntax: // {% if variableName %} // // {% endif %} // Does: includes if variableName exists and is true. .replace( /^{%\s*if\s*(\S+?)\s*%}$([\s\S]*?)^{%\s*endif\s*%}$/gm, (match, variableName, codeBlock) => { if (flattenedData[variableName] === undefined || flattenedData[variableName] === null) { throw new Error(`Error: "${variableName}" is not defined`) } return flattenedData[variableName] ? codeBlock : "" } ) }