/** * Builds the HTML file that is used as the index entry for the itemize * application * * @module */ import { escapeStringRegexp } from "../util"; import colors from "colors/safe"; import htmlMinifier from "html-minifier"; import fs from "fs"; import path from "path"; import { IBuilderBasicConfigType } from "./config"; const fsAsync = fs.promises; /** * Replaces html keys that exist as some sort of template from the html * file in order to create the final output for the html * @param html the html in question * @param obj the object that is used to replace keys from (normally this is the config) * @param prefix the prefix to expect things prefixed as, this is for complex types eg. key.key... * @returns a string that represents the built html */ function replaceHTMLKeys(html: string, obj: any, prefix: string): string { // so we make the new html let newHTML = html; // and loop per key Object.keys(obj).forEach((key) => { // if we have an array, not an object, or null if (typeof obj[key] !== "object" || obj[key] === null) { // then we replace that for the value using our prefix newHTML = newHTML.replace( new RegExp(escapeStringRegexp("%{" + prefix + key + "}"), "g"), // for null we want empty string obj[key] === null ? "" : obj[key].toString(), ); } else { // then we replace that for the value using our prefix newHTML = newHTML.replace( new RegExp(escapeStringRegexp("\"%{" + prefix + key + "}\""), "g"), JSON.stringify(obj[key]), ); if (!Array.isArray(obj[key])) { // otherwise we just prefix from the prefix and the key to recurse inside newHTML = replaceHTMLKeys(newHTML, obj[key], prefix + key + "."); } } }); // return it return newHTML; } /** * Builds and stores the html file in the dist directory from the source * for the itemize app, this file also makes for the buildnumber as the buildnumber * is synchronized within the html file * @param rawConfig the configuration that is being used */ export async function buildHTML(rawConfig: IBuilderBasicConfigType) { // the base html as we read it from either node_modules or an itemize folder let baseHTML: string = await fsAsync.readFile(path.join("node_modules", "@onzag", "itemize", "client", "internal", "index.html"), "utf8"); // we need to make a build number baseHTML = replaceHTMLKeys(baseHTML, rawConfig.standard, ""); // and we minify the html baseHTML = htmlMinifier.minify( baseHTML, { collapseBooleanAttributes: true, collapseInlineTagWhitespace: true, collapseWhitespace: true, conservativeCollapse: true, removeComments: true, removeEmptyAttributes: true, removeRedundantAttributes: true, }, ); // emit the html file const fileName = path.join("dist", "data", "index.html"); console.log("emiting " + colors.green(fileName)); await fsAsync.writeFile(fileName, baseHTML); }