import { mkdir, readFile, writeFile, copyFile } from "node:fs/promises";
import { existsSync } from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
const sourceDir = process.env.NODEDC_SOURCE_DIR || "/Users/dcconstructions/site-rescue/ssscript.app";
const targetDir = repoRoot;
const pages = ["index.html", "beta-apply.html", "founders.html", "enterprise.html"];
const assetHosts = new Set([
"cdn.prod.website-files.com",
"d3e54v103j8qbb.cloudfront.net",
"ssscript-website.vercel.app",
"ssscript.dev",
"cloud.umami.is",
]);
const assetExtensions = new Set([
".avif",
".css",
".glb",
".gif",
".jpg",
".jpeg",
".js",
".mp4",
".otf",
".png",
".svg",
".ttf",
".webm",
".webp",
".woff",
".woff2",
]);
const assetMap = new Map();
const queue = [];
const failures = [];
function cleanUrl(raw) {
let value = raw.trim();
value = value.replace(/&/g, "&");
value = value.replace(/[),.;]+$/g, "");
if (value.startsWith("//")) value = `https:${value}`;
return value;
}
function extensionFor(url) {
return path.extname(decodeURIComponent(url.pathname)).toLowerCase();
}
function isAssetUrl(url) {
if (!assetHosts.has(url.hostname)) return false;
if (url.href.includes("%7B") || url.href.includes("%7D") || url.href.includes("${")) return false;
if (url.hostname === "cdn.prod.website-files.com" && url.pathname.includes("/vendor/webflow-badge-")) return false;
if (url.hostname === "cloud.umami.is") return url.pathname === "/script.js";
return assetExtensions.has(extensionFor(url));
}
function localAssetPath(url) {
const decodedPath = decodeURIComponent(url.pathname);
const basename = path.basename(decodedPath);
const ext = path.extname(basename).toLowerCase();
if (url.hostname === "cdn.prod.website-files.com") {
if (decodedPath.includes("/css/")) return path.join("assets", "webflow", "css", basename);
if (decodedPath.includes("/js/")) return path.join("assets", "webflow", "js", basename);
return path.join("assets", "webflow", "images", basename);
}
if (url.hostname === "d3e54v103j8qbb.cloudfront.net") {
return path.join("assets", "vendor", basename);
}
if (url.hostname === "ssscript-website.vercel.app") {
if (ext === ".css") return path.join("assets", "custom", "css", basename);
if (ext === ".js") return path.join("assets", "custom", "js", basename);
return path.join("assets", "custom", basename);
}
if (url.hostname === "ssscript.dev") {
return path.join("assets", "media", basename);
}
if (url.hostname === "cloud.umami.is") {
return path.join("assets", "vendor", "umami-script.js");
}
return path.join("assets", url.hostname, basename);
}
function addAsset(rawUrl, baseUrl = undefined) {
let url;
try {
url = new URL(cleanUrl(rawUrl), baseUrl);
} catch {
return null;
}
if (!isAssetUrl(url)) return null;
const canonical = url.href;
if (!assetMap.has(canonical)) {
const localPath = localAssetPath(url);
assetMap.set(canonical, localPath);
queue.push({ url, localPath });
}
return assetMap.get(canonical);
}
function extractUrls(text) {
const urls = [];
const absoluteUrlPattern = /(?:https?:)?\/\/[^\s"'<>\\]+/g;
const cssUrlPattern = /url\((['"]?)([^'")]+)\1\)/g;
const relativeAssetPattern =
/(["'`])((?:\.{1,2}\/|\/)[^"'`?#)]+\.(?:avif|css|gif|glb|jpe?g|js|mp4|otf|png|svg|ttf|webm|webp|woff2?)(?:[?#][^"'`]*)?)\1/g;
for (const match of text.matchAll(absoluteUrlPattern)) {
urls.push(match[0]);
}
for (const match of text.matchAll(cssUrlPattern)) {
urls.push(match[2]);
}
for (const match of text.matchAll(relativeAssetPattern)) {
urls.push(match[2]);
}
return urls;
}
function rel(fromFile, toFile) {
const relative = path.relative(path.dirname(fromFile), toFile).replaceAll(path.sep, "/");
const webPath = relative.split("/").map(encodeURIComponent).join("/");
return webPath.startsWith(".") ? webPath : `./${webPath}`;
}
function pageRel(localPath) {
return `./${localPath.split(path.sep).join("/").split("/").map(encodeURIComponent).join("/")}`;
}
function rewriteUrls(text, fromLocalPath, baseUrl = undefined) {
let output = text;
const isJs = fromLocalPath.endsWith(".js");
const replacements = [...assetMap.entries()].map(([remote, local]) => {
const remoteUrl = new URL(remote);
return {
remote,
local,
relative: isJs ? pageRel(local) : rel(path.join(targetDir, fromLocalPath), path.join(targetDir, local)),
noQuery: `${remoteUrl.origin}${remoteUrl.pathname}`,
};
});
for (const item of replacements) {
output = output.split(item.remote).join(item.relative);
output = output.split(item.remote.replaceAll("&", "&")).join(item.relative);
output = output.split(item.noQuery).join(item.relative);
output = output.split(item.noQuery.replaceAll("&", "&")).join(item.relative);
}
if (baseUrl) {
output = output.replace(/url\((['"]?)([^'")]+)\1\)/g, (full, quote, value) => {
const local = addAsset(value, baseUrl);
if (!local) return full;
const localRef = isJs ? pageRel(local) : rel(path.join(targetDir, fromLocalPath), path.join(targetDir, local));
return `url(${quote}${localRef}${quote})`;
});
output = output.replace(
/(["'`])((?:\.{1,2}\/|\/)[^"'`?#)]+\.(?:avif|css|gif|glb|jpe?g|js|mp4|otf|png|svg|ttf|webm|webp|woff2?)(?:[?#][^"'`]*)?)\1/g,
(full, quote, value) => {
const local = addAsset(value, baseUrl);
if (!local) return full;
const localRef = isJs ? pageRel(local) : rel(path.join(targetDir, fromLocalPath), path.join(targetDir, local));
return `${quote}${localRef}${quote}`;
}
);
}
if (fromLocalPath.endsWith(".html")) {
output = output
.replace(/]*>/g, "")
.replace(/]*>/g, "")
.replaceAll("https://localhost:6545/app.js", "./assets/custom/js/app.js");
if (!output.includes("window.__API_ORIGIN__")) {
output = output.replace(
"