tscircuit/ti
ti tscircuit library
- Version
- 1.0.194
- License
- unset
- Stars
- 0
system-block-ui/scripts/inline-standalone.ts
import { readFile, rm, writeFile } from "node:fs/promises";
import path from "node:path";
import { fileURLToPath } from "node:url";
const packageRoot = fileURLToPath(new URL("..", import.meta.url));
const stageDirectory = path.join(packageRoot, "dist", ".standalone-stage");
const outputPath = path.join(
packageRoot,
"dist",
"ti-system-block-builder.html",
);
const sourceHtml = await readFile(
path.join(stageDirectory, "index.html"),
"utf8",
);
const moduleScript = sourceHtml.match(
/<script\b[^>]*\btype="module"[^>]*\bsrc="([^"]+)"[^>]*><\/script>/,
);
const stylesheet = sourceHtml.match(
/<link\b[^>]*\brel="stylesheet"[^>]*\bhref="([^"]+)"[^>]*>/,
);
if (!moduleScript || !stylesheet) {
throw new Error("The Vite entry script or stylesheet could not be located.");
}
const readStageAsset = (assetUrl: string) =>
readFile(path.join(stageDirectory, assetUrl.replace(/^\.\//, "")), "utf8");
const [javascript, css] = await Promise.all([
readStageAsset(moduleScript[1]),
readStageAsset(stylesheet[1]),
]);
if (css.toLowerCase().includes("</style")) {
throw new Error("The generated CSS contains an unsafe closing style tag.");
}
const safeJavascript = javascript.replace(/<\/script/gi, "<\\/script");
const standaloneHtml = sourceHtml
.replace(
moduleScript[0],
() => `<script type="module">\n${safeJavascript}\n</script>`,
)
.replace(stylesheet[0], () => `<style>\n${css}\n</style>`)
.replace(
"<!doctype html>",
"<!doctype html>\n<!-- Self-contained TI System Block Builder -->",
);
const documentShell = standaloneHtml
.replace(
/<script type="module">[\s\S]*?<\/script>/,
'<script type="module"></script>',
)
.replace(/<style>[\s\S]*?<\/style>/, "<style></style>");
const remainingExternalAsset = documentShell.match(
/<(?:script\b[^>]*\bsrc|link\b[^>]*\brel="stylesheet")[^>]*>/i,
);
if (remainingExternalAsset) {
throw new Error(
`The standalone HTML still contains an external entry asset: ${remainingExternalAsset[0]}`,
);
}
await writeFile(outputPath, standaloneHtml);
await rm(stageDirectory, { recursive: true, force: true });
console.log(`Standalone HTML: ${outputPath}`);