import { log, error } 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) return template // Syntax: {{ variableName }} // Does: Inserts a variable, if it exists. .replace( /{{\s*(.+)\s*}}/gm, (match, variableName) => { if (flattenedData[variableName] === undefined || flattenedData[variableName] === null) { error(`Error: ${variableName} is not defined!`) process.exit(1) } log(`${variableName} = ${flattenedData[variableName]}`) return flattenedData[variableName] } ) // Syntax: // {% if variableName %} // // {% endif %} // Does: includes if variableName exists and is true. .replace( /^{%\s*if\s*(.+)\s*%}$([\s\S]*?)^{%\s*endif\s*%}$/gm, (match, variableName, codeBlock) => { if (flattenedData[variableName] === undefined || flattenedData[variableName] === null) { error(`Error: ${variableName} is not defined!`) process.exit(1) } log(`${variableName} = ${flattenedData[variableName]}`) return flattenedData[variableName] ? codeBlock : "" } ) }