import { mkdir, readFile, writeFile } from "node:fs/promises"; import { dirname, join } from "node:path"; import { fileURLToPath } from "node:url"; const repoRoot = join(dirname(fileURLToPath(import.meta.url)), ".."); const sourcePath = join(repoRoot, "index.html"); const templateRoot = join(repoRoot, "templates", "pages", "home"); const blockRoot = join(templateRoot, "blocks"); const contentPath = join(repoRoot, "content", "pages", "home.json"); const html = await readFile(sourcePath, "utf8"); const marker = { hero: '
', features: '
', cViz: '
', pricingIntro: '
', waitlistFiles: '
', demoVideoFolder: '
', footer: '", footerStart) + "".length; const shell = [ html.slice(0, heroStart), "{{NODEDC_BLOCKS_BEFORE_CVIZ}}", html.slice(cVizStart, cVizOpenEnd), "{{NODEDC_BLOCKS_CVIZ}}", html.slice(footerEnd), ].join(""); const blocks = [ { region: "beforeCViz", id: "hero-waitlist", type: "staticHtml", template: "hero-waitlist.html", adminLabel: "Первый экран и заявка", anchor: "hero", html: html.slice(heroStart, featuresStart), }, { region: "beforeCViz", id: "feature-video", type: "staticHtml", template: "feature-video.html", adminLabel: "Демо и базовая логика", anchor: "features", html: html.slice(featuresStart, cVizStart), }, { region: "cViz", id: "product-system", type: "staticHtml", template: "product-system.html", adminLabel: "Компоненты, режимы, FAQ и тарифная таблица", anchor: null, html: html.slice(cVizOpenEnd, pricingIntroStart), }, { region: "cViz", id: "pricing-intro", type: "staticHtml", template: "pricing-intro.html", adminLabel: "Интро тарифов", anchor: "waitlist", html: html.slice(pricingIntroStart, waitlistFilesStart), }, { region: "cViz", id: "waitlist-files", type: "staticHtml", template: "waitlist-files.html", adminLabel: "Форма ожидания и txt-файлы", anchor: "waitlist", html: html.slice(waitlistFilesStart, demoVideoFolderStart), }, { region: "cViz", id: "demo-video-folder", type: "staticHtml", template: "demo-video-folder.html", adminLabel: "Иконка демо-видео в доке", anchor: null, html: html.slice(demoVideoFolderStart, footerStart), }, { region: "cViz", id: "footer", type: "staticHtml", template: "footer.html", adminLabel: "Футер", anchor: null, html: html.slice(footerStart, footerEnd), }, ]; const page = { schemaVersion: 1, slug: "home", output: "index.html", title: "NODE.DC", seo: { title: "NODE.DC — ИИ-платформа для Webflow", description: "Единая платформа для кастомного кода, MCP и ИИ-агентов в Webflow: контекст проекта, автоматизация, деплой и управляемая разработка.", }, regions: [ { id: "beforeCViz", label: "До c-viz wrapper", description: "Hero and first product section. These blocks live before the visual wrapper.", blocks: blocks .filter((block) => block.region === "beforeCViz") .map(({ html: _html, ...block }) => ({ ...block, enabled: true })), }, { id: "cViz", label: "Inside c-viz wrapper", description: "Sections coupled to WebGL/color-flip shell. Keep these in this region for now.", blocks: blocks .filter((block) => block.region === "cViz") .map(({ html: _html, ...block }) => ({ ...block, enabled: true })), }, ], }; await mkdir(blockRoot, { recursive: true }); await mkdir(dirname(contentPath), { recursive: true }); await writeFile(join(templateRoot, "shell.html"), shell); for (const block of blocks) { await writeFile(join(blockRoot, block.template), block.html); } await writeFile(contentPath, `${JSON.stringify(page, null, 2)}\n`); console.log(`Extracted ${blocks.length} blocks from ${sourcePath}`); console.log(`Wrote ${join(templateRoot, "shell.html")}`); console.log(`Wrote ${contentPath}`);