95 lines
3.3 KiB
JavaScript
95 lines
3.3 KiB
JavaScript
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(
|
|
/<head>/i,
|
|
`<head>\n<meta name="x-airshelf-exact-source" content="${basename(fileName)}">`
|
|
);
|
|
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<ExactHtmlKey, string> = {\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<ExactDocumentPageProps, "pageKey">) {\n` +
|
|
` return <ExactDocumentPage {...props} pageKey=${JSON.stringify(key)} />;\n` +
|
|
`}\n\n` +
|
|
`export default ${componentName};\n`,
|
|
"utf8"
|
|
);
|
|
}
|
|
|
|
console.log(`generated ${pages.length} exact documents -> ${outFile}`);
|