import { mkdirSync, readFileSync, writeFileSync } from "node:fs"; import { basename, dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; const root = dirname(fileURLToPath(import.meta.url)); const frontendRoot = join(root, ".."); const exactRoot = join(frontendRoot, "public", "exact"); const outFile = join(frontendRoot, "src", "routes", "exact-html.ts"); const componentRoot = join(frontendRoot, "src", "routes", "exact-pages"); const pages = [ ["account", "account.html"], ["assetFactory", "asset-factory.html"], ["dashboard", "index.html"], ["imageOptimize", "image-optimize.html"], ["library", "library.html"], ["login", "login.html"], ["messages", "messages.html"], ["modelPhoto", "model-photo.html"], ["modelPhotoDemoA", "model-photo-demo-a.html"], ["modelPhotoDemoB", "model-photo-demo-b.html"], ["pipeline", "pipeline.html"], ["platformCover", "platform-cover.html"], ["productCreate", "product-create.html"], ["productCreateUpload", "product-create-upload.html"], ["productDetail", "product-detail.html"], ["products", "products.html"], ["projectWizard", "projects-new.html"], ["projects", "projects.html"], ["register", "register.html"], ["settings", "settings.html"], ["team", "team.html"] ]; function normalizeDocument(html, fileName) { const withMeta = html.replace( //i, `\n` ); return withMeta .replace(/(src|href)="assets\//g, '$1="/exact/assets/') .replace(/url\((['"]?)assets\//g, "url($1/exact/assets/") .replace( "history.replaceState(null, '', '#' + id);", "try { window.location.hash = id; } catch (e) {}" ); } mkdirSync(dirname(outFile), { recursive: true }); mkdirSync(componentRoot, { recursive: true }); const entries = pages .map(([key, fileName]) => { const html = normalizeDocument(readFileSync(join(exactRoot, fileName), "utf8"), fileName); return ` ${JSON.stringify(key)}: ${JSON.stringify(html)}`; }) .join(",\n"); const keys = pages.map(([key]) => JSON.stringify(key)).join(" | "); writeFileSync( outFile, `/* This file is generated by scripts/generate-exact-html.mjs. Do not edit by hand. */\n` + `export type ExactHtmlKey = ${keys};\n\n` + `export const exactHtmlDocuments: Record = {\n${entries}\n};\n`, "utf8" ); function toPascalCase(value) { return value .replace(/([a-z0-9])([A-Z])/g, "$1-$2") .split(/[-_]/) .filter(Boolean) .map((part) => part.charAt(0).toUpperCase() + part.slice(1)) .join(""); } for (const [key] of pages) { const componentName = `Exact${toPascalCase(key)}Page`; const fileName = `${key.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase()}.tsx`; writeFileSync( join(componentRoot, fileName), `/* Generated by scripts/generate-exact-html.mjs. Do not edit by hand. */\n` + `import { ExactDocumentPage } from "../exact-document";\n` + `import type { ExactDocumentPageProps } from "../exact-document";\n\n` + `export function ${componentName}(props: Omit) {\n` + ` return ;\n` + `}\n\n` + `export default ${componentName};\n`, "utf8" ); } console.log(`generated ${pages.length} exact documents -> ${outFile}`);