@see-ms/converter 0.1.3 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +176 -28
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
import pc4 from "picocolors";
|
|
6
6
|
import * as readline2 from "readline";
|
|
7
|
+
import fs11 from "fs-extra";
|
|
8
|
+
import path13 from "path";
|
|
7
9
|
|
|
8
10
|
// src/converter.ts
|
|
9
11
|
import pc3 from "picocolors";
|
|
@@ -1244,13 +1246,55 @@ import fs10 from "fs-extra";
|
|
|
1244
1246
|
import path12 from "path";
|
|
1245
1247
|
import { glob as glob2 } from "glob";
|
|
1246
1248
|
import * as readline from "readline";
|
|
1249
|
+
var ENV_FILE = ".env";
|
|
1250
|
+
async function loadConfig(projectDir) {
|
|
1251
|
+
const envPath = path12.join(projectDir, ENV_FILE);
|
|
1252
|
+
if (await fs10.pathExists(envPath)) {
|
|
1253
|
+
try {
|
|
1254
|
+
const content = await fs10.readFile(envPath, "utf-8");
|
|
1255
|
+
const config = {};
|
|
1256
|
+
for (const line of content.split("\n")) {
|
|
1257
|
+
const trimmed = line.trim();
|
|
1258
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
1259
|
+
const [key, ...valueParts] = trimmed.split("=");
|
|
1260
|
+
const value = valueParts.join("=").trim();
|
|
1261
|
+
if (key === "STRAPI_API_TOKEN") {
|
|
1262
|
+
config.apiToken = value;
|
|
1263
|
+
} else if (key === "STRAPI_URL") {
|
|
1264
|
+
config.strapiUrl = value;
|
|
1265
|
+
}
|
|
1266
|
+
}
|
|
1267
|
+
return config;
|
|
1268
|
+
} catch {
|
|
1269
|
+
return {};
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
return {};
|
|
1273
|
+
}
|
|
1274
|
+
async function saveConfig(projectDir, config) {
|
|
1275
|
+
const envPath = path12.join(projectDir, ENV_FILE);
|
|
1276
|
+
let content = "";
|
|
1277
|
+
if (await fs10.pathExists(envPath)) {
|
|
1278
|
+
content = await fs10.readFile(envPath, "utf-8");
|
|
1279
|
+
content = content.split("\n").filter((line) => !line.startsWith("STRAPI_API_TOKEN=") && !line.startsWith("STRAPI_URL=")).join("\n");
|
|
1280
|
+
if (content && !content.endsWith("\n")) {
|
|
1281
|
+
content += "\n";
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
if (config.strapiUrl) {
|
|
1285
|
+
content += `STRAPI_URL=${config.strapiUrl}
|
|
1286
|
+
`;
|
|
1287
|
+
}
|
|
1288
|
+
if (config.apiToken) {
|
|
1289
|
+
content += `STRAPI_API_TOKEN=${config.apiToken}
|
|
1290
|
+
`;
|
|
1291
|
+
}
|
|
1292
|
+
await fs10.writeFile(envPath, content);
|
|
1293
|
+
}
|
|
1247
1294
|
async function completeSetup(options) {
|
|
1248
|
-
const {
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
strapiUrl = "http://localhost:1337",
|
|
1252
|
-
apiToken
|
|
1253
|
-
} = options;
|
|
1295
|
+
const { projectDir, strapiDir, strapiUrl: optionUrl, apiToken: optionToken, ignoreSavedToken } = options;
|
|
1296
|
+
const savedConfig = await loadConfig(projectDir);
|
|
1297
|
+
const strapiUrl = optionUrl || savedConfig.strapiUrl || "http://localhost:1337";
|
|
1254
1298
|
console.log("\u{1F680} Starting complete Strapi setup...\n");
|
|
1255
1299
|
console.log("\u{1F4E6} Step 1: Installing schemas...");
|
|
1256
1300
|
await installSchemas(projectDir, strapiDir);
|
|
@@ -1267,16 +1311,23 @@ async function completeSetup(options) {
|
|
|
1267
1311
|
process.exit(1);
|
|
1268
1312
|
}
|
|
1269
1313
|
console.log("\u2713 Connected to Strapi\n");
|
|
1270
|
-
let token = apiToken;
|
|
1271
|
-
if (!
|
|
1314
|
+
let token = optionToken || (!ignoreSavedToken ? savedConfig.apiToken : void 0);
|
|
1315
|
+
if (token && !ignoreSavedToken) {
|
|
1316
|
+
console.log("\u{1F511} Step 4: Using saved API token");
|
|
1317
|
+
} else if (token && optionToken) {
|
|
1318
|
+
console.log("\u{1F511} Step 4: Using provided API token");
|
|
1319
|
+
} else {
|
|
1272
1320
|
console.log("\u{1F511} Step 4: API Token needed");
|
|
1273
1321
|
console.log(" 1. Open Strapi admin: http://localhost:1337/admin");
|
|
1274
1322
|
console.log(" 2. Go to Settings > API Tokens > Create new API Token");
|
|
1275
|
-
console.log(
|
|
1276
|
-
' 3. Name: "Seed Script", Type: "Full access", Duration: "Unlimited"'
|
|
1277
|
-
);
|
|
1323
|
+
console.log(' 3. Name: "Seed Script", Type: "Full access", Duration: "Unlimited"');
|
|
1278
1324
|
console.log(" 4. Copy the token and paste it here:\n");
|
|
1279
1325
|
token = await promptForToken();
|
|
1326
|
+
const saveToken = await promptYesNo(" Save token for future use?");
|
|
1327
|
+
if (saveToken) {
|
|
1328
|
+
await saveConfig(projectDir, { ...savedConfig, apiToken: token, strapiUrl });
|
|
1329
|
+
console.log(" \u2713 Token saved to .env");
|
|
1330
|
+
}
|
|
1280
1331
|
console.log("");
|
|
1281
1332
|
}
|
|
1282
1333
|
console.log("\u{1F4F8} Step 5: Uploading images...");
|
|
@@ -1391,6 +1442,47 @@ async function promptForToken() {
|
|
|
1391
1442
|
});
|
|
1392
1443
|
});
|
|
1393
1444
|
}
|
|
1445
|
+
async function promptYesNo(question) {
|
|
1446
|
+
const rl = createReadline();
|
|
1447
|
+
return new Promise((resolve) => {
|
|
1448
|
+
rl.question(`${question} (y/n): `, (answer) => {
|
|
1449
|
+
rl.close();
|
|
1450
|
+
resolve(answer.trim().toLowerCase() === "y" || answer.trim().toLowerCase() === "yes");
|
|
1451
|
+
});
|
|
1452
|
+
});
|
|
1453
|
+
}
|
|
1454
|
+
async function getExistingMedia(strapiUrl, apiToken) {
|
|
1455
|
+
const existingMedia = /* @__PURE__ */ new Map();
|
|
1456
|
+
try {
|
|
1457
|
+
let page = 1;
|
|
1458
|
+
const pageSize = 100;
|
|
1459
|
+
let hasMore = true;
|
|
1460
|
+
while (hasMore) {
|
|
1461
|
+
const response = await fetch(
|
|
1462
|
+
`${strapiUrl}/api/upload/files?pagination[page]=${page}&pagination[pageSize]=${pageSize}`,
|
|
1463
|
+
{
|
|
1464
|
+
headers: {
|
|
1465
|
+
Authorization: `Bearer ${apiToken}`
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
);
|
|
1469
|
+
if (!response.ok) {
|
|
1470
|
+
break;
|
|
1471
|
+
}
|
|
1472
|
+
const data = await response.json();
|
|
1473
|
+
const files = Array.isArray(data) ? data : data.results || [];
|
|
1474
|
+
for (const file of files) {
|
|
1475
|
+
if (file.name) {
|
|
1476
|
+
existingMedia.set(file.name, file.id);
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1479
|
+
hasMore = files.length === pageSize;
|
|
1480
|
+
page++;
|
|
1481
|
+
}
|
|
1482
|
+
} catch (error) {
|
|
1483
|
+
}
|
|
1484
|
+
return existingMedia;
|
|
1485
|
+
}
|
|
1394
1486
|
async function uploadAllImages(projectDir, strapiUrl, apiToken) {
|
|
1395
1487
|
const mediaMap = /* @__PURE__ */ new Map();
|
|
1396
1488
|
const imagesDir = path12.join(projectDir, "public", "assets", "images");
|
|
@@ -1402,21 +1494,30 @@ async function uploadAllImages(projectDir, strapiUrl, apiToken) {
|
|
|
1402
1494
|
cwd: imagesDir,
|
|
1403
1495
|
absolute: false
|
|
1404
1496
|
});
|
|
1405
|
-
console.log(`
|
|
1497
|
+
console.log(` Checking for existing media...`);
|
|
1498
|
+
const existingMedia = await getExistingMedia(strapiUrl, apiToken);
|
|
1499
|
+
let uploadedCount = 0;
|
|
1500
|
+
let skippedCount = 0;
|
|
1501
|
+
console.log(` Processing ${imageFiles.length} images...`);
|
|
1406
1502
|
for (const imageFile of imageFiles) {
|
|
1503
|
+
const fileName = path12.basename(imageFile);
|
|
1504
|
+
const existingId = existingMedia.get(fileName);
|
|
1505
|
+
if (existingId) {
|
|
1506
|
+
mediaMap.set(`/images/${imageFile}`, existingId);
|
|
1507
|
+
mediaMap.set(imageFile, existingId);
|
|
1508
|
+
skippedCount++;
|
|
1509
|
+
continue;
|
|
1510
|
+
}
|
|
1407
1511
|
const imagePath = path12.join(imagesDir, imageFile);
|
|
1408
|
-
const mediaId = await uploadImage(
|
|
1409
|
-
imagePath,
|
|
1410
|
-
imageFile,
|
|
1411
|
-
strapiUrl,
|
|
1412
|
-
apiToken
|
|
1413
|
-
);
|
|
1512
|
+
const mediaId = await uploadImage(imagePath, imageFile, strapiUrl, apiToken);
|
|
1414
1513
|
if (mediaId) {
|
|
1415
1514
|
mediaMap.set(`/images/${imageFile}`, mediaId);
|
|
1416
1515
|
mediaMap.set(imageFile, mediaId);
|
|
1516
|
+
uploadedCount++;
|
|
1417
1517
|
console.log(` \u2713 ${imageFile}`);
|
|
1418
1518
|
}
|
|
1419
1519
|
}
|
|
1520
|
+
console.log(` Uploaded: ${uploadedCount}, Skipped (existing): ${skippedCount}`);
|
|
1420
1521
|
return mediaMap;
|
|
1421
1522
|
}
|
|
1422
1523
|
async function uploadImage(filePath, fileName, strapiUrl, apiToken) {
|
|
@@ -1627,7 +1728,14 @@ async function confirm(question) {
|
|
|
1627
1728
|
return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
|
|
1628
1729
|
}
|
|
1629
1730
|
program.name("cms").description("SeeMS - Webflow to CMS converter").version("0.1.2");
|
|
1630
|
-
program.command("convert").description("Convert Webflow export to Nuxt 3 project").argument("<input>", "Path to Webflow export directory").argument("<output>", "Path to output Nuxt project directory").option(
|
|
1731
|
+
program.command("convert").description("Convert Webflow export to Nuxt 3 project").argument("<input>", "Path to Webflow export directory").argument("<output>", "Path to output Nuxt project directory").option(
|
|
1732
|
+
"-b, --boilerplate <source>",
|
|
1733
|
+
"Boilerplate source (GitHub URL or local path)"
|
|
1734
|
+
).option("-o, --overrides <path>", "Path to overrides JSON file").option("--generate-schemas", "Generate CMS schemas immediately").option(
|
|
1735
|
+
"--cms <type>",
|
|
1736
|
+
"CMS backend type (strapi|contentful|sanity)",
|
|
1737
|
+
"strapi"
|
|
1738
|
+
).option("--no-interactive", "Skip interactive prompts").action(async (input, output, options) => {
|
|
1631
1739
|
try {
|
|
1632
1740
|
await convertWebflowExport({
|
|
1633
1741
|
inputDir: input,
|
|
@@ -1644,7 +1752,9 @@ program.command("convert").description("Convert Webflow export to Nuxt 3 project
|
|
|
1644
1752
|
);
|
|
1645
1753
|
if (shouldSetup) {
|
|
1646
1754
|
const strapiDir = await prompt(
|
|
1647
|
-
pc4.cyan(
|
|
1755
|
+
pc4.cyan(
|
|
1756
|
+
"\u{1F4C1} Enter path to your Strapi directory (e.g., ./strapi-dev): "
|
|
1757
|
+
)
|
|
1648
1758
|
);
|
|
1649
1759
|
if (strapiDir) {
|
|
1650
1760
|
console.log("");
|
|
@@ -1658,13 +1768,17 @@ program.command("convert").description("Convert Webflow export to Nuxt 3 project
|
|
|
1658
1768
|
} catch (error) {
|
|
1659
1769
|
console.error(pc4.red("\n\u274C Strapi setup failed"));
|
|
1660
1770
|
console.error(pc4.dim("You can run setup manually later with:"));
|
|
1661
|
-
console.error(
|
|
1771
|
+
console.error(
|
|
1772
|
+
pc4.dim(` cms setup-strapi ${output} ${strapiDir}`)
|
|
1773
|
+
);
|
|
1662
1774
|
}
|
|
1663
1775
|
}
|
|
1664
1776
|
} else {
|
|
1665
1777
|
console.log("");
|
|
1666
1778
|
console.log(pc4.dim("\u{1F4A1} You can setup Strapi later with:"));
|
|
1667
|
-
console.log(
|
|
1779
|
+
console.log(
|
|
1780
|
+
pc4.dim(` cms setup-strapi ${output} <strapi-directory>`)
|
|
1781
|
+
);
|
|
1668
1782
|
}
|
|
1669
1783
|
}
|
|
1670
1784
|
} catch (error) {
|
|
@@ -1672,13 +1786,14 @@ program.command("convert").description("Convert Webflow export to Nuxt 3 project
|
|
|
1672
1786
|
process.exit(1);
|
|
1673
1787
|
}
|
|
1674
1788
|
});
|
|
1675
|
-
program.command("setup-strapi").description("Setup Strapi with schemas and seed data").argument("<project-dir>", "Path to converted project directory").argument("<strapi-dir>", "Path to Strapi directory").option("--url <url>", "Strapi URL", "http://localhost:1337").option("--token <token>", "Strapi API token (optional)").action(async (projectDir, strapiDir, options) => {
|
|
1789
|
+
program.command("setup-strapi").description("Setup Strapi with schemas and seed data").argument("<project-dir>", "Path to converted project directory").argument("<strapi-dir>", "Path to Strapi directory").option("--url <url>", "Strapi URL", "http://localhost:1337").option("--token <token>", "Strapi API token (optional)").option("--new-token", "Ignore saved token and prompt for a new one").action(async (projectDir, strapiDir, options) => {
|
|
1676
1790
|
try {
|
|
1677
1791
|
await completeSetup({
|
|
1678
1792
|
projectDir,
|
|
1679
1793
|
strapiDir,
|
|
1680
1794
|
strapiUrl: options.url,
|
|
1681
|
-
apiToken: options.token
|
|
1795
|
+
apiToken: options.token,
|
|
1796
|
+
ignoreSavedToken: options.newToken
|
|
1682
1797
|
});
|
|
1683
1798
|
} catch (error) {
|
|
1684
1799
|
console.error(pc4.red("Strapi setup failed"));
|
|
@@ -1686,10 +1801,43 @@ program.command("setup-strapi").description("Setup Strapi with schemas and seed
|
|
|
1686
1801
|
process.exit(1);
|
|
1687
1802
|
}
|
|
1688
1803
|
});
|
|
1689
|
-
program.command("generate").description("Generate CMS schemas from manifest").argument("<manifest>", "Path to cms-manifest.json").option("-t, --type <cms>", "CMS type (strapi|contentful|sanity)", "strapi").option("-o, --output <dir>", "Output directory for schemas").action(async (
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1804
|
+
program.command("generate").description("Generate CMS schemas from manifest").argument("<manifest>", "Path to cms-manifest.json").option("-t, --type <cms>", "CMS type (strapi|contentful|sanity)", "strapi").option("-o, --output <dir>", "Output directory for schemas").action(async (manifestPath, options) => {
|
|
1805
|
+
try {
|
|
1806
|
+
console.log(pc4.cyan("\u{1F5C2}\uFE0F SeeMS Schema Generator"));
|
|
1807
|
+
console.log(pc4.dim(`Reading manifest from: ${manifestPath}`));
|
|
1808
|
+
const manifestExists = await fs11.pathExists(manifestPath);
|
|
1809
|
+
if (!manifestExists) {
|
|
1810
|
+
throw new Error(`Manifest file not found: ${manifestPath}`);
|
|
1811
|
+
}
|
|
1812
|
+
const manifestContent = await fs11.readFile(manifestPath, "utf-8");
|
|
1813
|
+
const manifest = JSON.parse(manifestContent);
|
|
1814
|
+
console.log(pc4.green(` \u2713 Manifest loaded successfully`));
|
|
1815
|
+
const outputDir = options.output || path13.dirname(manifestPath);
|
|
1816
|
+
if (options.type !== "strapi") {
|
|
1817
|
+
console.log(
|
|
1818
|
+
pc4.yellow(
|
|
1819
|
+
`\u26A0\uFE0F Only Strapi is currently supported. Using Strapi schema format.`
|
|
1820
|
+
)
|
|
1821
|
+
);
|
|
1822
|
+
}
|
|
1823
|
+
console.log(pc4.blue("\n\u{1F4CB} Generating Strapi schemas..."));
|
|
1824
|
+
const schemas = manifestToSchemas(manifest);
|
|
1825
|
+
await writeAllSchemas(outputDir, schemas);
|
|
1826
|
+
await createStrapiReadme(outputDir);
|
|
1827
|
+
console.log(
|
|
1828
|
+
pc4.green(
|
|
1829
|
+
` \u2713 Generated ${Object.keys(schemas).length} Strapi content types`
|
|
1830
|
+
)
|
|
1831
|
+
);
|
|
1832
|
+
console.log(pc4.dim(` \u2713 Schemas written to: ${path13.join(outputDir, "cms-schemas")}/`));
|
|
1833
|
+
console.log(pc4.green("\n\u2705 Schema generation completed successfully!"));
|
|
1834
|
+
} catch (error) {
|
|
1835
|
+
console.error(pc4.red("\n\u274C Schema generation failed:"));
|
|
1836
|
+
console.error(
|
|
1837
|
+
pc4.red(error instanceof Error ? error.message : String(error))
|
|
1838
|
+
);
|
|
1839
|
+
process.exit(1);
|
|
1840
|
+
}
|
|
1693
1841
|
});
|
|
1694
1842
|
program.parse();
|
|
1695
1843
|
//# sourceMappingURL=cli.mjs.map
|
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/converter.ts","../src/filesystem.ts","../src/parser.ts","../src/config-updater.ts","../src/editor-integration.ts","../src/boilerplate.ts","../src/manifest.ts","../src/detector.ts","../src/transformer.ts","../src/schema-writer.ts","../src/content-extractor.ts","../src/seed-writer.ts","../src/strapi-setup.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * CLI for @see-ms/converter\n * Usage: cms convert <input-dir> <output-dir> [options]\n */\n\nimport { Command } from 'commander';\nimport pc from 'picocolors';\nimport * as readline from 'readline';\nimport { convertWebflowExport } from './converter';\nimport { completeSetup } from './strapi-setup';\n\nconst program = new Command();\n\n/**\n * Prompt user for input\n */\nasync function prompt(question: string): Promise<string> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\n/**\n * Ask yes/no question\n */\nasync function confirm(question: string): Promise<boolean> {\n const answer = await prompt(`${question} (y/n): `);\n return answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes';\n}\n\nprogram\n .name('cms')\n .description('SeeMS - Webflow to CMS converter')\n .version('0.1.2');\n\nprogram\n .command('convert')\n .description('Convert Webflow export to Nuxt 3 project')\n .argument('<input>', 'Path to Webflow export directory')\n .argument('<output>', 'Path to output Nuxt project directory')\n .option('-b, --boilerplate <source>', 'Boilerplate source (GitHub URL or local path)')\n .option('-o, --overrides <path>', 'Path to overrides JSON file')\n .option('--generate-schemas', 'Generate CMS schemas immediately')\n .option('--cms <type>', 'CMS backend type (strapi|contentful|sanity)', 'strapi')\n .option('--no-interactive', 'Skip interactive prompts')\n .action(async (input, output, options) => {\n try {\n // Run conversion\n await convertWebflowExport({\n inputDir: input,\n outputDir: output,\n boilerplate: options.boilerplate,\n overridesPath: options.overrides,\n generateStrapi: options.generateSchemas,\n cmsBackend: options.cms,\n });\n\n // Interactive Strapi setup (if not disabled)\n if (options.interactive && options.cms === 'strapi') {\n console.log(''); // blank line\n const shouldSetup = await confirm(\n pc.cyan('🎯 Would you like to setup Strapi now?')\n );\n\n if (shouldSetup) {\n const strapiDir = await prompt(\n pc.cyan('📁 Enter path to your Strapi directory (e.g., ./strapi-dev): ')\n );\n\n if (strapiDir) {\n console.log(''); // blank line\n console.log(pc.cyan('🚀 Starting Strapi setup...'));\n console.log(''); // blank line\n\n try {\n await completeSetup({\n projectDir: output,\n strapiDir: strapiDir,\n });\n } catch (error) {\n console.error(pc.red('\\n❌ Strapi setup failed'));\n console.error(pc.dim('You can run setup manually later with:'));\n console.error(pc.dim(` cms setup-strapi ${output} ${strapiDir}`));\n }\n }\n } else {\n console.log(''); // blank line\n console.log(pc.dim('💡 You can setup Strapi later with:'));\n console.log(pc.dim(` cms setup-strapi ${output} <strapi-directory>`));\n }\n }\n } catch (error) {\n console.error(pc.red('Conversion failed'));\n process.exit(1);\n }\n });\n\nprogram\n .command('setup-strapi')\n .description('Setup Strapi with schemas and seed data')\n .argument('<project-dir>', 'Path to converted project directory')\n .argument('<strapi-dir>', 'Path to Strapi directory')\n .option('--url <url>', 'Strapi URL', 'http://localhost:1337')\n .option('--token <token>', 'Strapi API token (optional)')\n .action(async (projectDir, strapiDir, options) => {\n try {\n await completeSetup({\n projectDir,\n strapiDir,\n strapiUrl: options.url,\n apiToken: options.token,\n });\n } catch (error) {\n console.error(pc.red('Strapi setup failed'));\n console.error(error);\n process.exit(1);\n }\n });\n\nprogram\n .command('generate')\n .description('Generate CMS schemas from manifest')\n .argument('<manifest>', 'Path to cms-manifest.json')\n .option('-t, --type <cms>', 'CMS type (strapi|contentful|sanity)', 'strapi')\n .option('-o, --output <dir>', 'Output directory for schemas')\n .action(async (manifest, _options) => {\n console.log(pc.cyan('🗂️ SeeMS Schema Generator'));\n console.log(pc.dim(`Generating schemas from: ${manifest}`));\n\n // TODO: Implementation in Sprint 3\n console.log(pc.yellow('⚠️ Schema generation logic to be implemented'));\n });\n\nprogram.parse();\n","/**\n * Main conversion logic\n */\n\nimport type { ConversionOptions } from '@see-ms/types';\nimport pc from 'picocolors';\nimport path from 'path';\nimport fs from 'fs-extra';\nimport {\n scanAssets,\n copyAllAssets,\n findHTMLFiles,\n readHTMLFile,\n writeVueComponent,\n formatVueFiles,\n} from './filesystem';\nimport { parseHTML, transformForNuxt, htmlToVueComponent, deduplicateStyles } from './parser';\nimport {\n writeWebflowAssetPlugin,\n updateNuxtConfig,\n writeEmbeddedStyles,\n} from './config-updater';\nimport { createEditorPlugin, addEditorDependency, createSaveEndpoint } from './editor-integration';\nimport { setupBoilerplate } from './boilerplate';\nimport { generateManifest, writeManifest } from './manifest';\nimport { manifestToSchemas } from './transformer';\nimport { writeAllSchemas, createStrapiReadme } from './schema-writer';\nimport { extractAllContent, formatForStrapi } from './content-extractor';\nimport { writeSeedData, createSeedReadme } from './seed-writer';\n\nexport async function convertWebflowExport(options: ConversionOptions): Promise<void> {\n const { inputDir, outputDir, boilerplate } = options;\n\n console.log(pc.cyan('🚀 Starting Webflow to Nuxt conversion...'));\n console.log(pc.dim(`Input: ${inputDir}`));\n console.log(pc.dim(`Output: ${outputDir}`));\n\n try {\n // Step 0: Setup boilerplate first\n await setupBoilerplate(boilerplate, outputDir);\n\n // Step 1: Verify input directory exists\n const inputExists = await fs.pathExists(inputDir);\n if (!inputExists) {\n throw new Error(`Input directory not found: ${inputDir}`);\n }\n\n // Step 2: Scan for assets\n console.log(pc.blue('\\n📂 Scanning assets...'));\n const assets = await scanAssets(inputDir);\n console.log(pc.green(` ✓ Found ${assets.css.length} CSS files`));\n console.log(pc.green(` ✓ Found ${assets.images.length} images`));\n console.log(pc.green(` ✓ Found ${assets.fonts.length} fonts`));\n console.log(pc.green(` ✓ Found ${assets.js.length} JS files`));\n\n // Step 3: Copy assets to output\n console.log(pc.blue('\\n📦 Copying assets...'));\n await copyAllAssets(inputDir, outputDir, assets);\n console.log(pc.green(' ✓ Assets copied successfully'));\n\n // Step 4: Find all HTML files (including in subfolders)\n console.log(pc.blue('\\n🔍 Finding HTML files...'));\n const htmlFiles = await findHTMLFiles(inputDir);\n console.log(pc.green(` ✓ Found ${htmlFiles.length} HTML files`));\n\n // Step 5: Read and store HTML content (before converting to Vue)\n // We need this for content extraction later\n const htmlContentMap = new Map<string, string>();\n\n for (const htmlFile of htmlFiles) {\n const html = await readHTMLFile(inputDir, htmlFile);\n const pageName = htmlFile.replace('.html', '').replace(/\\//g, '-');\n htmlContentMap.set(pageName, html);\n console.log(pc.dim(` Stored: ${pageName} from ${htmlFile}`));\n }\n\n // Step 6: Convert HTML files to Vue components\n console.log(pc.blue('\\n⚙️ Converting HTML to Vue components...'));\n let allEmbeddedStyles = '';\n\n for (const htmlFile of htmlFiles) {\n const html = htmlContentMap.get(htmlFile.replace('.html', '').replace(/\\//g, '-'))!;\n const parsed = parseHTML(html, htmlFile);\n\n // Collect embedded styles\n if (parsed.embeddedStyles) {\n allEmbeddedStyles += `\\n/* From ${htmlFile} */\\n${parsed.embeddedStyles}\\n`;\n }\n\n // Transform HTML for Nuxt\n const transformed = transformForNuxt(parsed.htmlContent);\n\n // Convert to Vue component\n const pageName = htmlFile.replace('.html', '').replace(/\\//g, '-');\n const vueComponent = htmlToVueComponent(transformed, pageName);\n\n // Write to pages directory (this will overwrite existing files)\n await writeVueComponent(outputDir, htmlFile, vueComponent);\n console.log(pc.green(` ✓ Created ${htmlFile.replace('.html', '.vue')}`));\n }\n\n // Step 7: Format Vue files with Prettier\n await formatVueFiles(outputDir);\n\n // Step 8: Generate CMS manifest\n console.log(pc.blue('\\n🔍 Analyzing pages for CMS fields...'));\n const pagesDir = path.join(outputDir, 'pages');\n const manifest = await generateManifest(pagesDir);\n await writeManifest(outputDir, manifest);\n\n const totalFields = Object.values(manifest.pages).reduce(\n (sum, page) => sum + Object.keys(page.fields || {}).length,\n 0\n );\n const totalCollections = Object.values(manifest.pages).reduce(\n (sum, page) => sum + Object.keys(page.collections || {}).length,\n 0\n );\n\n console.log(pc.green(` ✓ Detected ${totalFields} fields across ${Object.keys(manifest.pages).length} pages`));\n console.log(pc.green(` ✓ Detected ${totalCollections} collections`));\n console.log(pc.green(' ✓ Generated cms-manifest.json'));\n\n // Step 9: Extract content from original HTML\n console.log(pc.blue('\\n📝 Extracting content from HTML...'));\n console.log(pc.dim(` HTML map has ${htmlContentMap.size} entries`));\n console.log(pc.dim(` Manifest has ${Object.keys(manifest.pages).length} pages`));\n\n const extractedContent = extractAllContent(htmlContentMap, manifest);\n const seedData = formatForStrapi(extractedContent);\n\n await writeSeedData(outputDir, seedData);\n await createSeedReadme(outputDir);\n\n // Count pages that had content extracted (not boilerplate-only pages)\n const pagesWithContent = Object.keys(seedData).filter(key => {\n const data = seedData[key];\n if (Array.isArray(data)) return data.length > 0;\n return Object.keys(data).length > 0;\n }).length;\n\n console.log(pc.green(` ✓ Extracted content from ${pagesWithContent} pages`));\n console.log(pc.green(` ✓ Generated cms-seed/seed-data.json`));\n\n // Step 10: Generate Strapi schemas\n console.log(pc.blue('\\n📋 Generating Strapi schemas...'));\n const schemas = manifestToSchemas(manifest);\n await writeAllSchemas(outputDir, schemas);\n await createStrapiReadme(outputDir);\n\n console.log(pc.green(` ✓ Generated ${Object.keys(schemas).length} Strapi content types`));\n console.log(pc.dim(' View schemas in: cms-schemas/'));\n\n // Step 11: Deduplicate and write embedded styles to main.css\n if (allEmbeddedStyles.trim()) {\n console.log(pc.blue('\\n✨ Writing embedded styles...'));\n const dedupedStyles = deduplicateStyles(allEmbeddedStyles);\n await writeEmbeddedStyles(outputDir, dedupedStyles);\n console.log(pc.green(' ✓ Embedded styles added to main.css'));\n }\n\n // Step 12: Generate/overwrite webflow-assets.ts\n console.log(pc.blue('\\n🔧 Generating webflow-assets.ts plugin...'));\n await writeWebflowAssetPlugin(outputDir, assets.css);\n console.log(pc.green(' ✓ Plugin generated (existing file overwritten)'));\n\n // Step 13: Update nuxt.config.ts\n console.log(pc.blue('\\n⚙️ Updating nuxt.config.ts...'));\n try {\n await updateNuxtConfig(outputDir, assets.css);\n console.log(pc.green(' ✓ Config updated'));\n } catch (error) {\n console.log(pc.yellow(' ⚠ Could not update nuxt.config.ts automatically'));\n console.log(pc.dim(' Please add CSS files manually'));\n }\n\n console.log(pc.blue('\\n🎨 Setting up editor overlay...'));\n await createEditorPlugin(outputDir);\n await addEditorDependency(outputDir);\n await createSaveEndpoint(outputDir);\n console.log(pc.green(' ✓ Editor plugin created'));\n console.log(pc.green(' ✓ Editor dependency added'));\n console.log(pc.green(' ✓ Save endpoint created'));\n\n // Success!\n console.log(pc.green('\\n✅ Conversion completed successfully!'));\n console.log(pc.cyan('\\n📋 Next steps:'));\n console.log(pc.dim(` 1. cd ${outputDir}`));\n console.log(pc.dim(' 2. Review cms-manifest.json and cms-seed/seed-data.json'));\n console.log(pc.dim(' 3. Set up Strapi and install schemas from cms-schemas/'));\n console.log(pc.dim(' 4. Seed Strapi with data from cms-seed/'));\n console.log(pc.dim(' 5. pnpm install && pnpm dev'));\n console.log(pc.dim(' 6. Visit http://localhost:3000?preview=true to edit inline!'));\n\n } catch (error) {\n console.error(pc.red('\\n❌ Conversion failed:'));\n console.error(pc.red(error instanceof Error ? error.message : String(error)));\n throw error;\n }\n}\n","/**\n * File system utilities for copying Webflow assets\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { glob } from 'glob';\nimport { execSync } from 'child_process';\nimport pc from 'picocolors';\n\nexport interface AssetPaths {\n css: string[]; // Goes to assets/css/\n images: string[]; // Goes to public/assets/images/\n fonts: string[]; // Goes to public/assets/fonts/\n js: string[]; // Goes to public/assets/js/\n}\n\n/**\n * Scan Webflow export directory for assets\n */\nexport async function scanAssets(webflowDir: string): Promise<AssetPaths> {\n const assets: AssetPaths = {\n css: [],\n images: [],\n fonts: [],\n js: [],\n };\n\n // Find CSS files\n const cssFiles = await glob('css/**/*.css', { cwd: webflowDir });\n assets.css = cssFiles;\n\n // Find images\n const imageFiles = await glob('images/**/*', { cwd: webflowDir });\n assets.images = imageFiles;\n\n // Find fonts\n const fontFiles = await glob('fonts/**/*', { cwd: webflowDir });\n assets.fonts = fontFiles;\n\n // Find JS files\n const jsFiles = await glob('js/**/*.js', { cwd: webflowDir });\n assets.js = jsFiles;\n\n return assets;\n}\n\n/**\n * Copy CSS files to assets/css/\n */\nexport async function copyCSSFiles(\n webflowDir: string,\n outputDir: string,\n cssFiles: string[]\n): Promise<void> {\n const targetDir = path.join(outputDir, 'assets', 'css');\n await fs.ensureDir(targetDir);\n\n for (const file of cssFiles) {\n const source = path.join(webflowDir, file);\n const target = path.join(targetDir, path.basename(file));\n await fs.copy(source, target);\n }\n}\n\n/**\n * Copy images to public/assets/images/\n */\nexport async function copyImages(\n webflowDir: string,\n outputDir: string,\n imageFiles: string[]\n): Promise<void> {\n const targetDir = path.join(outputDir, 'public', 'assets', 'images');\n await fs.ensureDir(targetDir);\n\n for (const file of imageFiles) {\n const source = path.join(webflowDir, file);\n const target = path.join(targetDir, path.basename(file));\n await fs.copy(source, target);\n }\n}\n\n/**\n * Copy fonts to public/assets/fonts/\n */\nexport async function copyFonts(\n webflowDir: string,\n outputDir: string,\n fontFiles: string[]\n): Promise<void> {\n const targetDir = path.join(outputDir, 'public', 'assets', 'fonts');\n await fs.ensureDir(targetDir);\n\n for (const file of fontFiles) {\n const source = path.join(webflowDir, file);\n const target = path.join(targetDir, path.basename(file));\n await fs.copy(source, target);\n }\n}\n\n/**\n * Copy JS files to public/assets/js/\n */\nexport async function copyJSFiles(\n webflowDir: string,\n outputDir: string,\n jsFiles: string[]\n): Promise<void> {\n const targetDir = path.join(outputDir, 'public', 'assets', 'js');\n await fs.ensureDir(targetDir);\n\n for (const file of jsFiles) {\n const source = path.join(webflowDir, file);\n const target = path.join(targetDir, path.basename(file));\n await fs.copy(source, target);\n }\n}\n\n/**\n * Copy all assets to their proper locations\n */\nexport async function copyAllAssets(\n webflowDir: string,\n outputDir: string,\n assets: AssetPaths\n): Promise<void> {\n await copyCSSFiles(webflowDir, outputDir, assets.css);\n await copyImages(webflowDir, outputDir, assets.images);\n await copyFonts(webflowDir, outputDir, assets.fonts);\n await copyJSFiles(webflowDir, outputDir, assets.js);\n}\n\n/**\n * Find all HTML files in Webflow export (including subfolders)\n */\nexport async function findHTMLFiles(webflowDir: string): Promise<string[]> {\n // Find all HTML files recursively\n const htmlFiles = await glob('**/*.html', { cwd: webflowDir });\n return htmlFiles;\n}\n\n/**\n * Read HTML file content\n */\nexport async function readHTMLFile(webflowDir: string, fileName: string): Promise<string> {\n const filePath = path.join(webflowDir, fileName);\n return await fs.readFile(filePath, 'utf-8');\n}\n\n/**\n * Write Vue component to pages directory\n * Handles nested paths (e.g., press-release/article.html -> pages/press-release/article.vue)\n */\nexport async function writeVueComponent(\n outputDir: string,\n fileName: string,\n content: string\n): Promise<void> {\n const pagesDir = path.join(outputDir, 'pages');\n \n // Convert HTML path to Vue path\n // e.g., press-release/article.html -> press-release/article.vue\n const vueName = fileName.replace('.html', '.vue');\n const targetPath = path.join(pagesDir, vueName);\n\n // Ensure the directory exists\n await fs.ensureDir(path.dirname(targetPath));\n\n await fs.writeFile(targetPath, content, 'utf-8');\n}\n\n/**\n * Format Vue files with Prettier\n */\nexport async function formatVueFiles(outputDir: string): Promise<void> {\n const pagesDir = path.join(outputDir, 'pages');\n \n try {\n console.log(pc.blue('\\n✨ Formatting Vue files with Prettier...'));\n \n // Check if prettier is available\n execSync('npx prettier --version', { stdio: 'ignore' });\n \n // Format all Vue files in pages directory\n execSync(`npx prettier --write \"${pagesDir}/**/*.vue\"`, { \n cwd: outputDir,\n stdio: 'inherit' \n });\n \n console.log(pc.green(' ✓ Vue files formatted'));\n } catch (error) {\n console.log(pc.yellow(' ⚠ Prettier not available, skipping formatting'));\n }\n}\n","/**\n * HTML Parser for Webflow exports\n * Handles conversion to Vue/Nuxt format\n */\n\nimport * as cheerio from 'cheerio';\nimport path from 'path';\n\nexport interface ParsedPage {\n fileName: string;\n title: string;\n htmlContent: string;\n cssFiles: string[];\n embeddedStyles: string;\n images: string[];\n links: string[];\n}\n\n/**\n * Normalize a path to absolute format\n * Examples:\n * - index.html -> /\n * - about.html -> /about\n * - ../index.html -> /\n * - press-release/article.html -> /press-release/article\n */\nfunction normalizeRoute(href: string): string {\n // Remove .html extension\n let route = href.replace('.html', '');\n\n // Handle various index patterns\n if (route === 'index' || route === '/index' || route.endsWith('/index')) {\n return '/';\n }\n\n // Handle parent directory references\n if (route === '..' || route === '../' || route === '/..' || route === '../index') {\n return '/';\n }\n\n // Remove all relative path indicators\n route = route.replace(/\\.\\.\\//g, '').replace(/\\.\\//g, '');\n\n // Normalize the path\n const normalized = path.posix.normalize(route);\n\n // Ensure it starts with /\n if (!normalized.startsWith('/')) {\n return '/' + normalized;\n }\n\n // If it became just '.' after normalization, return '/'\n if (normalized === '.' || normalized === '') {\n return '/';\n }\n\n return normalized;\n}\n\n/**\n * Normalize asset path to absolute\n * Examples:\n * - images/logo.svg -> /assets/images/logo.svg\n * - ../images/logo.svg -> /assets/images/logo.svg\n * - /assets/../images/logo.svg -> /assets/images/logo.svg\n */\nfunction normalizeAssetPath(src: string): string {\n if (!src || src.startsWith('http') || src.startsWith('https')) {\n return src;\n }\n\n // Remove any ../ or ./ at the start\n let normalized = src.replace(/^(\\.\\.\\/)+/, '').replace(/^\\.\\//, '');\n\n // If it already starts with /assets/, clean up any ../ in the middle\n if (normalized.startsWith('/assets/')) {\n normalized = normalized.replace(/\\/\\.\\.\\//g, '/');\n return normalized;\n }\n\n // Otherwise, add /assets/ prefix\n return `/assets/${normalized}`;\n}\n\n/**\n * Parse a Webflow HTML file\n */\nexport function parseHTML(html: string, fileName: string): ParsedPage {\n const $ = cheerio.load(html);\n\n // Extract page title\n const title = $('title').text() || fileName.replace('.html', '');\n\n // Find all CSS files\n const cssFiles: string[] = [];\n $('link[rel=\"stylesheet\"]').each((_, el) => {\n const href = $(el).attr('href');\n if (href) {\n cssFiles.push(href);\n }\n });\n\n // Extract embedded styles (from .global-embed or style tags in body)\n let embeddedStyles = '';\n\n // Get styles from .global-embed class\n $('.global-embed style').each((_, el) => {\n embeddedStyles += $(el).html() + '\\n';\n });\n\n // Get style tags before closing body\n $('body > style').each((_, el) => {\n embeddedStyles += $(el).html() + '\\n';\n });\n\n // Remove the global-embed elements and body style tags from DOM\n $('.global-embed').remove();\n $('body > style').remove();\n\n // Remove all script tags from body\n $('body script').remove();\n\n // Get all images for asset mapping\n const images: string[] = [];\n $('img').each((_, el) => {\n const src = $(el).attr('src');\n if (src) {\n images.push(src);\n }\n });\n\n // Get all links\n const links: string[] = [];\n $('a').each((_, el) => {\n const href = $(el).attr('href');\n if (href) {\n links.push(href);\n }\n });\n\n // Get ONLY the body's inner content (not the body tag itself)\n const htmlContent = $('body').html() || '';\n\n return {\n fileName,\n title,\n htmlContent,\n cssFiles,\n embeddedStyles,\n images,\n links,\n };\n}\n\n/**\n * Transform HTML content for Nuxt/Vue\n * - Convert <a> to <NuxtLink>\n * - Fix image paths (add /assets/ prefix for public folder)\n * - Remove any remaining html/head/body tags\n * - Remove srcset and sizes attributes from images\n */\nexport function transformForNuxt(html: string): string {\n const $ = cheerio.load(html);\n\n // Remove any html, head, body tags that might have leaked through\n $('html, head, body').each((_, el) => {\n const $el = $(el);\n $el.replaceWith($el.html() || '');\n });\n\n // Remove all script tags\n $('script').remove();\n\n // 1. Convert <a> tags to <NuxtLink>\n $('a').each((_, el) => {\n const $el = $(el);\n const href = $el.attr('href');\n\n if (!href) return;\n\n // Check if it's an internal link\n const isExternal = href.startsWith('http://') ||\n href.startsWith('https://') ||\n href.startsWith('mailto:') ||\n href.startsWith('tel:') ||\n href.startsWith('#');\n\n if (!isExternal) {\n // Normalize the route\n const route = normalizeRoute(href);\n\n $el.attr('to', route);\n $el.removeAttr('href');\n\n // Change tag name to NuxtLink\n const content = $el.html();\n const classes = $el.attr('class') || '';\n\n $el.replaceWith(`<nuxt-link to=\"${route}\" class=\"${classes}\">${content}</nuxt-link>`);\n }\n });\n\n // 2. Fix image paths and remove srcset/sizes\n $('img').each((_, el) => {\n const $el = $(el);\n const src = $el.attr('src');\n\n if (src) {\n // Normalize the asset path\n const normalizedSrc = normalizeAssetPath(src);\n $el.attr('src', normalizedSrc);\n }\n\n // Remove srcset and sizes attributes\n $el.removeAttr('srcset');\n $el.removeAttr('sizes');\n });\n\n // Note: CSS background-image paths are NOT changed here\n // They will be handled by the webflow-assets.ts Vite plugin\n\n return $.html();\n}\n\n/**\n * Convert transformed HTML to Vue component\n */\nexport function htmlToVueComponent(html: string, pageName: string): string {\n return `\n<script setup lang=\"ts\">\n// Page: ${pageName}\n</script>\n\n<template>\n <div>\n ${html}\n </div>\n</template>\n`;\n}\n\n/**\n * Deduplicate styles - remove duplicate CSS rules\n */\nexport function deduplicateStyles(styles: string): string {\n if (!styles.trim()) return '';\n\n // Split by comments that indicate file sources\n const sections = styles.split(/\\/\\* From .+ \\*\\//);\n\n // Keep only unique style content\n const uniqueStyles = new Set<string>();\n\n for (const section of sections) {\n const trimmed = section.trim();\n if (trimmed) {\n uniqueStyles.add(trimmed);\n }\n }\n\n return Array.from(uniqueStyles).join('\\n\\n');\n}\n","/**\n * Utilities to update Nuxt config and generate webflow-assets.ts\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\n\n/**\n * Generate the webflow-assets.ts Vite plugin\n */\nexport function generateWebflowAssetPlugin(cssFiles: string[]): string {\n // Convert css/normalize.css to /assets/css/normalize.css\n const webflowFiles = cssFiles.map(file => `/assets/css/${path.basename(file)}`);\n\n return `import type { Plugin } from 'vite'\n\nconst webflowFiles = [${webflowFiles.map(f => `'${f}'`).join(', ')}]\nconst replacements = [\n ['../images/', '/assets/images/'],\n ['../fonts/', '/assets/fonts/']\n]\n\nconst webflowURLReset = (): Plugin => ({\n name: 'webflowURLReset',\n config: () => ({\n build: {\n rollupOptions: {\n external: [/\\\\.\\\\.\\\\/fonts\\\\//, /\\\\.\\\\.\\\\/images\\\\//]\n }\n }\n }),\n transform: (code, id) => {\n if (webflowFiles.some((path) => id.includes(path))) {\n replacements.forEach(([search, replace]) => {\n code = code.replaceAll(search, replace)\n })\n }\n\n return { code, id, map: null }\n }\n})\n\nexport default webflowURLReset\n`;\n}\n\n/**\n * Write webflow-assets.ts to utils folder (overwrites existing)\n */\nexport async function writeWebflowAssetPlugin(\n outputDir: string,\n cssFiles: string[]\n): Promise<void> {\n const utilsDir = path.join(outputDir, 'utils');\n await fs.ensureDir(utilsDir);\n\n const content = generateWebflowAssetPlugin(cssFiles);\n const targetPath = path.join(utilsDir, 'webflow-assets.ts');\n\n // This will overwrite if it exists\n await fs.writeFile(targetPath, content, 'utf-8');\n}\n\n/**\n * Update nuxt.config.ts to add CSS files\n */\nexport async function updateNuxtConfig(\n outputDir: string,\n cssFiles: string[]\n): Promise<void> {\n const configPath = path.join(outputDir, 'nuxt.config.ts');\n\n // Check if config exists\n const configExists = await fs.pathExists(configPath);\n if (!configExists) {\n throw new Error('nuxt.config.ts not found in output directory');\n }\n\n // Read existing config\n let config = await fs.readFile(configPath, 'utf-8');\n\n // Generate CSS array entries\n const cssEntries = cssFiles.map(file => ` '~/assets/css/${path.basename(file)}'`);\n\n // Check if css array exists\n if (config.includes('css:')) {\n // Find the css array and add our files\n // This is a simple approach - we'll add them at the end of the array\n config = config.replace(\n /css:\\s*\\[/,\n `css: [\\n${cssEntries.join(',\\n')},`\n );\n } else {\n // Add css array to the config\n // Find the export default defineNuxtConfig({\n config = config.replace(\n /export default defineNuxtConfig\\(\\{/,\n `export default defineNuxtConfig({\\n css: [\\n${cssEntries.join(',\\n')}\\n ],`\n );\n }\n\n // Write updated config\n await fs.writeFile(configPath, config, 'utf-8');\n}\n\n/**\n * Write embedded styles to main.css\n */\nexport async function writeEmbeddedStyles(\n outputDir: string,\n styles: string\n): Promise<void> {\n if (!styles.trim()) return;\n\n const cssDir = path.join(outputDir, 'assets', 'css');\n await fs.ensureDir(cssDir);\n\n const mainCssPath = path.join(cssDir, 'main.css');\n\n // Check if main.css exists\n const exists = await fs.pathExists(mainCssPath);\n\n if (exists) {\n // Append to existing main.css\n const existing = await fs.readFile(mainCssPath, 'utf-8');\n await fs.writeFile(mainCssPath, `${existing}\\n\\n/* Webflow Embedded Styles */\\n${styles}`, 'utf-8');\n } else {\n // Create new main.css\n await fs.writeFile(mainCssPath, `/* Webflow Embedded Styles */\\n${styles}`, 'utf-8');\n }\n}\n","/**\n * Integrate editor overlay into Nuxt projects\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\n\n/**\n * Create a Nuxt plugin to load the editor overlay\n */\nexport async function createEditorPlugin(outputDir: string): Promise<void> {\n const pluginsDir = path.join(outputDir, 'plugins');\n await fs.ensureDir(pluginsDir);\n\n const pluginContent = `/**\n * CMS Editor Overlay Plugin\n * Loads the inline editor when ?preview=true\n */\n\nexport default defineNuxtPlugin(() => {\n // Only run on client side\n if (process.server) return;\n \n // Check for preview mode\n const params = new URLSearchParams(window.location.search);\n \n if (params.get('preview') === 'true') {\n // Dynamically import the editor\n import('@see-ms/editor-overlay').then(({ initEditor, createToolbar }) => {\n const editor = initEditor({\n apiEndpoint: '/api/cms/save',\n richText: true,\n });\n \n editor.enable();\n \n const toolbar = createToolbar(editor);\n document.body.appendChild(toolbar);\n });\n }\n});\n`;\n\n const pluginPath = path.join(pluginsDir, 'cms-editor.client.ts');\n await fs.writeFile(pluginPath, pluginContent, 'utf-8');\n}\n\n/**\n * Add editor overlay as a dependency\n */\nexport async function addEditorDependency(outputDir: string): Promise<void> {\n const packageJsonPath = path.join(outputDir, 'package.json');\n\n if (await fs.pathExists(packageJsonPath)) {\n const packageJson = await fs.readJson(packageJsonPath);\n\n if (!packageJson.dependencies) {\n packageJson.dependencies = {};\n }\n\n packageJson.dependencies['@see-ms/editor-overlay'] = '^0.1.1';\n\n await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });\n }\n}\n\n/**\n * Create API endpoint for saving changes\n */\nexport async function createSaveEndpoint(outputDir: string): Promise<void> {\n const serverDir = path.join(outputDir, 'server', 'api', 'cms');\n await fs.ensureDir(serverDir);\n\n const endpointContent = `/**\n * API endpoint for saving CMS changes\n */\n\nexport default defineEventHandler(async (event) => {\n const body = await readBody(event);\n \n // TODO: Implement actual saving to Strapi\n // For now, just log the changes\n console.log('CMS changes:', body);\n \n // In production, this would:\n // 1. Validate the changes\n // 2. Send to Strapi API\n // 3. Return success/error\n \n return {\n success: true,\n message: 'Changes saved (demo mode)',\n };\n});\n`;\n\n const endpointPath = path.join(serverDir, 'save.post.ts');\n await fs.writeFile(endpointPath, endpointContent, 'utf-8');\n}\n","/**\n * Boilerplate cloning and setup utilities\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { execSync } from 'child_process';\nimport pc from 'picocolors';\n\n/**\n * Check if a string is a GitHub URL\n */\nfunction isGitHubURL(source: string): boolean {\n return source.startsWith('https://github.com/') || \n source.startsWith('git@github.com:') ||\n source.includes('github.com');\n}\n\n/**\n * Clone a GitHub repository\n */\nasync function cloneFromGitHub(repoUrl: string, outputDir: string): Promise<void> {\n console.log(pc.blue(' Cloning from GitHub...'));\n \n try {\n // Clone the repo\n execSync(`git clone ${repoUrl} ${outputDir}`, { stdio: 'inherit' });\n \n // Remove .git directory to start fresh\n const gitDir = path.join(outputDir, '.git');\n await fs.remove(gitDir);\n \n console.log(pc.green(' ✓ Boilerplate cloned successfully'));\n } catch (error) {\n throw new Error(`Failed to clone repository: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Copy from local directory\n */\nasync function copyFromLocal(sourcePath: string, outputDir: string): Promise<void> {\n console.log(pc.blue(' Copying from local path...'));\n \n const sourceExists = await fs.pathExists(sourcePath);\n if (!sourceExists) {\n throw new Error(`Local boilerplate not found: ${sourcePath}`);\n }\n \n // Copy everything except node_modules, .nuxt, .output, .git\n await fs.copy(sourcePath, outputDir, {\n filter: (src) => {\n const name = path.basename(src);\n return !['node_modules', '.nuxt', '.output', '.git', 'dist'].includes(name);\n },\n });\n \n console.log(pc.green(' ✓ Boilerplate copied successfully'));\n}\n\n/**\n * Setup boilerplate in output directory\n */\nexport async function setupBoilerplate(\n boilerplateSource: string | undefined,\n outputDir: string\n): Promise<void> {\n if (!boilerplateSource) {\n // No boilerplate specified - create minimal structure\n console.log(pc.blue('\\n📦 Creating minimal Nuxt structure...'));\n await fs.ensureDir(outputDir);\n await fs.ensureDir(path.join(outputDir, 'pages'));\n await fs.ensureDir(path.join(outputDir, 'assets'));\n await fs.ensureDir(path.join(outputDir, 'public'));\n await fs.ensureDir(path.join(outputDir, 'utils'));\n \n // Create a basic nuxt.config.ts if it doesn't exist\n const configPath = path.join(outputDir, 'nuxt.config.ts');\n const configExists = await fs.pathExists(configPath);\n \n if (!configExists) {\n const basicConfig = `export default defineNuxtConfig({\n devtools: { enabled: true },\n css: [],\n})\n`;\n await fs.writeFile(configPath, basicConfig, 'utf-8');\n }\n \n console.log(pc.green(' ✓ Structure created'));\n return;\n }\n\n // Check if output directory already exists\n const outputExists = await fs.pathExists(outputDir);\n if (outputExists) {\n throw new Error(`Output directory already exists: ${outputDir}. Please choose a different path or remove it first.`);\n }\n\n console.log(pc.blue('\\n📦 Setting up boilerplate...'));\n\n if (isGitHubURL(boilerplateSource)) {\n await cloneFromGitHub(boilerplateSource, outputDir);\n } else {\n await copyFromLocal(boilerplateSource, outputDir);\n }\n}\n","/**\n * Manifest generation\n */\n\nimport type { CMSManifest, PageManifest } from '@see-ms/types';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { analyzeVuePages } from './detector';\n\n/**\n * Generate CMS manifest from analyzed pages\n */\nexport async function generateManifest(pagesDir: string): Promise<CMSManifest> {\n // Analyze all Vue pages\n const analyzed = await analyzeVuePages(pagesDir);\n\n // Build the manifest\n const pages: Record<string, PageManifest> = {};\n\n for (const [pageName, detection] of Object.entries(analyzed)) {\n pages[pageName] = {\n fields: detection.fields,\n collections: detection.collections,\n meta: {\n route: pageName === 'index' ? '/' : `/${pageName}`,\n },\n };\n }\n\n const manifest: CMSManifest = {\n version: '1.0',\n pages,\n };\n\n return manifest;\n}\n\n/**\n * Write manifest to file\n */\nexport async function writeManifest(\n outputDir: string,\n manifest: CMSManifest\n): Promise<void> {\n const manifestPath = path.join(outputDir, 'cms-manifest.json');\n await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2), 'utf-8');\n}\n\n/**\n * Read manifest from file\n */\nexport async function readManifest(outputDir: string): Promise<CMSManifest> {\n const manifestPath = path.join(outputDir, 'cms-manifest.json');\n const content = await fs.readFile(manifestPath, 'utf-8');\n return JSON.parse(content);\n}\n","/**\n * Auto-detection of editable fields from Vue components\n */\n\nimport * as cheerio from 'cheerio';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport type { FieldMapping, CollectionMapping } from '@see-ms/types';\n\n/**\n * Clean class name - remove utility prefixes and normalize\n */\nfunction cleanClassName(className: string): string {\n return className\n .split(' ')\n .filter(cls => !cls.startsWith('c-') && !cls.startsWith('w-'))\n .filter(cls => cls.length > 0)\n .join(' ');\n}\n\n/**\n * Get primary semantic class from an element\n * Returns both original selector and normalized field name\n */\nfunction getPrimaryClass(classAttr: string | undefined): { selector: string; fieldName: string } | null {\n if (!classAttr) return null;\n\n const cleaned = cleanClassName(classAttr);\n const classes = cleaned.split(' ').filter(c => c.length > 0);\n\n if (classes.length === 0) return null;\n\n const original = classes[0];\n\n return {\n selector: original, // Keep original with dashes for CSS selector\n fieldName: original.replace(/-/g, '_') // Normalize for field name\n };\n}\n\n/**\n * Get context modifier from parent classes (cc-* prefixes)\n */\nfunction getContextModifier(_$: cheerio.CheerioAPI, $el: cheerio.Cheerio<any>): string | null {\n // Look up the parent tree for cc-* modifiers\n let $current = $el.parent();\n let depth = 0;\n\n while ($current.length > 0 && depth < 5) {\n const classes = $current.attr('class');\n if (classes) {\n const ccClass = classes.split(' ').find(c => c.startsWith('cc-'));\n if (ccClass) {\n return ccClass.replace('cc-', '').replace(/-/g, '_');\n }\n }\n $current = $current.parent();\n depth++;\n }\n\n return null;\n}\n\n/**\n * Check if element is decorative (shouldn't be editable)\n */\nfunction isDecorativeImage(_$: cheerio.CheerioAPI, $img: cheerio.Cheerio<any>): boolean {\n const $parent = $img.parent();\n const parentClass = $parent.attr('class') || '';\n\n // Skip images in these contexts\n const decorativePatterns = [\n 'nav', 'logo', 'icon', 'arrow', 'button',\n 'quote', 'pagination', 'footer', 'link'\n ];\n\n return decorativePatterns.some(pattern =>\n parentClass.includes(pattern) || parentClass.includes(`${pattern}_`)\n );\n}\n\n/**\n * Check if element is inside a button or link\n */\nfunction isInsideButton($: cheerio.CheerioAPI, el: any): boolean {\n const $el = $(el);\n const $button = $el.closest('button, a, NuxtLink, .c_button, .c_icon_button');\n return $button.length > 0;\n}\n\n/**\n * Analyze a Vue file and extract template content\n */\nexport function extractTemplateFromVue(vueContent: string): string {\n const templateMatch = vueContent.match(/<template>([\\s\\S]*?)<\\/template>/);\n if (!templateMatch) {\n return '';\n }\n return templateMatch[1];\n}\n\n/**\n * Detect editable fields from Vue template content\n */\nexport function detectEditableFields(templateHtml: string): {\n fields: Record<string, FieldMapping>;\n collections: Record<string, CollectionMapping>;\n} {\n const $ = cheerio.load(templateHtml);\n const detectedFields: Record<string, FieldMapping> = {};\n const detectedCollections: Record<string, CollectionMapping> = {};\n\n // Track which elements are part of collections\n const collectionElements = new Set<any>();\n const processedCollectionClasses = new Set<string>();\n\n // 1. Detect collections FIRST\n const potentialCollections = new Map<string, any[]>();\n\n $('[class]').each((_, el) => {\n const primaryClass = getPrimaryClass($(el).attr('class'));\n\n // Only detect top-level collection containers\n if (primaryClass && (\n primaryClass.fieldName.includes('card') ||\n primaryClass.fieldName.includes('item') ||\n primaryClass.fieldName.includes('post') ||\n primaryClass.fieldName.includes('feature')\n ) && !primaryClass.fieldName.includes('image') && !primaryClass.fieldName.includes('inner')) {\n if (!potentialCollections.has(primaryClass.fieldName)) {\n potentialCollections.set(primaryClass.fieldName, []);\n }\n potentialCollections.get(primaryClass.fieldName)?.push(el);\n }\n });\n\n // Process collections\n potentialCollections.forEach((elements, className) => {\n if (elements.length >= 2) {\n const $first = $(elements[0]);\n const collectionFields: Record<string, any> = {};\n\n // Mark this collection as processed\n processedCollectionClasses.add(className);\n\n // Mark all elements in this collection\n elements.forEach(el => {\n collectionElements.add(el);\n $(el).find('*').each((_, child) => {\n collectionElements.add(child);\n });\n });\n\n // Get the original selector for the collection\n const collectionClassInfo = getPrimaryClass($(elements[0]).attr('class'));\n const collectionSelector = collectionClassInfo ? `.${collectionClassInfo.selector}` : `.${className}`;\n\n // Detect fields within collection\n // Images\n // @ts-ignore\n $first.find('img').each((_, img) => {\n if (isInsideButton($, img)) return;\n\n const $img = $(img);\n const $parent = $img.parent();\n const parentClassInfo = getPrimaryClass($parent.attr('class'));\n\n if (parentClassInfo && parentClassInfo.fieldName.includes('image')) {\n collectionFields.image = `.${parentClassInfo.selector}`;\n return false; // Only first image\n }\n });\n\n // Tags/categories\n // @ts-ignore\n $first.find('div').each((_, el) => {\n const classInfo = getPrimaryClass($(el).attr('class'));\n if (classInfo && classInfo.fieldName.includes('tag') && !classInfo.fieldName.includes('container')) {\n collectionFields.tag = `.${classInfo.selector}`;\n return false;\n }\n });\n\n // Headings\n $first.find('h1, h2, h3, h4, h5, h6').first().each((_, el) => {\n const classInfo = getPrimaryClass($(el).attr('class'));\n if (classInfo) {\n collectionFields.title = `.${classInfo.selector}`;\n }\n });\n\n // Descriptions\n $first.find('p').first().each((_, el) => {\n const classInfo = getPrimaryClass($(el).attr('class'));\n if (classInfo) {\n collectionFields.description = `.${classInfo.selector}`;\n }\n });\n\n // Links\n // @ts-ignore\n $first.find('a, NuxtLink').not('.c_button, .c_icon_button').each((_, el) => {\n const $link = $(el);\n const linkText = $link.text().trim();\n\n if (linkText) {\n const classInfo = getPrimaryClass($link.attr('class'));\n collectionFields.link = classInfo ? `.${classInfo.selector}` : 'a';\n return false; // Only first link\n }\n });\n\n if (Object.keys(collectionFields).length > 0) {\n let collectionName = className;\n if (!collectionName.endsWith('s')) {\n collectionName += 's';\n }\n\n detectedCollections[collectionName] = {\n selector: collectionSelector,\n fields: collectionFields,\n };\n }\n }\n });\n\n // 2. Detect individual fields\n const $body = $('body');\n\n // Headings\n $body.find('h1, h2, h3, h4, h5, h6').each((index, el) => {\n if (collectionElements.has(el)) return;\n\n const $el = $(el);\n const text = $el.text().trim();\n const classInfo = getPrimaryClass($el.attr('class'));\n\n if (text) {\n let fieldName: string;\n let selector: string;\n\n if (classInfo && !classInfo.fieldName.startsWith('heading_')) {\n // Has semantic class\n fieldName = classInfo.fieldName;\n selector = `.${classInfo.selector}`;\n } else {\n // Generic heading - use parent context\n const $parent = $el.closest('[class*=\"header\"], [class*=\"hero\"], [class*=\"cta\"]').first();\n const parentClassInfo = getPrimaryClass($parent.attr('class'));\n const modifier = getContextModifier($, $el);\n\n if (parentClassInfo) {\n fieldName = modifier ? `${modifier}_${parentClassInfo.fieldName}` : parentClassInfo.fieldName;\n selector = classInfo ? `.${classInfo.selector}` : `.${parentClassInfo.selector}`;\n } else if (modifier) {\n fieldName = `${modifier}_heading`;\n selector = classInfo ? `.${classInfo.selector}` : el.tagName.toLowerCase();\n } else {\n fieldName = `heading_${index}`;\n selector = classInfo ? `.${classInfo.selector}` : el.tagName.toLowerCase();\n }\n }\n\n detectedFields[fieldName] = {\n selector: selector,\n type: 'plain',\n editable: true,\n };\n }\n });\n\n // Paragraphs\n $body.find('p').each((_index, el) => {\n if (collectionElements.has(el)) return;\n\n const $el = $(el);\n const text = $el.text().trim();\n const classInfo = getPrimaryClass($el.attr('class'));\n\n if (text && text.length > 20 && classInfo) {\n const hasFormatting = $el.find('strong, em, b, i, a, NuxtLink').length > 0;\n\n detectedFields[classInfo.fieldName] = {\n selector: `.${classInfo.selector}`,\n type: hasFormatting ? 'rich' : 'plain',\n editable: true,\n };\n }\n });\n\n // Content images only (skip decorative)\n $body.find('img').each((_index, el) => {\n if (collectionElements.has(el)) return;\n if (isInsideButton($, el)) return;\n\n const $el = $(el);\n\n // Skip decorative images\n if (isDecorativeImage($, $el)) return;\n\n const $parent = $el.parent();\n const parentClassInfo = getPrimaryClass($parent.attr('class'));\n\n if (parentClassInfo) {\n const fieldName = parentClassInfo.fieldName.includes('image')\n ? parentClassInfo.fieldName\n : `${parentClassInfo.fieldName}_image`;\n\n detectedFields[fieldName] = {\n selector: `.${parentClassInfo.selector}`,\n type: 'image',\n editable: true,\n };\n }\n });\n\n // Button text\n $body.find('NuxtLink.c_button, a.c_button, .c_button').each((_index, el) => {\n if (collectionElements.has(el)) return;\n\n const $el = $(el);\n const text = $el.contents().filter(function() {\n return this.type === 'text' || (this.type === 'tag' && this.name === 'div');\n }).first().text().trim();\n\n if (text && text.length > 2) {\n const $parent = $el.closest('[class*=\"cta\"]').first();\n const parentClassInfo = getPrimaryClass($parent.attr('class'));\n const fieldName = parentClassInfo ? `${parentClassInfo.fieldName}_button_text` : 'button_text';\n\n detectedFields[fieldName] = {\n selector: `.c_button`,\n type: 'plain',\n editable: true,\n };\n }\n });\n\n return {\n fields: detectedFields,\n collections: detectedCollections,\n };\n}\n\n/**\n * Analyze all Vue pages in a directory\n */\nexport async function analyzeVuePages(pagesDir: string): Promise<Record<string, {\n fields: Record<string, FieldMapping>;\n collections: Record<string, CollectionMapping>;\n}>> {\n const results: Record<string, any> = {};\n\n const vueFiles = await fs.readdir(pagesDir);\n\n for (const file of vueFiles) {\n if (file.endsWith('.vue')) {\n const filePath = path.join(pagesDir, file);\n const content = await fs.readFile(filePath, 'utf-8');\n const template = extractTemplateFromVue(content);\n\n if (template) {\n const pageName = file.replace('.vue', '');\n results[pageName] = detectEditableFields(template);\n }\n }\n }\n\n return results;\n}\n","/**\n * Transform CMS manifest to Strapi schemas\n */\n\nimport type { CMSManifest, StrapiSchema, FieldMapping } from '@see-ms/types';\n\n/**\n * Map field type to Strapi field type\n */\nfunction mapFieldTypeToStrapi(fieldType: string): string {\n const typeMap: Record<string, string> = {\n plain: 'string',\n rich: 'richtext',\n html: 'richtext',\n image: 'media',\n link: 'string',\n email: 'email',\n phone: 'string',\n };\n\n return typeMap[fieldType] || 'string';\n}\n\n/**\n * Generate proper plural form for a word\n */\nfunction pluralize(word: string): string {\n // Handle special cases\n if (word.endsWith('s') || word.endsWith('x') || word.endsWith('z') ||\n word.endsWith('ch') || word.endsWith('sh')) {\n return word + 'es';\n }\n\n // Handle words ending in 'y' preceded by consonant\n if (word.endsWith('y') && word.length > 1) {\n const secondLast = word[word.length - 2];\n if (!'aeiou'.includes(secondLast.toLowerCase())) {\n return word.slice(0, -1) + 'ies';\n }\n }\n\n // Default: just add 's'\n return word + 's';\n}\n\n/**\n * Convert a page manifest to a Strapi schema (single type)\n */\nfunction pageToStrapiSchema(pageName: string, fields: Record<string, FieldMapping>): StrapiSchema {\n const attributes: Record<string, any> = {};\n\n // Convert each field\n for (const [fieldName, field] of Object.entries(fields)) {\n attributes[fieldName] = {\n type: mapFieldTypeToStrapi(field.type),\n required: field.required || false,\n };\n\n if (field.default) {\n attributes[fieldName].default = field.default;\n }\n }\n\n // Generate display name\n const displayName = pageName\n .split('-')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n\n // Use kebab-case consistently (keep the original pageName format)\n // This matches Strapi conventions and avoids conversion issues\n const kebabCaseName = pageName;\n\n // Generate plural name\n const pluralName = pluralize(kebabCaseName);\n\n return {\n kind: 'singleType',\n collectionName: kebabCaseName,\n info: {\n singularName: kebabCaseName,\n pluralName: pluralName,\n displayName: displayName,\n },\n options: {\n draftAndPublish: true,\n },\n attributes,\n };\n}\n\n/**\n * Convert a collection to a Strapi schema (collection type)\n */\nfunction collectionToStrapiSchema(\n collectionName: string,\n collection: any\n): StrapiSchema {\n const attributes: Record<string, any> = {};\n\n // Convert each field in the collection\n for (const [fieldName, _selector] of Object.entries(collection.fields)) {\n // Determine type based on field name\n let type = 'string';\n\n if (fieldName === 'image' || fieldName.includes('image')) {\n type = 'media';\n } else if (fieldName === 'description' || fieldName === 'content') {\n type = 'richtext';\n } else if (fieldName === 'link' || fieldName === 'url') {\n type = 'string';\n } else if (fieldName === 'title' || fieldName === 'tag') {\n type = 'string';\n }\n\n attributes[fieldName] = {\n type,\n };\n }\n\n // Generate display name\n const displayName = collectionName\n .split(/[-_]/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n\n // Convert underscores to kebab-case for consistency\n const kebabCaseName = collectionName.replace(/_/g, '-');\n\n // Get singular name (remove trailing 's')\n const singularName = kebabCaseName.endsWith('s')\n ? kebabCaseName.slice(0, -1)\n : kebabCaseName;\n\n return {\n kind: 'collectionType',\n collectionName: kebabCaseName,\n info: {\n singularName: singularName,\n pluralName: kebabCaseName,\n displayName: displayName,\n },\n options: {\n draftAndPublish: true,\n },\n attributes,\n };\n}\n\n/**\n * Transform entire manifest to Strapi schemas\n */\nexport function manifestToSchemas(manifest: CMSManifest): Record<string, StrapiSchema> {\n const schemas: Record<string, StrapiSchema> = {};\n\n // Convert pages to single types\n for (const [pageName, page] of Object.entries(manifest.pages)) {\n // Only create schema if page has fields\n if (page.fields && Object.keys(page.fields).length > 0) {\n schemas[pageName] = pageToStrapiSchema(pageName, page.fields);\n }\n\n // Convert collections to collection types\n if (page.collections) {\n for (const [collectionName, collection] of Object.entries(page.collections)) {\n schemas[collectionName] = collectionToStrapiSchema(collectionName, collection);\n }\n }\n }\n\n return schemas;\n}\n","/**\n * Write Strapi schemas to disk\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport type { StrapiSchema } from '@see-ms/types';\n\n/**\n * Write a single Strapi schema to a flat directory\n */\nexport async function writeStrapiSchema(\n outputDir: string,\n name: string,\n schema: StrapiSchema\n): Promise<void> {\n const schemasDir = path.join(outputDir, 'cms-schemas');\n await fs.ensureDir(schemasDir);\n \n const schemaPath = path.join(schemasDir, `${name}.json`);\n await fs.writeFile(schemaPath, JSON.stringify(schema, null, 2), 'utf-8');\n}\n\n/**\n * Write all schemas\n */\nexport async function writeAllSchemas(\n outputDir: string,\n schemas: Record<string, StrapiSchema>\n): Promise<void> {\n for (const [name, schema] of Object.entries(schemas)) {\n await writeStrapiSchema(outputDir, name, schema);\n }\n}\n\n/**\n * Create a README for the CMS schemas\n */\nexport async function createStrapiReadme(outputDir: string): Promise<void> {\n const readmePath = path.join(outputDir, 'cms-schemas', 'README.md');\n \n const content = `# CMS Schemas\n\nAuto-generated Strapi content type schemas from your Webflow export.\n\n## What's in this folder?\n\nEach \\`.json\\` file is a Strapi content type schema:\n\n- **Pages** (single types) - Unique pages like \\`index.json\\`, \\`about.json\\`\n- **Collections** (collection types) - Repeating content like \\`portfolio_cards.json\\`\n\n## How to use with Strapi\n\n### Option 1: Manual Setup (Recommended for learning)\n\n1. Start your Strapi project\n2. In Strapi admin, go to **Content-Type Builder**\n3. Create each content type manually using these schemas as reference\n4. Match the field names and types\n\n### Option 2: Automated Setup (Advanced)\n\nCopy schemas to your Strapi project structure:\n\n\\`\\`\\`bash\n# For each schema file, create the Strapi directory structure\n# Example for index.json (single type):\nmkdir -p strapi/src/api/index/content-types/index\ncp cms-schemas/index.json strapi/src/api/index/content-types/index/schema.json\n\n# Example for portfolio_cards.json (collection type):\nmkdir -p strapi/src/api/portfolio-cards/content-types/portfolio-card\ncp cms-schemas/portfolio_cards.json strapi/src/api/portfolio-cards/content-types/portfolio-card/schema.json\n\\`\\`\\`\n\nThen restart Strapi - it will auto-create the content types.\n\n## Schema Structure\n\nEach schema defines:\n- \\`kind\\`: \"singleType\" (unique page) or \"collectionType\" (repeating)\n- \\`attributes\\`: Fields and their types (string, richtext, media, etc.)\n- \\`displayName\\`: How it appears in Strapi admin\n\n## Field Types\n\n- \\`string\\` - Plain text\n- \\`richtext\\` - Formatted text with HTML\n- \\`media\\` - Image uploads\n\n## Next Steps\n\n1. Set up a Strapi project: \\`npx create-strapi-app@latest my-strapi\\`\n2. Use these schemas to create content types\n3. Populate content in Strapi admin\n4. Connect your Nuxt app to Strapi API\n\n## API Usage in Nuxt\n\nOnce Strapi is running with these content types:\n\n\\`\\`\\`typescript\n// Fetch single type (e.g., home page)\nconst { data } = await $fetch('http://localhost:1337/api/index')\n\n// Fetch collection type (e.g., portfolio cards)\nconst { data } = await $fetch('http://localhost:1337/api/portfolio-cards')\n\\`\\`\\`\n`;\n \n await fs.writeFile(readmePath, content, 'utf-8');\n}\n","/**\n * Content Extractor\n * Extracts actual content values from HTML based on cms-manifest selectors\n */\n\nimport type { CMSManifest, PageManifest } from '@see-ms/types';\nimport * as cheerio from 'cheerio';\nimport path from 'path';\n\nexport interface ExtractedContent {\n pages: Record<string, PageContent>;\n}\n\nexport interface PageContent {\n fields: Record<string, string>;\n collections: Record<string, CollectionItem[]>;\n}\n\nexport interface CollectionItem {\n [key: string]: string;\n}\n\n/**\n * Extract content from HTML based on manifest selectors\n */\nexport function extractContentFromHTML(\n html: string,\n _pageName: string,\n pageManifest: PageManifest\n): PageContent {\n const $ = cheerio.load(html);\n\n const content: PageContent = {\n fields: {},\n collections: {},\n };\n\n // Extract single fields\n if (pageManifest.fields) {\n for (const [fieldName, field] of Object.entries(pageManifest.fields)) {\n const selector = field.selector;\n const element = $(selector).first();\n\n if (element.length > 0) {\n if (field.type === 'image') {\n // Extract image src\n const src = element.attr('src') || element.find('img').attr('src') || '';\n content.fields[fieldName] = src;\n } else {\n // Extract text content\n const text = element.text().trim();\n content.fields[fieldName] = text;\n }\n }\n }\n }\n\n // Extract collections\n if (pageManifest.collections) {\n for (const [collectionName, collection] of Object.entries(pageManifest.collections)) {\n const items: CollectionItem[] = [];\n const collectionElements = $(collection.selector);\n\n collectionElements.each((_, elem) => {\n const item: CollectionItem = {};\n const $elem = $(elem);\n\n // Extract each field within the collection item\n for (const [fieldName, fieldSelector] of Object.entries(collection.fields)) {\n const fieldElement = $elem.find(fieldSelector as string).first();\n\n if (fieldElement.length > 0) {\n // Check if it's an image field\n if (fieldName === 'image' || fieldName.includes('image')) {\n const src = fieldElement.attr('src') || fieldElement.find('img').attr('src') || '';\n item[fieldName] = src;\n } else if (fieldName === 'link' || fieldName === 'url') {\n const href = fieldElement.attr('href') || '';\n item[fieldName] = href;\n } else {\n // Extract text\n const text = fieldElement.text().trim();\n item[fieldName] = text;\n }\n }\n }\n\n // Only add item if it has some content\n if (Object.keys(item).length > 0) {\n items.push(item);\n }\n });\n\n if (items.length > 0) {\n content.collections[collectionName] = items;\n }\n }\n }\n\n return content;\n}\n\n/**\n * Extract content from all pages based on manifest\n */\nexport function extractAllContent(\n htmlFiles: Map<string, string>,\n manifest: CMSManifest\n): ExtractedContent {\n const extractedContent: ExtractedContent = {\n pages: {},\n };\n\n for (const [pageName, pageManifest] of Object.entries(manifest.pages)) {\n const html = htmlFiles.get(pageName);\n\n if (html) {\n const content = extractContentFromHTML(html, pageName, pageManifest);\n extractedContent.pages[pageName] = content;\n }\n }\n\n return extractedContent;\n}\n\n/**\n * Normalize image paths for seed data\n * Converts absolute/relative paths to public asset paths\n */\nexport function normalizeImagePath(imageSrc: string): string {\n if (!imageSrc) return '';\n\n // If it's already a relative path starting with /, keep it\n if (imageSrc.startsWith('/')) return imageSrc;\n\n // If it's in images folder, normalize to /images/filename\n const filename = path.basename(imageSrc);\n\n if (imageSrc.includes('images/')) {\n return `/images/${filename}`;\n }\n\n // Default: assume it's in public root\n return `/${filename}`;\n}\n\n/**\n * Convert extracted content to Strapi seed format\n */\nexport function formatForStrapi(extracted: ExtractedContent): Record<string, any> {\n const seedData: Record<string, any> = {};\n\n for (const [pageName, content] of Object.entries(extracted.pages)) {\n // Format single type fields\n if (Object.keys(content.fields).length > 0) {\n const formattedFields: Record<string, any> = {};\n\n for (const [fieldName, value] of Object.entries(content.fields)) {\n // Normalize image paths\n if (fieldName.includes('image') || fieldName.includes('bg')) {\n formattedFields[fieldName] = normalizeImagePath(value);\n } else {\n formattedFields[fieldName] = value;\n }\n }\n\n seedData[pageName] = formattedFields;\n }\n\n // Format collection types\n for (const [collectionName, items] of Object.entries(content.collections)) {\n const formattedItems = items.map(item => {\n const formattedItem: Record<string, any> = {};\n\n for (const [fieldName, value] of Object.entries(item)) {\n // Normalize image paths\n if (fieldName === 'image' || fieldName.includes('image')) {\n formattedItem[fieldName] = normalizeImagePath(value);\n } else {\n formattedItem[fieldName] = value;\n }\n }\n\n return formattedItem;\n });\n\n seedData[collectionName] = formattedItems;\n }\n }\n\n return seedData;\n}\n","/**\n * Seed Data Writer\n * Writes extracted content to seed data files\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\n\n/**\n * Write seed data to JSON file\n */\nexport async function writeSeedData(\n outputDir: string,\n seedData: Record<string, any>\n): Promise<void> {\n const seedDir = path.join(outputDir, 'cms-seed');\n await fs.ensureDir(seedDir);\n\n const seedPath = path.join(seedDir, 'seed-data.json');\n await fs.writeJson(seedPath, seedData, { spaces: 2 });\n}\n\n/**\n * Create README for seed data\n */\nexport async function createSeedReadme(outputDir: string): Promise<void> {\n const readmePath = path.join(outputDir, 'cms-seed', 'README.md');\n\n const content = `# CMS Seed Data\n\nAuto-extracted content from your Webflow export, ready to seed into Strapi.\n\n## What's in this folder?\n\n\\`seed-data.json\\` contains the actual content extracted from your HTML:\n- **Single types** - Page-specific content (homepage, about page, etc.)\n- **Collection types** - Repeating items (portfolio cards, team members, etc.)\n\n## Structure\n\n\\`\\`\\`json\n{\n \"index\": {\n \"hero_heading_container\": \"Actual heading from HTML\",\n \"hero_bg_image\": \"/images/hero.jpg\",\n ...\n },\n \"portfolio_cards\": [\n {\n \"image\": \"/images/card1.jpg\",\n \"tag\": \"Technology\",\n \"description\": \"Card description\"\n }\n ]\n}\n\\`\\`\\`\n\n## How to Seed Strapi\n\n### Option 1: Manual Entry\n1. Open Strapi admin panel\n2. Go to Content Manager\n3. Create entries using the data from \\`seed-data.json\\`\n\n### Option 2: Automated Seeding (Coming Soon)\nWe'll provide a seeding script that:\n1. Uploads images to Strapi media library\n2. Creates content entries via Strapi API\n3. Handles relationships between content types\n\n## Image Paths\n\nImage paths in the seed data reference files in your Nuxt \\`public/\\` directory:\n- \\`/images/hero.jpg\\` → \\`public/images/hero.jpg\\`\n\nWhen seeding Strapi, these images will be uploaded to Strapi's media library.\n\n## Next Steps\n\n1. Review the extracted data for accuracy\n2. Set up your Strapi instance with the schemas from \\`cms-schemas/\\`\n3. Use this seed data to populate your CMS\n`;\n\n await fs.writeFile(readmePath, content, 'utf-8');\n}\n","/**\n * Strapi Complete Setup Script\n * Installs schemas, uploads images, and seeds content - all in one command\n */\n\nimport fs from \"fs-extra\";\nimport path from \"path\";\nimport { glob } from \"glob\";\nimport * as readline from \"readline\";\n\n// @ts-ignore\ninterface SchemaFile {\n name: string;\n path: string;\n schema: any;\n}\n\ninterface SetupOptions {\n projectDir: string;\n strapiDir: string;\n strapiUrl?: string;\n apiToken?: string;\n}\n\n/**\n * Main setup function\n * Exported for use by CLI and direct execution\n */\nexport async function completeSetup(options: SetupOptions): Promise<void> {\n const {\n projectDir,\n strapiDir,\n strapiUrl = \"http://localhost:1337\",\n apiToken\n } = options;\n\n console.log(\"🚀 Starting complete Strapi setup...\\n\");\n\n // Step 1: Install schemas\n console.log(\"📦 Step 1: Installing schemas...\");\n await installSchemas(projectDir, strapiDir);\n console.log(\"✓ Schemas installed\\n\");\n\n // Step 2: Wait for user to restart Strapi\n console.log(\"⏸️ Step 2: Restart Strapi to load schemas\");\n console.log(\" Run: npm run develop (in Strapi directory)\");\n console.log(\" Press Enter when Strapi is running...\");\n\n await waitForEnter();\n\n // Step 3: Check Strapi is running\n console.log(\"\\n🔍 Step 3: Checking Strapi connection...\");\n const isRunning = await checkStrapiRunning(strapiUrl);\n\n if (!isRunning) {\n console.error(\"❌ Cannot connect to Strapi at\", strapiUrl);\n console.log(\" Make sure Strapi is running: npm run develop\");\n process.exit(1);\n }\n\n console.log(\"✓ Connected to Strapi\\n\");\n\n // Step 4: Get API token\n let token = apiToken;\n if (!token) {\n console.log(\"🔑 Step 4: API Token needed\");\n console.log(\" 1. Open Strapi admin: http://localhost:1337/admin\");\n console.log(\" 2. Go to Settings > API Tokens > Create new API Token\");\n console.log(\n \" 3. Name: \\\"Seed Script\\\", Type: \\\"Full access\\\", Duration: \\\"Unlimited\\\"\"\n );\n console.log(\" 4. Copy the token and paste it here:\\n\");\n\n token = await promptForToken();\n console.log(\"\");\n }\n\n // Step 5: Upload images\n console.log(\"📸 Step 5: Uploading images...\");\n const mediaMap = await uploadAllImages(projectDir, strapiUrl, token);\n console.log(`✓ Uploaded ${Object.keys(mediaMap).length} images\\n`);\n\n // Step 6: Seed content\n console.log(\"📝 Step 6: Seeding content...\");\n await seedContent(projectDir, strapiUrl, token, mediaMap);\n console.log(\"✓ Content seeded\\n\");\n\n console.log(\"✅ Complete setup finished!\");\n console.log(\"\\n📋 Next steps:\");\n console.log(\" 1. Open Strapi admin: http://localhost:1337/admin\");\n console.log(\" 2. Check Content Manager - your content should be there!\");\n console.log(\" 3. Connect your Nuxt app to Strapi API\");\n}\n\n/**\n * Install all schemas from cms-schemas folder into Strapi\n */\nasync function installSchemas(\n projectDir: string,\n strapiDir: string\n): Promise<void> {\n // Validate strapi directory exists\n if (!(await fs.pathExists(strapiDir))) {\n console.error(` ✗ Strapi directory not found: ${strapiDir}`);\n console.error(` Resolved to: ${path.resolve(strapiDir)}`);\n throw new Error(`Strapi directory not found: ${strapiDir}`);\n }\n // Check it's actually a Strapi project\n const packageJsonPath = path.join(strapiDir, \"package.json\");\n if (await fs.pathExists(packageJsonPath)) {\n const pkg = await fs.readJson(packageJsonPath);\n if (!pkg.dependencies?.[\"@strapi/strapi\"]) {\n console.warn(` ⚠️ Warning: ${strapiDir} may not be a Strapi project`);\n }\n }\n\n const schemaDir = path.join(projectDir, \"cms-schemas\");\n\n const schemaFiles = await glob(\"*.json\", {\n cwd: schemaDir,\n absolute: false\n });\n\n if (schemaFiles.length === 0) {\n console.log(\"⚠️ No schema files found\");\n return;\n }\n\n console.log(` Found ${schemaFiles.length} schema file(s)`);\n\n for (const file of schemaFiles) {\n const schemaPath = path.join(schemaDir, file);\n const schema = await fs.readJson(schemaPath);\n const singularName =\n schema.info?.singularName || path.basename(file, \".json\");\n\n // console.log(` Generating ${singularName}...`);\n //\n // try {\n // execSync(`npx strapi generate api ${singularName}`, {\n // cwd: strapiDir,\n // stdio: 'pipe',\n // });\n //\n // const apiPath = path.join(strapiDir, 'src', 'api', singularName);\n // const contentTypesPath = path.join(apiPath, 'content-types', singularName);\n // const targetPath = path.join(contentTypesPath, 'schema.json');\n //\n // await fs.writeJson(targetPath, schema, { spaces: 2 });\n // console.log(` ✓ Created ${singularName}`);\n // } catch (error: any) {\n // const errorMessage = error.stderr?.toString() || error.message || 'Unknown error';\n // console.error(` ✗ Failed to generate ${singularName}: ${errorMessage}`);\n // }\n // // const apiPath = path.join(strapiDir, 'src', 'api', singularName);\n // // const contentTypesPath = path.join(apiPath, 'content-types', singularName);\n // // const targetPath = path.join(contentTypesPath, 'schema.json');\n // //\n // // await fs.ensureDir(contentTypesPath);\n // // await fs.writeJson(targetPath, schema, { spaces: 2 });\n console.log(` Installing ${singularName}...`);\n try {\n // Create the Strapi API structure manually (strapi generate is interactive)\n const apiPath = path.join(strapiDir, \"src\", \"api\", singularName);\n const contentTypesPath = path.join(\n apiPath,\n \"content-types\",\n singularName\n );\n const targetPath = path.join(contentTypesPath, \"schema.json\");\n\n // Create directories\n await fs.ensureDir(contentTypesPath);\n await fs.ensureDir(path.join(apiPath, \"routes\"));\n await fs.ensureDir(path.join(apiPath, \"controllers\"));\n await fs.ensureDir(path.join(apiPath, \"services\"));\n\n // Write the schema\n await fs.writeJson(targetPath, schema, { spaces: 2 });\n\n // Create TypeScript route file (Strapi 5 format)\n const routeContent = `import { factories } from '@strapi/strapi';\n export default factories.createCoreRouter('api::${singularName}.${singularName}');\n `;\n await fs.writeFile(\n path.join(apiPath, \"routes\", `${singularName}.ts`),\n routeContent\n );\n\n // Create TypeScript controller file\n const controllerContent = `import { factories } from '@strapi/strapi';\n export default factories.createCoreController('api::${singularName}.${singularName}');\n `;\n await fs.writeFile(\n path.join(apiPath, \"controllers\", `${singularName}.ts`),\n controllerContent\n );\n\n // Create TypeScript service file\n const serviceContent = `import { factories } from '@strapi/strapi';\n export default factories.createCoreService('api::${singularName}.${singularName}');\n `;\n await fs.writeFile(\n path.join(apiPath, \"services\", `${singularName}.ts`),\n serviceContent\n );\n } catch (error: any) {\n console.error(` ✗ Failed to install ${singularName}: ${error.message}`);\n }\n }\n}\n\n/**\n * Check if Strapi is running\n */\nasync function checkStrapiRunning(strapiUrl: string): Promise<boolean> {\n try {\n const response = await fetch(`${strapiUrl}/_health`);\n return response.ok;\n } catch {\n return false;\n }\n}\n\nfunction createReadline(): readline.Interface {\n return readline.createInterface({\n input: process.stdin,\n output: process.stdout\n });\n}\n\n/**\n * Wait for user to press Enter\n */\nasync function waitForEnter(): Promise<void> {\n const rl = createReadline();\n return new Promise((resolve) => {\n rl.question(\"\", () => {\n rl.close();\n resolve();\n });\n });\n}\n\n/**\n * Prompt user for API token\n */\nasync function promptForToken(): Promise<string> {\n const rl = createReadline();\n\n return new Promise((resolve) => {\n rl.question(\" Token: \", (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\n/**\n * Upload all images to Strapi media library\n * Returns a map of original paths to Strapi media IDs\n */\nasync function uploadAllImages(\n projectDir: string,\n strapiUrl: string,\n apiToken: string\n): Promise<Map<string, number>> {\n const mediaMap = new Map<string, number>();\n const imagesDir = path.join(projectDir, \"public\", \"assets\", \"images\");\n\n if (!(await fs.pathExists(imagesDir))) {\n console.log(\" No images directory found\");\n return mediaMap;\n }\n\n const imageFiles = await glob(\"**/*.{jpg,jpeg,png,gif,webp,svg}\", {\n cwd: imagesDir,\n absolute: false\n });\n\n console.log(` Uploading ${imageFiles.length} images...`);\n\n for (const imageFile of imageFiles) {\n const imagePath = path.join(imagesDir, imageFile);\n const mediaId = await uploadImage(\n imagePath,\n imageFile,\n strapiUrl,\n apiToken\n );\n\n if (mediaId) {\n // Store both with and without /images/ prefix for lookup\n mediaMap.set(`/images/${imageFile}`, mediaId);\n mediaMap.set(imageFile, mediaId);\n console.log(` ✓ ${imageFile}`);\n }\n }\n\n return mediaMap;\n}\n\n/**\n * Upload a single image to Strapi\n */\nasync function uploadImage(\n filePath: string,\n fileName: string,\n strapiUrl: string,\n apiToken: string\n): Promise<number | null> {\n try {\n // Read file as buffer and create Blob\n const fileBuffer = await fs.readFile(filePath);\n const mimeType = getMimeType(fileName);\n const blob = new Blob([fileBuffer], { type: mimeType });\n\n // Use native FormData (works with native fetch)\n const formData = new globalThis.FormData();\n formData.append(\"files\", blob, fileName);\n\n const response = await fetch(`${strapiUrl}/api/upload`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiToken}`\n },\n body: formData\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(\n ` ✗ Failed to upload ${fileName}: ${response.status} - ${errorText}`\n );\n return null;\n }\n const data = await response.json();\n\n // @ts-ignore\n return data[0]?.id || null;\n } catch (error) {\n console.error(` ✗ Error uploading ${fileName}:`, error);\n return null;\n }\n}\n\n\nfunction getMimeType(fileName: string): string {\n const ext = path.extname(fileName).toLowerCase();\n const mimeTypes: Record<string, string> = {\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".png\": \"image/png\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\"\n };\n return mimeTypes[ext] || \"application/octet-stream\";\n}\n\n/**\n * Seed all content from seed-data.json\n */\nasync function seedContent(\n projectDir: string,\n strapiUrl: string,\n apiToken: string,\n mediaMap: Map<string, number>\n): Promise<void> {\n const seedPath = path.join(projectDir, \"cms-seed\", \"seed-data.json\");\n\n if (!(await fs.pathExists(seedPath))) {\n console.log(\" No seed data found\");\n return;\n }\n\n const seedData = await fs.readJson(seedPath);\n\n const schemasDir = path.join(projectDir, \"cms-schemas\");\n const schemas = new Map<string, any>();\n\n const schemaFiles = await glob(\"*.json\", { cwd: schemasDir });\n for (const file of schemaFiles) {\n const schema = await fs.readJson(path.join(schemasDir, file));\n const name = path.basename(file, \".json\");\n schemas.set(name, schema);\n }\n\n let successCount = 0;\n let totalCount = 0;\n\n for (const [contentType, data] of Object.entries(seedData)) {\n const schema = schemas.get(contentType);\n\n if (!schema) {\n console.log(` ⚠️ No schema found for ${contentType}, skipping...`);\n continue;\n }\n\n const singularName = schema.info.singularName;\n const pluralName = schema.info.pluralName;\n\n // Check if it's a collection (array) or single type (object)\n if (Array.isArray(data)) {\n // Collection type - use pluralName\n console.log(` Seeding ${contentType} (${data.length} items)...`);\n\n for (const item of data) {\n totalCount++;\n const processedItem = processMediaFields(item, mediaMap);\n const success = await createEntry(\n pluralName,\n processedItem,\n strapiUrl,\n apiToken\n );\n if (success) successCount++;\n }\n } else {\n // Single type - use singularName\n console.log(` Seeding ${contentType}...`);\n totalCount++;\n const processedData = processMediaFields(data, mediaMap);\n const success = await createOrUpdateSingleType(\n singularName,\n processedData,\n strapiUrl,\n apiToken\n );\n if (success) successCount++;\n }\n }\n\n console.log(` ✓ Successfully seeded ${successCount}/${totalCount} entries`);\n}\n\n/**\n * Process an object to replace image paths with media IDs\n */\nfunction processMediaFields(data: any, mediaMap: Map<string, number>): any {\n const processed: any = {};\n\n for (const [key, value] of Object.entries(data)) {\n if (typeof value === \"string\") {\n // Check if this is an image path\n if (\n key.includes(\"image\") ||\n key.includes(\"bg\") ||\n value.startsWith(\"/images/\")\n ) {\n const mediaId = mediaMap.get(value);\n if (mediaId) {\n processed[key] = mediaId;\n } else {\n processed[key] = value; // Keep original if not found\n }\n } else {\n processed[key] = value;\n }\n } else {\n processed[key] = value;\n }\n }\n\n return processed;\n}\n\n/**\n * Create a collection entry\n */\nasync function createEntry(\n contentType: string,\n data: any,\n strapiUrl: string,\n apiToken: string\n): Promise<boolean> {\n try {\n const response = await fetch(`${strapiUrl}/api/${contentType}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiToken}`\n },\n body: JSON.stringify({ data })\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(\n ` ✗ Failed to create ${contentType}: ${response.status} - ${errorText}`\n );\n return false;\n }\n\n return true;\n } catch (error) {\n console.error(` ✗ Error creating ${contentType}:`, error);\n return false;\n }\n}\n\n/**\n * Create or update a single type entry\n */\nasync function createOrUpdateSingleType(\n contentType: string,\n data: any,\n strapiUrl: string,\n apiToken: string\n): Promise<boolean> {\n try {\n const response = await fetch(`${strapiUrl}/api/${contentType}`, {\n method: \"PUT\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiToken}`\n },\n body: JSON.stringify({ data })\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(\n ` ✗ Failed to update ${contentType}: ${response.status} - ${errorText}`\n );\n return false;\n }\n\n return true;\n } catch (error) {\n console.error(` ✗ Error updating ${contentType}:`, error);\n return false;\n }\n}\n\n/**\n * CLI wrapper\n */\nasync function main() {\n const args = process.argv.slice(2);\n\n if (args.length < 2) {\n console.log(\n \"Usage: tsx strapi-setup.ts <project-dir> <strapi-dir> [strapi-url] [api-token]\"\n );\n console.log(\"\");\n console.log(\"Example:\");\n console.log(\" tsx strapi-setup.ts ./nuxt-project ./strapi-dev\");\n console.log(\n \" tsx strapi-setup.ts ./nuxt-project ./strapi-dev http://localhost:1337 abc123\"\n );\n process.exit(1);\n }\n\n const [projectDir, strapiDir, strapiUrl, apiToken] = args;\n\n await completeSetup({\n projectDir,\n strapiDir,\n strapiUrl,\n apiToken\n });\n}\n\n// Run if executed directly (ESM compatible)\n// When imported, this won't run. When executed directly, it will.\nconst isMainModule =\n process.argv[1] && process.argv[1].endsWith(\"strapi-setup.ts\");\nif (isMainModule) {\n main().catch((error) => {\n console.error(\"❌ Setup failed:\", error.message);\n process.exit(1);\n });\n}\n"],"mappings":"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","names":["pc","readline","pc","path","fs","path","fs","path","fs","path","fs","path","execSync","pc","fs","path","cheerio","fs","path","path","fs","fs","path","cheerio","path","fs","path","pc","fs","path","fs","path","glob","pc"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/converter.ts","../src/filesystem.ts","../src/parser.ts","../src/config-updater.ts","../src/editor-integration.ts","../src/boilerplate.ts","../src/manifest.ts","../src/detector.ts","../src/transformer.ts","../src/schema-writer.ts","../src/content-extractor.ts","../src/seed-writer.ts","../src/strapi-setup.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * CLI for @see-ms/converter\n * Usage: cms convert <input-dir> <output-dir> [options]\n */\n\nimport { Command } from \"commander\";\nimport pc from \"picocolors\";\nimport * as readline from \"readline\";\nimport fs from \"fs-extra\";\nimport path from \"path\";\nimport { convertWebflowExport } from \"./converter\";\nimport { completeSetup } from \"./strapi-setup\";\nimport { manifestToSchemas } from \"./transformer\";\nimport { writeAllSchemas, createStrapiReadme } from \"./schema-writer\";\nimport type { CMSManifest } from \"@see-ms/types\";\n\nconst program = new Command();\n\n/**\n * Prompt user for input\n */\nasync function prompt(question: string): Promise<string> {\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout\n });\n\n return new Promise((resolve) => {\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\n/**\n * Ask yes/no question\n */\nasync function confirm(question: string): Promise<boolean> {\n const answer = await prompt(`${question} (y/n): `);\n return answer.toLowerCase() === \"y\" || answer.toLowerCase() === \"yes\";\n}\n\nprogram\n .name(\"cms\")\n .description(\"SeeMS - Webflow to CMS converter\")\n .version(\"0.1.2\");\n\nprogram\n .command(\"convert\")\n .description(\"Convert Webflow export to Nuxt 3 project\")\n .argument(\"<input>\", \"Path to Webflow export directory\")\n .argument(\"<output>\", \"Path to output Nuxt project directory\")\n .option(\n \"-b, --boilerplate <source>\",\n \"Boilerplate source (GitHub URL or local path)\"\n )\n .option(\"-o, --overrides <path>\", \"Path to overrides JSON file\")\n .option(\"--generate-schemas\", \"Generate CMS schemas immediately\")\n .option(\n \"--cms <type>\",\n \"CMS backend type (strapi|contentful|sanity)\",\n \"strapi\"\n )\n .option(\"--no-interactive\", \"Skip interactive prompts\")\n .action(async (input, output, options) => {\n try {\n // Run conversion\n await convertWebflowExport({\n inputDir: input,\n outputDir: output,\n boilerplate: options.boilerplate,\n overridesPath: options.overrides,\n generateStrapi: options.generateSchemas,\n cmsBackend: options.cms\n });\n\n // Interactive Strapi setup (if not disabled)\n if (options.interactive && options.cms === \"strapi\") {\n console.log(\"\"); // blank line\n const shouldSetup = await confirm(\n pc.cyan(\"🎯 Would you like to setup Strapi now?\")\n );\n\n if (shouldSetup) {\n const strapiDir = await prompt(\n pc.cyan(\n \"📁 Enter path to your Strapi directory (e.g., ./strapi-dev): \"\n )\n );\n\n if (strapiDir) {\n console.log(\"\"); // blank line\n console.log(pc.cyan(\"🚀 Starting Strapi setup...\"));\n console.log(\"\"); // blank line\n\n try {\n await completeSetup({\n projectDir: output,\n strapiDir: strapiDir\n });\n } catch (error) {\n console.error(pc.red(\"\\n❌ Strapi setup failed\"));\n console.error(pc.dim(\"You can run setup manually later with:\"));\n console.error(\n pc.dim(` cms setup-strapi ${output} ${strapiDir}`)\n );\n }\n }\n } else {\n console.log(\"\"); // blank line\n console.log(pc.dim(\"💡 You can setup Strapi later with:\"));\n console.log(\n pc.dim(` cms setup-strapi ${output} <strapi-directory>`)\n );\n }\n }\n } catch (error) {\n console.error(pc.red(\"Conversion failed\"));\n process.exit(1);\n }\n });\n\nprogram\n .command(\"setup-strapi\")\n .description(\"Setup Strapi with schemas and seed data\")\n .argument(\"<project-dir>\", \"Path to converted project directory\")\n .argument(\"<strapi-dir>\", \"Path to Strapi directory\")\n .option(\"--url <url>\", \"Strapi URL\", \"http://localhost:1337\")\n .option(\"--token <token>\", \"Strapi API token (optional)\")\n .option(\"--new-token\", \"Ignore saved token and prompt for a new one\")\n .action(async (projectDir, strapiDir, options) => {\n try {\n await completeSetup({\n projectDir,\n strapiDir,\n strapiUrl: options.url,\n apiToken: options.token,\n ignoreSavedToken: options.newToken\n });\n } catch (error) {\n console.error(pc.red(\"Strapi setup failed\"));\n console.error(error);\n process.exit(1);\n }\n });\n\nprogram\n .command(\"generate\")\n .description(\"Generate CMS schemas from manifest\")\n .argument(\"<manifest>\", \"Path to cms-manifest.json\")\n .option(\"-t, --type <cms>\", \"CMS type (strapi|contentful|sanity)\", \"strapi\")\n .option(\"-o, --output <dir>\", \"Output directory for schemas\")\n .action(async (manifestPath, options) => {\n try {\n console.log(pc.cyan(\"🗂️ SeeMS Schema Generator\"));\n console.log(pc.dim(`Reading manifest from: ${manifestPath}`));\n\n // Read the manifest file\n const manifestExists = await fs.pathExists(manifestPath);\n if (!manifestExists) {\n throw new Error(`Manifest file not found: ${manifestPath}`);\n }\n\n const manifestContent = await fs.readFile(manifestPath, \"utf-8\");\n const manifest: CMSManifest = JSON.parse(manifestContent);\n\n console.log(pc.green(` ✓ Manifest loaded successfully`));\n\n // Determine output directory\n const outputDir = options.output || path.dirname(manifestPath);\n\n // Only support Strapi for now\n if (options.type !== \"strapi\") {\n console.log(\n pc.yellow(\n `⚠️ Only Strapi is currently supported. Using Strapi schema format.`\n )\n );\n }\n\n // Generate schemas\n console.log(pc.blue(\"\\n📋 Generating Strapi schemas...\"));\n const schemas = manifestToSchemas(manifest);\n await writeAllSchemas(outputDir, schemas);\n await createStrapiReadme(outputDir);\n\n console.log(\n pc.green(\n ` ✓ Generated ${Object.keys(schemas).length} Strapi content types`\n )\n );\n console.log(pc.dim(` ✓ Schemas written to: ${path.join(outputDir, \"cms-schemas\")}/`));\n\n console.log(pc.green(\"\\n✅ Schema generation completed successfully!\"));\n } catch (error) {\n console.error(pc.red(\"\\n❌ Schema generation failed:\"));\n console.error(\n pc.red(error instanceof Error ? error.message : String(error))\n );\n process.exit(1);\n }\n });\n\nprogram.parse();\n","/**\n * Main conversion logic\n */\n\nimport type { ConversionOptions } from '@see-ms/types';\nimport pc from 'picocolors';\nimport path from 'path';\nimport fs from 'fs-extra';\nimport {\n scanAssets,\n copyAllAssets,\n findHTMLFiles,\n readHTMLFile,\n writeVueComponent,\n formatVueFiles,\n} from './filesystem';\nimport { parseHTML, transformForNuxt, htmlToVueComponent, deduplicateStyles } from './parser';\nimport {\n writeWebflowAssetPlugin,\n updateNuxtConfig,\n writeEmbeddedStyles,\n} from './config-updater';\nimport { createEditorPlugin, addEditorDependency, createSaveEndpoint } from './editor-integration';\nimport { setupBoilerplate } from './boilerplate';\nimport { generateManifest, writeManifest } from './manifest';\nimport { manifestToSchemas } from './transformer';\nimport { writeAllSchemas, createStrapiReadme } from './schema-writer';\nimport { extractAllContent, formatForStrapi } from './content-extractor';\nimport { writeSeedData, createSeedReadme } from './seed-writer';\n\nexport async function convertWebflowExport(options: ConversionOptions): Promise<void> {\n const { inputDir, outputDir, boilerplate } = options;\n\n console.log(pc.cyan('🚀 Starting Webflow to Nuxt conversion...'));\n console.log(pc.dim(`Input: ${inputDir}`));\n console.log(pc.dim(`Output: ${outputDir}`));\n\n try {\n // Step 0: Setup boilerplate first\n await setupBoilerplate(boilerplate, outputDir);\n\n // Step 1: Verify input directory exists\n const inputExists = await fs.pathExists(inputDir);\n if (!inputExists) {\n throw new Error(`Input directory not found: ${inputDir}`);\n }\n\n // Step 2: Scan for assets\n console.log(pc.blue('\\n📂 Scanning assets...'));\n const assets = await scanAssets(inputDir);\n console.log(pc.green(` ✓ Found ${assets.css.length} CSS files`));\n console.log(pc.green(` ✓ Found ${assets.images.length} images`));\n console.log(pc.green(` ✓ Found ${assets.fonts.length} fonts`));\n console.log(pc.green(` ✓ Found ${assets.js.length} JS files`));\n\n // Step 3: Copy assets to output\n console.log(pc.blue('\\n📦 Copying assets...'));\n await copyAllAssets(inputDir, outputDir, assets);\n console.log(pc.green(' ✓ Assets copied successfully'));\n\n // Step 4: Find all HTML files (including in subfolders)\n console.log(pc.blue('\\n🔍 Finding HTML files...'));\n const htmlFiles = await findHTMLFiles(inputDir);\n console.log(pc.green(` ✓ Found ${htmlFiles.length} HTML files`));\n\n // Step 5: Read and store HTML content (before converting to Vue)\n // We need this for content extraction later\n const htmlContentMap = new Map<string, string>();\n\n for (const htmlFile of htmlFiles) {\n const html = await readHTMLFile(inputDir, htmlFile);\n const pageName = htmlFile.replace('.html', '').replace(/\\//g, '-');\n htmlContentMap.set(pageName, html);\n console.log(pc.dim(` Stored: ${pageName} from ${htmlFile}`));\n }\n\n // Step 6: Convert HTML files to Vue components\n console.log(pc.blue('\\n⚙️ Converting HTML to Vue components...'));\n let allEmbeddedStyles = '';\n\n for (const htmlFile of htmlFiles) {\n const html = htmlContentMap.get(htmlFile.replace('.html', '').replace(/\\//g, '-'))!;\n const parsed = parseHTML(html, htmlFile);\n\n // Collect embedded styles\n if (parsed.embeddedStyles) {\n allEmbeddedStyles += `\\n/* From ${htmlFile} */\\n${parsed.embeddedStyles}\\n`;\n }\n\n // Transform HTML for Nuxt\n const transformed = transformForNuxt(parsed.htmlContent);\n\n // Convert to Vue component\n const pageName = htmlFile.replace('.html', '').replace(/\\//g, '-');\n const vueComponent = htmlToVueComponent(transformed, pageName);\n\n // Write to pages directory (this will overwrite existing files)\n await writeVueComponent(outputDir, htmlFile, vueComponent);\n console.log(pc.green(` ✓ Created ${htmlFile.replace('.html', '.vue')}`));\n }\n\n // Step 7: Format Vue files with Prettier\n await formatVueFiles(outputDir);\n\n // Step 8: Generate CMS manifest\n console.log(pc.blue('\\n🔍 Analyzing pages for CMS fields...'));\n const pagesDir = path.join(outputDir, 'pages');\n const manifest = await generateManifest(pagesDir);\n await writeManifest(outputDir, manifest);\n\n const totalFields = Object.values(manifest.pages).reduce(\n (sum, page) => sum + Object.keys(page.fields || {}).length,\n 0\n );\n const totalCollections = Object.values(manifest.pages).reduce(\n (sum, page) => sum + Object.keys(page.collections || {}).length,\n 0\n );\n\n console.log(pc.green(` ✓ Detected ${totalFields} fields across ${Object.keys(manifest.pages).length} pages`));\n console.log(pc.green(` ✓ Detected ${totalCollections} collections`));\n console.log(pc.green(' ✓ Generated cms-manifest.json'));\n\n // Step 9: Extract content from original HTML\n console.log(pc.blue('\\n📝 Extracting content from HTML...'));\n console.log(pc.dim(` HTML map has ${htmlContentMap.size} entries`));\n console.log(pc.dim(` Manifest has ${Object.keys(manifest.pages).length} pages`));\n\n const extractedContent = extractAllContent(htmlContentMap, manifest);\n const seedData = formatForStrapi(extractedContent);\n\n await writeSeedData(outputDir, seedData);\n await createSeedReadme(outputDir);\n\n // Count pages that had content extracted (not boilerplate-only pages)\n const pagesWithContent = Object.keys(seedData).filter(key => {\n const data = seedData[key];\n if (Array.isArray(data)) return data.length > 0;\n return Object.keys(data).length > 0;\n }).length;\n\n console.log(pc.green(` ✓ Extracted content from ${pagesWithContent} pages`));\n console.log(pc.green(` ✓ Generated cms-seed/seed-data.json`));\n\n // Step 10: Generate Strapi schemas\n console.log(pc.blue('\\n📋 Generating Strapi schemas...'));\n const schemas = manifestToSchemas(manifest);\n await writeAllSchemas(outputDir, schemas);\n await createStrapiReadme(outputDir);\n\n console.log(pc.green(` ✓ Generated ${Object.keys(schemas).length} Strapi content types`));\n console.log(pc.dim(' View schemas in: cms-schemas/'));\n\n // Step 11: Deduplicate and write embedded styles to main.css\n if (allEmbeddedStyles.trim()) {\n console.log(pc.blue('\\n✨ Writing embedded styles...'));\n const dedupedStyles = deduplicateStyles(allEmbeddedStyles);\n await writeEmbeddedStyles(outputDir, dedupedStyles);\n console.log(pc.green(' ✓ Embedded styles added to main.css'));\n }\n\n // Step 12: Generate/overwrite webflow-assets.ts\n console.log(pc.blue('\\n🔧 Generating webflow-assets.ts plugin...'));\n await writeWebflowAssetPlugin(outputDir, assets.css);\n console.log(pc.green(' ✓ Plugin generated (existing file overwritten)'));\n\n // Step 13: Update nuxt.config.ts\n console.log(pc.blue('\\n⚙️ Updating nuxt.config.ts...'));\n try {\n await updateNuxtConfig(outputDir, assets.css);\n console.log(pc.green(' ✓ Config updated'));\n } catch (error) {\n console.log(pc.yellow(' ⚠ Could not update nuxt.config.ts automatically'));\n console.log(pc.dim(' Please add CSS files manually'));\n }\n\n console.log(pc.blue('\\n🎨 Setting up editor overlay...'));\n await createEditorPlugin(outputDir);\n await addEditorDependency(outputDir);\n await createSaveEndpoint(outputDir);\n console.log(pc.green(' ✓ Editor plugin created'));\n console.log(pc.green(' ✓ Editor dependency added'));\n console.log(pc.green(' ✓ Save endpoint created'));\n\n // Success!\n console.log(pc.green('\\n✅ Conversion completed successfully!'));\n console.log(pc.cyan('\\n📋 Next steps:'));\n console.log(pc.dim(` 1. cd ${outputDir}`));\n console.log(pc.dim(' 2. Review cms-manifest.json and cms-seed/seed-data.json'));\n console.log(pc.dim(' 3. Set up Strapi and install schemas from cms-schemas/'));\n console.log(pc.dim(' 4. Seed Strapi with data from cms-seed/'));\n console.log(pc.dim(' 5. pnpm install && pnpm dev'));\n console.log(pc.dim(' 6. Visit http://localhost:3000?preview=true to edit inline!'));\n\n } catch (error) {\n console.error(pc.red('\\n❌ Conversion failed:'));\n console.error(pc.red(error instanceof Error ? error.message : String(error)));\n throw error;\n }\n}\n","/**\n * File system utilities for copying Webflow assets\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { glob } from 'glob';\nimport { execSync } from 'child_process';\nimport pc from 'picocolors';\n\nexport interface AssetPaths {\n css: string[]; // Goes to assets/css/\n images: string[]; // Goes to public/assets/images/\n fonts: string[]; // Goes to public/assets/fonts/\n js: string[]; // Goes to public/assets/js/\n}\n\n/**\n * Scan Webflow export directory for assets\n */\nexport async function scanAssets(webflowDir: string): Promise<AssetPaths> {\n const assets: AssetPaths = {\n css: [],\n images: [],\n fonts: [],\n js: [],\n };\n\n // Find CSS files\n const cssFiles = await glob('css/**/*.css', { cwd: webflowDir });\n assets.css = cssFiles;\n\n // Find images\n const imageFiles = await glob('images/**/*', { cwd: webflowDir });\n assets.images = imageFiles;\n\n // Find fonts\n const fontFiles = await glob('fonts/**/*', { cwd: webflowDir });\n assets.fonts = fontFiles;\n\n // Find JS files\n const jsFiles = await glob('js/**/*.js', { cwd: webflowDir });\n assets.js = jsFiles;\n\n return assets;\n}\n\n/**\n * Copy CSS files to assets/css/\n */\nexport async function copyCSSFiles(\n webflowDir: string,\n outputDir: string,\n cssFiles: string[]\n): Promise<void> {\n const targetDir = path.join(outputDir, 'assets', 'css');\n await fs.ensureDir(targetDir);\n\n for (const file of cssFiles) {\n const source = path.join(webflowDir, file);\n const target = path.join(targetDir, path.basename(file));\n await fs.copy(source, target);\n }\n}\n\n/**\n * Copy images to public/assets/images/\n */\nexport async function copyImages(\n webflowDir: string,\n outputDir: string,\n imageFiles: string[]\n): Promise<void> {\n const targetDir = path.join(outputDir, 'public', 'assets', 'images');\n await fs.ensureDir(targetDir);\n\n for (const file of imageFiles) {\n const source = path.join(webflowDir, file);\n const target = path.join(targetDir, path.basename(file));\n await fs.copy(source, target);\n }\n}\n\n/**\n * Copy fonts to public/assets/fonts/\n */\nexport async function copyFonts(\n webflowDir: string,\n outputDir: string,\n fontFiles: string[]\n): Promise<void> {\n const targetDir = path.join(outputDir, 'public', 'assets', 'fonts');\n await fs.ensureDir(targetDir);\n\n for (const file of fontFiles) {\n const source = path.join(webflowDir, file);\n const target = path.join(targetDir, path.basename(file));\n await fs.copy(source, target);\n }\n}\n\n/**\n * Copy JS files to public/assets/js/\n */\nexport async function copyJSFiles(\n webflowDir: string,\n outputDir: string,\n jsFiles: string[]\n): Promise<void> {\n const targetDir = path.join(outputDir, 'public', 'assets', 'js');\n await fs.ensureDir(targetDir);\n\n for (const file of jsFiles) {\n const source = path.join(webflowDir, file);\n const target = path.join(targetDir, path.basename(file));\n await fs.copy(source, target);\n }\n}\n\n/**\n * Copy all assets to their proper locations\n */\nexport async function copyAllAssets(\n webflowDir: string,\n outputDir: string,\n assets: AssetPaths\n): Promise<void> {\n await copyCSSFiles(webflowDir, outputDir, assets.css);\n await copyImages(webflowDir, outputDir, assets.images);\n await copyFonts(webflowDir, outputDir, assets.fonts);\n await copyJSFiles(webflowDir, outputDir, assets.js);\n}\n\n/**\n * Find all HTML files in Webflow export (including subfolders)\n */\nexport async function findHTMLFiles(webflowDir: string): Promise<string[]> {\n // Find all HTML files recursively\n const htmlFiles = await glob('**/*.html', { cwd: webflowDir });\n return htmlFiles;\n}\n\n/**\n * Read HTML file content\n */\nexport async function readHTMLFile(webflowDir: string, fileName: string): Promise<string> {\n const filePath = path.join(webflowDir, fileName);\n return await fs.readFile(filePath, 'utf-8');\n}\n\n/**\n * Write Vue component to pages directory\n * Handles nested paths (e.g., press-release/article.html -> pages/press-release/article.vue)\n */\nexport async function writeVueComponent(\n outputDir: string,\n fileName: string,\n content: string\n): Promise<void> {\n const pagesDir = path.join(outputDir, 'pages');\n \n // Convert HTML path to Vue path\n // e.g., press-release/article.html -> press-release/article.vue\n const vueName = fileName.replace('.html', '.vue');\n const targetPath = path.join(pagesDir, vueName);\n\n // Ensure the directory exists\n await fs.ensureDir(path.dirname(targetPath));\n\n await fs.writeFile(targetPath, content, 'utf-8');\n}\n\n/**\n * Format Vue files with Prettier\n */\nexport async function formatVueFiles(outputDir: string): Promise<void> {\n const pagesDir = path.join(outputDir, 'pages');\n \n try {\n console.log(pc.blue('\\n✨ Formatting Vue files with Prettier...'));\n \n // Check if prettier is available\n execSync('npx prettier --version', { stdio: 'ignore' });\n \n // Format all Vue files in pages directory\n execSync(`npx prettier --write \"${pagesDir}/**/*.vue\"`, { \n cwd: outputDir,\n stdio: 'inherit' \n });\n \n console.log(pc.green(' ✓ Vue files formatted'));\n } catch (error) {\n console.log(pc.yellow(' ⚠ Prettier not available, skipping formatting'));\n }\n}\n","/**\n * HTML Parser for Webflow exports\n * Handles conversion to Vue/Nuxt format\n */\n\nimport * as cheerio from 'cheerio';\nimport path from 'path';\n\nexport interface ParsedPage {\n fileName: string;\n title: string;\n htmlContent: string;\n cssFiles: string[];\n embeddedStyles: string;\n images: string[];\n links: string[];\n}\n\n/**\n * Normalize a path to absolute format\n * Examples:\n * - index.html -> /\n * - about.html -> /about\n * - ../index.html -> /\n * - press-release/article.html -> /press-release/article\n */\nfunction normalizeRoute(href: string): string {\n // Remove .html extension\n let route = href.replace('.html', '');\n\n // Handle various index patterns\n if (route === 'index' || route === '/index' || route.endsWith('/index')) {\n return '/';\n }\n\n // Handle parent directory references\n if (route === '..' || route === '../' || route === '/..' || route === '../index') {\n return '/';\n }\n\n // Remove all relative path indicators\n route = route.replace(/\\.\\.\\//g, '').replace(/\\.\\//g, '');\n\n // Normalize the path\n const normalized = path.posix.normalize(route);\n\n // Ensure it starts with /\n if (!normalized.startsWith('/')) {\n return '/' + normalized;\n }\n\n // If it became just '.' after normalization, return '/'\n if (normalized === '.' || normalized === '') {\n return '/';\n }\n\n return normalized;\n}\n\n/**\n * Normalize asset path to absolute\n * Examples:\n * - images/logo.svg -> /assets/images/logo.svg\n * - ../images/logo.svg -> /assets/images/logo.svg\n * - /assets/../images/logo.svg -> /assets/images/logo.svg\n */\nfunction normalizeAssetPath(src: string): string {\n if (!src || src.startsWith('http') || src.startsWith('https')) {\n return src;\n }\n\n // Remove any ../ or ./ at the start\n let normalized = src.replace(/^(\\.\\.\\/)+/, '').replace(/^\\.\\//, '');\n\n // If it already starts with /assets/, clean up any ../ in the middle\n if (normalized.startsWith('/assets/')) {\n normalized = normalized.replace(/\\/\\.\\.\\//g, '/');\n return normalized;\n }\n\n // Otherwise, add /assets/ prefix\n return `/assets/${normalized}`;\n}\n\n/**\n * Parse a Webflow HTML file\n */\nexport function parseHTML(html: string, fileName: string): ParsedPage {\n const $ = cheerio.load(html);\n\n // Extract page title\n const title = $('title').text() || fileName.replace('.html', '');\n\n // Find all CSS files\n const cssFiles: string[] = [];\n $('link[rel=\"stylesheet\"]').each((_, el) => {\n const href = $(el).attr('href');\n if (href) {\n cssFiles.push(href);\n }\n });\n\n // Extract embedded styles (from .global-embed or style tags in body)\n let embeddedStyles = '';\n\n // Get styles from .global-embed class\n $('.global-embed style').each((_, el) => {\n embeddedStyles += $(el).html() + '\\n';\n });\n\n // Get style tags before closing body\n $('body > style').each((_, el) => {\n embeddedStyles += $(el).html() + '\\n';\n });\n\n // Remove the global-embed elements and body style tags from DOM\n $('.global-embed').remove();\n $('body > style').remove();\n\n // Remove all script tags from body\n $('body script').remove();\n\n // Get all images for asset mapping\n const images: string[] = [];\n $('img').each((_, el) => {\n const src = $(el).attr('src');\n if (src) {\n images.push(src);\n }\n });\n\n // Get all links\n const links: string[] = [];\n $('a').each((_, el) => {\n const href = $(el).attr('href');\n if (href) {\n links.push(href);\n }\n });\n\n // Get ONLY the body's inner content (not the body tag itself)\n const htmlContent = $('body').html() || '';\n\n return {\n fileName,\n title,\n htmlContent,\n cssFiles,\n embeddedStyles,\n images,\n links,\n };\n}\n\n/**\n * Transform HTML content for Nuxt/Vue\n * - Convert <a> to <NuxtLink>\n * - Fix image paths (add /assets/ prefix for public folder)\n * - Remove any remaining html/head/body tags\n * - Remove srcset and sizes attributes from images\n */\nexport function transformForNuxt(html: string): string {\n const $ = cheerio.load(html);\n\n // Remove any html, head, body tags that might have leaked through\n $('html, head, body').each((_, el) => {\n const $el = $(el);\n $el.replaceWith($el.html() || '');\n });\n\n // Remove all script tags\n $('script').remove();\n\n // 1. Convert <a> tags to <NuxtLink>\n $('a').each((_, el) => {\n const $el = $(el);\n const href = $el.attr('href');\n\n if (!href) return;\n\n // Check if it's an internal link\n const isExternal = href.startsWith('http://') ||\n href.startsWith('https://') ||\n href.startsWith('mailto:') ||\n href.startsWith('tel:') ||\n href.startsWith('#');\n\n if (!isExternal) {\n // Normalize the route\n const route = normalizeRoute(href);\n\n $el.attr('to', route);\n $el.removeAttr('href');\n\n // Change tag name to NuxtLink\n const content = $el.html();\n const classes = $el.attr('class') || '';\n\n $el.replaceWith(`<nuxt-link to=\"${route}\" class=\"${classes}\">${content}</nuxt-link>`);\n }\n });\n\n // 2. Fix image paths and remove srcset/sizes\n $('img').each((_, el) => {\n const $el = $(el);\n const src = $el.attr('src');\n\n if (src) {\n // Normalize the asset path\n const normalizedSrc = normalizeAssetPath(src);\n $el.attr('src', normalizedSrc);\n }\n\n // Remove srcset and sizes attributes\n $el.removeAttr('srcset');\n $el.removeAttr('sizes');\n });\n\n // Note: CSS background-image paths are NOT changed here\n // They will be handled by the webflow-assets.ts Vite plugin\n\n return $.html();\n}\n\n/**\n * Convert transformed HTML to Vue component\n */\nexport function htmlToVueComponent(html: string, pageName: string): string {\n return `\n<script setup lang=\"ts\">\n// Page: ${pageName}\n</script>\n\n<template>\n <div>\n ${html}\n </div>\n</template>\n`;\n}\n\n/**\n * Deduplicate styles - remove duplicate CSS rules\n */\nexport function deduplicateStyles(styles: string): string {\n if (!styles.trim()) return '';\n\n // Split by comments that indicate file sources\n const sections = styles.split(/\\/\\* From .+ \\*\\//);\n\n // Keep only unique style content\n const uniqueStyles = new Set<string>();\n\n for (const section of sections) {\n const trimmed = section.trim();\n if (trimmed) {\n uniqueStyles.add(trimmed);\n }\n }\n\n return Array.from(uniqueStyles).join('\\n\\n');\n}\n","/**\n * Utilities to update Nuxt config and generate webflow-assets.ts\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\n\n/**\n * Generate the webflow-assets.ts Vite plugin\n */\nexport function generateWebflowAssetPlugin(cssFiles: string[]): string {\n // Convert css/normalize.css to /assets/css/normalize.css\n const webflowFiles = cssFiles.map(file => `/assets/css/${path.basename(file)}`);\n\n return `import type { Plugin } from 'vite'\n\nconst webflowFiles = [${webflowFiles.map(f => `'${f}'`).join(', ')}]\nconst replacements = [\n ['../images/', '/assets/images/'],\n ['../fonts/', '/assets/fonts/']\n]\n\nconst webflowURLReset = (): Plugin => ({\n name: 'webflowURLReset',\n config: () => ({\n build: {\n rollupOptions: {\n external: [/\\\\.\\\\.\\\\/fonts\\\\//, /\\\\.\\\\.\\\\/images\\\\//]\n }\n }\n }),\n transform: (code, id) => {\n if (webflowFiles.some((path) => id.includes(path))) {\n replacements.forEach(([search, replace]) => {\n code = code.replaceAll(search, replace)\n })\n }\n\n return { code, id, map: null }\n }\n})\n\nexport default webflowURLReset\n`;\n}\n\n/**\n * Write webflow-assets.ts to utils folder (overwrites existing)\n */\nexport async function writeWebflowAssetPlugin(\n outputDir: string,\n cssFiles: string[]\n): Promise<void> {\n const utilsDir = path.join(outputDir, 'utils');\n await fs.ensureDir(utilsDir);\n\n const content = generateWebflowAssetPlugin(cssFiles);\n const targetPath = path.join(utilsDir, 'webflow-assets.ts');\n\n // This will overwrite if it exists\n await fs.writeFile(targetPath, content, 'utf-8');\n}\n\n/**\n * Update nuxt.config.ts to add CSS files\n */\nexport async function updateNuxtConfig(\n outputDir: string,\n cssFiles: string[]\n): Promise<void> {\n const configPath = path.join(outputDir, 'nuxt.config.ts');\n\n // Check if config exists\n const configExists = await fs.pathExists(configPath);\n if (!configExists) {\n throw new Error('nuxt.config.ts not found in output directory');\n }\n\n // Read existing config\n let config = await fs.readFile(configPath, 'utf-8');\n\n // Generate CSS array entries\n const cssEntries = cssFiles.map(file => ` '~/assets/css/${path.basename(file)}'`);\n\n // Check if css array exists\n if (config.includes('css:')) {\n // Find the css array and add our files\n // This is a simple approach - we'll add them at the end of the array\n config = config.replace(\n /css:\\s*\\[/,\n `css: [\\n${cssEntries.join(',\\n')},`\n );\n } else {\n // Add css array to the config\n // Find the export default defineNuxtConfig({\n config = config.replace(\n /export default defineNuxtConfig\\(\\{/,\n `export default defineNuxtConfig({\\n css: [\\n${cssEntries.join(',\\n')}\\n ],`\n );\n }\n\n // Write updated config\n await fs.writeFile(configPath, config, 'utf-8');\n}\n\n/**\n * Write embedded styles to main.css\n */\nexport async function writeEmbeddedStyles(\n outputDir: string,\n styles: string\n): Promise<void> {\n if (!styles.trim()) return;\n\n const cssDir = path.join(outputDir, 'assets', 'css');\n await fs.ensureDir(cssDir);\n\n const mainCssPath = path.join(cssDir, 'main.css');\n\n // Check if main.css exists\n const exists = await fs.pathExists(mainCssPath);\n\n if (exists) {\n // Append to existing main.css\n const existing = await fs.readFile(mainCssPath, 'utf-8');\n await fs.writeFile(mainCssPath, `${existing}\\n\\n/* Webflow Embedded Styles */\\n${styles}`, 'utf-8');\n } else {\n // Create new main.css\n await fs.writeFile(mainCssPath, `/* Webflow Embedded Styles */\\n${styles}`, 'utf-8');\n }\n}\n","/**\n * Integrate editor overlay into Nuxt projects\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\n\n/**\n * Create a Nuxt plugin to load the editor overlay\n */\nexport async function createEditorPlugin(outputDir: string): Promise<void> {\n const pluginsDir = path.join(outputDir, 'plugins');\n await fs.ensureDir(pluginsDir);\n\n const pluginContent = `/**\n * CMS Editor Overlay Plugin\n * Loads the inline editor when ?preview=true\n */\n\nexport default defineNuxtPlugin(() => {\n // Only run on client side\n if (process.server) return;\n \n // Check for preview mode\n const params = new URLSearchParams(window.location.search);\n \n if (params.get('preview') === 'true') {\n // Dynamically import the editor\n import('@see-ms/editor-overlay').then(({ initEditor, createToolbar }) => {\n const editor = initEditor({\n apiEndpoint: '/api/cms/save',\n richText: true,\n });\n \n editor.enable();\n \n const toolbar = createToolbar(editor);\n document.body.appendChild(toolbar);\n });\n }\n});\n`;\n\n const pluginPath = path.join(pluginsDir, 'cms-editor.client.ts');\n await fs.writeFile(pluginPath, pluginContent, 'utf-8');\n}\n\n/**\n * Add editor overlay as a dependency\n */\nexport async function addEditorDependency(outputDir: string): Promise<void> {\n const packageJsonPath = path.join(outputDir, 'package.json');\n\n if (await fs.pathExists(packageJsonPath)) {\n const packageJson = await fs.readJson(packageJsonPath);\n\n if (!packageJson.dependencies) {\n packageJson.dependencies = {};\n }\n\n packageJson.dependencies['@see-ms/editor-overlay'] = '^0.1.1';\n\n await fs.writeJson(packageJsonPath, packageJson, { spaces: 2 });\n }\n}\n\n/**\n * Create API endpoint for saving changes\n */\nexport async function createSaveEndpoint(outputDir: string): Promise<void> {\n const serverDir = path.join(outputDir, 'server', 'api', 'cms');\n await fs.ensureDir(serverDir);\n\n const endpointContent = `/**\n * API endpoint for saving CMS changes\n */\n\nexport default defineEventHandler(async (event) => {\n const body = await readBody(event);\n \n // TODO: Implement actual saving to Strapi\n // For now, just log the changes\n console.log('CMS changes:', body);\n \n // In production, this would:\n // 1. Validate the changes\n // 2. Send to Strapi API\n // 3. Return success/error\n \n return {\n success: true,\n message: 'Changes saved (demo mode)',\n };\n});\n`;\n\n const endpointPath = path.join(serverDir, 'save.post.ts');\n await fs.writeFile(endpointPath, endpointContent, 'utf-8');\n}\n","/**\n * Boilerplate cloning and setup utilities\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { execSync } from 'child_process';\nimport pc from 'picocolors';\n\n/**\n * Check if a string is a GitHub URL\n */\nfunction isGitHubURL(source: string): boolean {\n return source.startsWith('https://github.com/') || \n source.startsWith('git@github.com:') ||\n source.includes('github.com');\n}\n\n/**\n * Clone a GitHub repository\n */\nasync function cloneFromGitHub(repoUrl: string, outputDir: string): Promise<void> {\n console.log(pc.blue(' Cloning from GitHub...'));\n \n try {\n // Clone the repo\n execSync(`git clone ${repoUrl} ${outputDir}`, { stdio: 'inherit' });\n \n // Remove .git directory to start fresh\n const gitDir = path.join(outputDir, '.git');\n await fs.remove(gitDir);\n \n console.log(pc.green(' ✓ Boilerplate cloned successfully'));\n } catch (error) {\n throw new Error(`Failed to clone repository: ${error instanceof Error ? error.message : String(error)}`);\n }\n}\n\n/**\n * Copy from local directory\n */\nasync function copyFromLocal(sourcePath: string, outputDir: string): Promise<void> {\n console.log(pc.blue(' Copying from local path...'));\n \n const sourceExists = await fs.pathExists(sourcePath);\n if (!sourceExists) {\n throw new Error(`Local boilerplate not found: ${sourcePath}`);\n }\n \n // Copy everything except node_modules, .nuxt, .output, .git\n await fs.copy(sourcePath, outputDir, {\n filter: (src) => {\n const name = path.basename(src);\n return !['node_modules', '.nuxt', '.output', '.git', 'dist'].includes(name);\n },\n });\n \n console.log(pc.green(' ✓ Boilerplate copied successfully'));\n}\n\n/**\n * Setup boilerplate in output directory\n */\nexport async function setupBoilerplate(\n boilerplateSource: string | undefined,\n outputDir: string\n): Promise<void> {\n if (!boilerplateSource) {\n // No boilerplate specified - create minimal structure\n console.log(pc.blue('\\n📦 Creating minimal Nuxt structure...'));\n await fs.ensureDir(outputDir);\n await fs.ensureDir(path.join(outputDir, 'pages'));\n await fs.ensureDir(path.join(outputDir, 'assets'));\n await fs.ensureDir(path.join(outputDir, 'public'));\n await fs.ensureDir(path.join(outputDir, 'utils'));\n \n // Create a basic nuxt.config.ts if it doesn't exist\n const configPath = path.join(outputDir, 'nuxt.config.ts');\n const configExists = await fs.pathExists(configPath);\n \n if (!configExists) {\n const basicConfig = `export default defineNuxtConfig({\n devtools: { enabled: true },\n css: [],\n})\n`;\n await fs.writeFile(configPath, basicConfig, 'utf-8');\n }\n \n console.log(pc.green(' ✓ Structure created'));\n return;\n }\n\n // Check if output directory already exists\n const outputExists = await fs.pathExists(outputDir);\n if (outputExists) {\n throw new Error(`Output directory already exists: ${outputDir}. Please choose a different path or remove it first.`);\n }\n\n console.log(pc.blue('\\n📦 Setting up boilerplate...'));\n\n if (isGitHubURL(boilerplateSource)) {\n await cloneFromGitHub(boilerplateSource, outputDir);\n } else {\n await copyFromLocal(boilerplateSource, outputDir);\n }\n}\n","/**\n * Manifest generation\n */\n\nimport type { CMSManifest, PageManifest } from '@see-ms/types';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { analyzeVuePages } from './detector';\n\n/**\n * Generate CMS manifest from analyzed pages\n */\nexport async function generateManifest(pagesDir: string): Promise<CMSManifest> {\n // Analyze all Vue pages\n const analyzed = await analyzeVuePages(pagesDir);\n\n // Build the manifest\n const pages: Record<string, PageManifest> = {};\n\n for (const [pageName, detection] of Object.entries(analyzed)) {\n pages[pageName] = {\n fields: detection.fields,\n collections: detection.collections,\n meta: {\n route: pageName === 'index' ? '/' : `/${pageName}`,\n },\n };\n }\n\n const manifest: CMSManifest = {\n version: '1.0',\n pages,\n };\n\n return manifest;\n}\n\n/**\n * Write manifest to file\n */\nexport async function writeManifest(\n outputDir: string,\n manifest: CMSManifest\n): Promise<void> {\n const manifestPath = path.join(outputDir, 'cms-manifest.json');\n await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2), 'utf-8');\n}\n\n/**\n * Read manifest from file\n */\nexport async function readManifest(outputDir: string): Promise<CMSManifest> {\n const manifestPath = path.join(outputDir, 'cms-manifest.json');\n const content = await fs.readFile(manifestPath, 'utf-8');\n return JSON.parse(content);\n}\n","/**\n * Auto-detection of editable fields from Vue components\n */\n\nimport * as cheerio from 'cheerio';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport type { FieldMapping, CollectionMapping } from '@see-ms/types';\n\n/**\n * Clean class name - remove utility prefixes and normalize\n */\nfunction cleanClassName(className: string): string {\n return className\n .split(' ')\n .filter(cls => !cls.startsWith('c-') && !cls.startsWith('w-'))\n .filter(cls => cls.length > 0)\n .join(' ');\n}\n\n/**\n * Get primary semantic class from an element\n * Returns both original selector and normalized field name\n */\nfunction getPrimaryClass(classAttr: string | undefined): { selector: string; fieldName: string } | null {\n if (!classAttr) return null;\n\n const cleaned = cleanClassName(classAttr);\n const classes = cleaned.split(' ').filter(c => c.length > 0);\n\n if (classes.length === 0) return null;\n\n const original = classes[0];\n\n return {\n selector: original, // Keep original with dashes for CSS selector\n fieldName: original.replace(/-/g, '_') // Normalize for field name\n };\n}\n\n/**\n * Get context modifier from parent classes (cc-* prefixes)\n */\nfunction getContextModifier(_$: cheerio.CheerioAPI, $el: cheerio.Cheerio<any>): string | null {\n // Look up the parent tree for cc-* modifiers\n let $current = $el.parent();\n let depth = 0;\n\n while ($current.length > 0 && depth < 5) {\n const classes = $current.attr('class');\n if (classes) {\n const ccClass = classes.split(' ').find(c => c.startsWith('cc-'));\n if (ccClass) {\n return ccClass.replace('cc-', '').replace(/-/g, '_');\n }\n }\n $current = $current.parent();\n depth++;\n }\n\n return null;\n}\n\n/**\n * Check if element is decorative (shouldn't be editable)\n */\nfunction isDecorativeImage(_$: cheerio.CheerioAPI, $img: cheerio.Cheerio<any>): boolean {\n const $parent = $img.parent();\n const parentClass = $parent.attr('class') || '';\n\n // Skip images in these contexts\n const decorativePatterns = [\n 'nav', 'logo', 'icon', 'arrow', 'button',\n 'quote', 'pagination', 'footer', 'link'\n ];\n\n return decorativePatterns.some(pattern =>\n parentClass.includes(pattern) || parentClass.includes(`${pattern}_`)\n );\n}\n\n/**\n * Check if element is inside a button or link\n */\nfunction isInsideButton($: cheerio.CheerioAPI, el: any): boolean {\n const $el = $(el);\n const $button = $el.closest('button, a, NuxtLink, .c_button, .c_icon_button');\n return $button.length > 0;\n}\n\n/**\n * Analyze a Vue file and extract template content\n */\nexport function extractTemplateFromVue(vueContent: string): string {\n const templateMatch = vueContent.match(/<template>([\\s\\S]*?)<\\/template>/);\n if (!templateMatch) {\n return '';\n }\n return templateMatch[1];\n}\n\n/**\n * Detect editable fields from Vue template content\n */\nexport function detectEditableFields(templateHtml: string): {\n fields: Record<string, FieldMapping>;\n collections: Record<string, CollectionMapping>;\n} {\n const $ = cheerio.load(templateHtml);\n const detectedFields: Record<string, FieldMapping> = {};\n const detectedCollections: Record<string, CollectionMapping> = {};\n\n // Track which elements are part of collections\n const collectionElements = new Set<any>();\n const processedCollectionClasses = new Set<string>();\n\n // 1. Detect collections FIRST\n const potentialCollections = new Map<string, any[]>();\n\n $('[class]').each((_, el) => {\n const primaryClass = getPrimaryClass($(el).attr('class'));\n\n // Only detect top-level collection containers\n if (primaryClass && (\n primaryClass.fieldName.includes('card') ||\n primaryClass.fieldName.includes('item') ||\n primaryClass.fieldName.includes('post') ||\n primaryClass.fieldName.includes('feature')\n ) && !primaryClass.fieldName.includes('image') && !primaryClass.fieldName.includes('inner')) {\n if (!potentialCollections.has(primaryClass.fieldName)) {\n potentialCollections.set(primaryClass.fieldName, []);\n }\n potentialCollections.get(primaryClass.fieldName)?.push(el);\n }\n });\n\n // Process collections\n potentialCollections.forEach((elements, className) => {\n if (elements.length >= 2) {\n const $first = $(elements[0]);\n const collectionFields: Record<string, any> = {};\n\n // Mark this collection as processed\n processedCollectionClasses.add(className);\n\n // Mark all elements in this collection\n elements.forEach(el => {\n collectionElements.add(el);\n $(el).find('*').each((_, child) => {\n collectionElements.add(child);\n });\n });\n\n // Get the original selector for the collection\n const collectionClassInfo = getPrimaryClass($(elements[0]).attr('class'));\n const collectionSelector = collectionClassInfo ? `.${collectionClassInfo.selector}` : `.${className}`;\n\n // Detect fields within collection\n // Images\n // @ts-ignore\n $first.find('img').each((_, img) => {\n if (isInsideButton($, img)) return;\n\n const $img = $(img);\n const $parent = $img.parent();\n const parentClassInfo = getPrimaryClass($parent.attr('class'));\n\n if (parentClassInfo && parentClassInfo.fieldName.includes('image')) {\n collectionFields.image = `.${parentClassInfo.selector}`;\n return false; // Only first image\n }\n });\n\n // Tags/categories\n // @ts-ignore\n $first.find('div').each((_, el) => {\n const classInfo = getPrimaryClass($(el).attr('class'));\n if (classInfo && classInfo.fieldName.includes('tag') && !classInfo.fieldName.includes('container')) {\n collectionFields.tag = `.${classInfo.selector}`;\n return false;\n }\n });\n\n // Headings\n $first.find('h1, h2, h3, h4, h5, h6').first().each((_, el) => {\n const classInfo = getPrimaryClass($(el).attr('class'));\n if (classInfo) {\n collectionFields.title = `.${classInfo.selector}`;\n }\n });\n\n // Descriptions\n $first.find('p').first().each((_, el) => {\n const classInfo = getPrimaryClass($(el).attr('class'));\n if (classInfo) {\n collectionFields.description = `.${classInfo.selector}`;\n }\n });\n\n // Links\n // @ts-ignore\n $first.find('a, NuxtLink').not('.c_button, .c_icon_button').each((_, el) => {\n const $link = $(el);\n const linkText = $link.text().trim();\n\n if (linkText) {\n const classInfo = getPrimaryClass($link.attr('class'));\n collectionFields.link = classInfo ? `.${classInfo.selector}` : 'a';\n return false; // Only first link\n }\n });\n\n if (Object.keys(collectionFields).length > 0) {\n let collectionName = className;\n if (!collectionName.endsWith('s')) {\n collectionName += 's';\n }\n\n detectedCollections[collectionName] = {\n selector: collectionSelector,\n fields: collectionFields,\n };\n }\n }\n });\n\n // 2. Detect individual fields\n const $body = $('body');\n\n // Headings\n $body.find('h1, h2, h3, h4, h5, h6').each((index, el) => {\n if (collectionElements.has(el)) return;\n\n const $el = $(el);\n const text = $el.text().trim();\n const classInfo = getPrimaryClass($el.attr('class'));\n\n if (text) {\n let fieldName: string;\n let selector: string;\n\n if (classInfo && !classInfo.fieldName.startsWith('heading_')) {\n // Has semantic class\n fieldName = classInfo.fieldName;\n selector = `.${classInfo.selector}`;\n } else {\n // Generic heading - use parent context\n const $parent = $el.closest('[class*=\"header\"], [class*=\"hero\"], [class*=\"cta\"]').first();\n const parentClassInfo = getPrimaryClass($parent.attr('class'));\n const modifier = getContextModifier($, $el);\n\n if (parentClassInfo) {\n fieldName = modifier ? `${modifier}_${parentClassInfo.fieldName}` : parentClassInfo.fieldName;\n selector = classInfo ? `.${classInfo.selector}` : `.${parentClassInfo.selector}`;\n } else if (modifier) {\n fieldName = `${modifier}_heading`;\n selector = classInfo ? `.${classInfo.selector}` : el.tagName.toLowerCase();\n } else {\n fieldName = `heading_${index}`;\n selector = classInfo ? `.${classInfo.selector}` : el.tagName.toLowerCase();\n }\n }\n\n detectedFields[fieldName] = {\n selector: selector,\n type: 'plain',\n editable: true,\n };\n }\n });\n\n // Paragraphs\n $body.find('p').each((_index, el) => {\n if (collectionElements.has(el)) return;\n\n const $el = $(el);\n const text = $el.text().trim();\n const classInfo = getPrimaryClass($el.attr('class'));\n\n if (text && text.length > 20 && classInfo) {\n const hasFormatting = $el.find('strong, em, b, i, a, NuxtLink').length > 0;\n\n detectedFields[classInfo.fieldName] = {\n selector: `.${classInfo.selector}`,\n type: hasFormatting ? 'rich' : 'plain',\n editable: true,\n };\n }\n });\n\n // Content images only (skip decorative)\n $body.find('img').each((_index, el) => {\n if (collectionElements.has(el)) return;\n if (isInsideButton($, el)) return;\n\n const $el = $(el);\n\n // Skip decorative images\n if (isDecorativeImage($, $el)) return;\n\n const $parent = $el.parent();\n const parentClassInfo = getPrimaryClass($parent.attr('class'));\n\n if (parentClassInfo) {\n const fieldName = parentClassInfo.fieldName.includes('image')\n ? parentClassInfo.fieldName\n : `${parentClassInfo.fieldName}_image`;\n\n detectedFields[fieldName] = {\n selector: `.${parentClassInfo.selector}`,\n type: 'image',\n editable: true,\n };\n }\n });\n\n // Button text\n $body.find('NuxtLink.c_button, a.c_button, .c_button').each((_index, el) => {\n if (collectionElements.has(el)) return;\n\n const $el = $(el);\n const text = $el.contents().filter(function() {\n return this.type === 'text' || (this.type === 'tag' && this.name === 'div');\n }).first().text().trim();\n\n if (text && text.length > 2) {\n const $parent = $el.closest('[class*=\"cta\"]').first();\n const parentClassInfo = getPrimaryClass($parent.attr('class'));\n const fieldName = parentClassInfo ? `${parentClassInfo.fieldName}_button_text` : 'button_text';\n\n detectedFields[fieldName] = {\n selector: `.c_button`,\n type: 'plain',\n editable: true,\n };\n }\n });\n\n return {\n fields: detectedFields,\n collections: detectedCollections,\n };\n}\n\n/**\n * Analyze all Vue pages in a directory\n */\nexport async function analyzeVuePages(pagesDir: string): Promise<Record<string, {\n fields: Record<string, FieldMapping>;\n collections: Record<string, CollectionMapping>;\n}>> {\n const results: Record<string, any> = {};\n\n const vueFiles = await fs.readdir(pagesDir);\n\n for (const file of vueFiles) {\n if (file.endsWith('.vue')) {\n const filePath = path.join(pagesDir, file);\n const content = await fs.readFile(filePath, 'utf-8');\n const template = extractTemplateFromVue(content);\n\n if (template) {\n const pageName = file.replace('.vue', '');\n results[pageName] = detectEditableFields(template);\n }\n }\n }\n\n return results;\n}\n","/**\n * Transform CMS manifest to Strapi schemas\n */\n\nimport type { CMSManifest, StrapiSchema, FieldMapping } from '@see-ms/types';\n\n/**\n * Map field type to Strapi field type\n */\nfunction mapFieldTypeToStrapi(fieldType: string): string {\n const typeMap: Record<string, string> = {\n plain: 'string',\n rich: 'richtext',\n html: 'richtext',\n image: 'media',\n link: 'string',\n email: 'email',\n phone: 'string',\n };\n\n return typeMap[fieldType] || 'string';\n}\n\n/**\n * Generate proper plural form for a word\n */\nfunction pluralize(word: string): string {\n // Handle special cases\n if (word.endsWith('s') || word.endsWith('x') || word.endsWith('z') ||\n word.endsWith('ch') || word.endsWith('sh')) {\n return word + 'es';\n }\n\n // Handle words ending in 'y' preceded by consonant\n if (word.endsWith('y') && word.length > 1) {\n const secondLast = word[word.length - 2];\n if (!'aeiou'.includes(secondLast.toLowerCase())) {\n return word.slice(0, -1) + 'ies';\n }\n }\n\n // Default: just add 's'\n return word + 's';\n}\n\n/**\n * Convert a page manifest to a Strapi schema (single type)\n */\nfunction pageToStrapiSchema(pageName: string, fields: Record<string, FieldMapping>): StrapiSchema {\n const attributes: Record<string, any> = {};\n\n // Convert each field\n for (const [fieldName, field] of Object.entries(fields)) {\n attributes[fieldName] = {\n type: mapFieldTypeToStrapi(field.type),\n required: field.required || false,\n };\n\n if (field.default) {\n attributes[fieldName].default = field.default;\n }\n }\n\n // Generate display name\n const displayName = pageName\n .split('-')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n\n // Use kebab-case consistently (keep the original pageName format)\n // This matches Strapi conventions and avoids conversion issues\n const kebabCaseName = pageName;\n\n // Generate plural name\n const pluralName = pluralize(kebabCaseName);\n\n return {\n kind: 'singleType',\n collectionName: kebabCaseName,\n info: {\n singularName: kebabCaseName,\n pluralName: pluralName,\n displayName: displayName,\n },\n options: {\n draftAndPublish: true,\n },\n attributes,\n };\n}\n\n/**\n * Convert a collection to a Strapi schema (collection type)\n */\nfunction collectionToStrapiSchema(\n collectionName: string,\n collection: any\n): StrapiSchema {\n const attributes: Record<string, any> = {};\n\n // Convert each field in the collection\n for (const [fieldName, _selector] of Object.entries(collection.fields)) {\n // Determine type based on field name\n let type = 'string';\n\n if (fieldName === 'image' || fieldName.includes('image')) {\n type = 'media';\n } else if (fieldName === 'description' || fieldName === 'content') {\n type = 'richtext';\n } else if (fieldName === 'link' || fieldName === 'url') {\n type = 'string';\n } else if (fieldName === 'title' || fieldName === 'tag') {\n type = 'string';\n }\n\n attributes[fieldName] = {\n type,\n };\n }\n\n // Generate display name\n const displayName = collectionName\n .split(/[-_]/)\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n\n // Convert underscores to kebab-case for consistency\n const kebabCaseName = collectionName.replace(/_/g, '-');\n\n // Get singular name (remove trailing 's')\n const singularName = kebabCaseName.endsWith('s')\n ? kebabCaseName.slice(0, -1)\n : kebabCaseName;\n\n return {\n kind: 'collectionType',\n collectionName: kebabCaseName,\n info: {\n singularName: singularName,\n pluralName: kebabCaseName,\n displayName: displayName,\n },\n options: {\n draftAndPublish: true,\n },\n attributes,\n };\n}\n\n/**\n * Transform entire manifest to Strapi schemas\n */\nexport function manifestToSchemas(manifest: CMSManifest): Record<string, StrapiSchema> {\n const schemas: Record<string, StrapiSchema> = {};\n\n // Convert pages to single types\n for (const [pageName, page] of Object.entries(manifest.pages)) {\n // Only create schema if page has fields\n if (page.fields && Object.keys(page.fields).length > 0) {\n schemas[pageName] = pageToStrapiSchema(pageName, page.fields);\n }\n\n // Convert collections to collection types\n if (page.collections) {\n for (const [collectionName, collection] of Object.entries(page.collections)) {\n schemas[collectionName] = collectionToStrapiSchema(collectionName, collection);\n }\n }\n }\n\n return schemas;\n}\n","/**\n * Write Strapi schemas to disk\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport type { StrapiSchema } from '@see-ms/types';\n\n/**\n * Write a single Strapi schema to a flat directory\n */\nexport async function writeStrapiSchema(\n outputDir: string,\n name: string,\n schema: StrapiSchema\n): Promise<void> {\n const schemasDir = path.join(outputDir, 'cms-schemas');\n await fs.ensureDir(schemasDir);\n \n const schemaPath = path.join(schemasDir, `${name}.json`);\n await fs.writeFile(schemaPath, JSON.stringify(schema, null, 2), 'utf-8');\n}\n\n/**\n * Write all schemas\n */\nexport async function writeAllSchemas(\n outputDir: string,\n schemas: Record<string, StrapiSchema>\n): Promise<void> {\n for (const [name, schema] of Object.entries(schemas)) {\n await writeStrapiSchema(outputDir, name, schema);\n }\n}\n\n/**\n * Create a README for the CMS schemas\n */\nexport async function createStrapiReadme(outputDir: string): Promise<void> {\n const readmePath = path.join(outputDir, 'cms-schemas', 'README.md');\n \n const content = `# CMS Schemas\n\nAuto-generated Strapi content type schemas from your Webflow export.\n\n## What's in this folder?\n\nEach \\`.json\\` file is a Strapi content type schema:\n\n- **Pages** (single types) - Unique pages like \\`index.json\\`, \\`about.json\\`\n- **Collections** (collection types) - Repeating content like \\`portfolio_cards.json\\`\n\n## How to use with Strapi\n\n### Option 1: Manual Setup (Recommended for learning)\n\n1. Start your Strapi project\n2. In Strapi admin, go to **Content-Type Builder**\n3. Create each content type manually using these schemas as reference\n4. Match the field names and types\n\n### Option 2: Automated Setup (Advanced)\n\nCopy schemas to your Strapi project structure:\n\n\\`\\`\\`bash\n# For each schema file, create the Strapi directory structure\n# Example for index.json (single type):\nmkdir -p strapi/src/api/index/content-types/index\ncp cms-schemas/index.json strapi/src/api/index/content-types/index/schema.json\n\n# Example for portfolio_cards.json (collection type):\nmkdir -p strapi/src/api/portfolio-cards/content-types/portfolio-card\ncp cms-schemas/portfolio_cards.json strapi/src/api/portfolio-cards/content-types/portfolio-card/schema.json\n\\`\\`\\`\n\nThen restart Strapi - it will auto-create the content types.\n\n## Schema Structure\n\nEach schema defines:\n- \\`kind\\`: \"singleType\" (unique page) or \"collectionType\" (repeating)\n- \\`attributes\\`: Fields and their types (string, richtext, media, etc.)\n- \\`displayName\\`: How it appears in Strapi admin\n\n## Field Types\n\n- \\`string\\` - Plain text\n- \\`richtext\\` - Formatted text with HTML\n- \\`media\\` - Image uploads\n\n## Next Steps\n\n1. Set up a Strapi project: \\`npx create-strapi-app@latest my-strapi\\`\n2. Use these schemas to create content types\n3. Populate content in Strapi admin\n4. Connect your Nuxt app to Strapi API\n\n## API Usage in Nuxt\n\nOnce Strapi is running with these content types:\n\n\\`\\`\\`typescript\n// Fetch single type (e.g., home page)\nconst { data } = await $fetch('http://localhost:1337/api/index')\n\n// Fetch collection type (e.g., portfolio cards)\nconst { data } = await $fetch('http://localhost:1337/api/portfolio-cards')\n\\`\\`\\`\n`;\n \n await fs.writeFile(readmePath, content, 'utf-8');\n}\n","/**\n * Content Extractor\n * Extracts actual content values from HTML based on cms-manifest selectors\n */\n\nimport type { CMSManifest, PageManifest } from '@see-ms/types';\nimport * as cheerio from 'cheerio';\nimport path from 'path';\n\nexport interface ExtractedContent {\n pages: Record<string, PageContent>;\n}\n\nexport interface PageContent {\n fields: Record<string, string>;\n collections: Record<string, CollectionItem[]>;\n}\n\nexport interface CollectionItem {\n [key: string]: string;\n}\n\n/**\n * Extract content from HTML based on manifest selectors\n */\nexport function extractContentFromHTML(\n html: string,\n _pageName: string,\n pageManifest: PageManifest\n): PageContent {\n const $ = cheerio.load(html);\n\n const content: PageContent = {\n fields: {},\n collections: {},\n };\n\n // Extract single fields\n if (pageManifest.fields) {\n for (const [fieldName, field] of Object.entries(pageManifest.fields)) {\n const selector = field.selector;\n const element = $(selector).first();\n\n if (element.length > 0) {\n if (field.type === 'image') {\n // Extract image src\n const src = element.attr('src') || element.find('img').attr('src') || '';\n content.fields[fieldName] = src;\n } else {\n // Extract text content\n const text = element.text().trim();\n content.fields[fieldName] = text;\n }\n }\n }\n }\n\n // Extract collections\n if (pageManifest.collections) {\n for (const [collectionName, collection] of Object.entries(pageManifest.collections)) {\n const items: CollectionItem[] = [];\n const collectionElements = $(collection.selector);\n\n collectionElements.each((_, elem) => {\n const item: CollectionItem = {};\n const $elem = $(elem);\n\n // Extract each field within the collection item\n for (const [fieldName, fieldSelector] of Object.entries(collection.fields)) {\n const fieldElement = $elem.find(fieldSelector as string).first();\n\n if (fieldElement.length > 0) {\n // Check if it's an image field\n if (fieldName === 'image' || fieldName.includes('image')) {\n const src = fieldElement.attr('src') || fieldElement.find('img').attr('src') || '';\n item[fieldName] = src;\n } else if (fieldName === 'link' || fieldName === 'url') {\n const href = fieldElement.attr('href') || '';\n item[fieldName] = href;\n } else {\n // Extract text\n const text = fieldElement.text().trim();\n item[fieldName] = text;\n }\n }\n }\n\n // Only add item if it has some content\n if (Object.keys(item).length > 0) {\n items.push(item);\n }\n });\n\n if (items.length > 0) {\n content.collections[collectionName] = items;\n }\n }\n }\n\n return content;\n}\n\n/**\n * Extract content from all pages based on manifest\n */\nexport function extractAllContent(\n htmlFiles: Map<string, string>,\n manifest: CMSManifest\n): ExtractedContent {\n const extractedContent: ExtractedContent = {\n pages: {},\n };\n\n for (const [pageName, pageManifest] of Object.entries(manifest.pages)) {\n const html = htmlFiles.get(pageName);\n\n if (html) {\n const content = extractContentFromHTML(html, pageName, pageManifest);\n extractedContent.pages[pageName] = content;\n }\n }\n\n return extractedContent;\n}\n\n/**\n * Normalize image paths for seed data\n * Converts absolute/relative paths to public asset paths\n */\nexport function normalizeImagePath(imageSrc: string): string {\n if (!imageSrc) return '';\n\n // If it's already a relative path starting with /, keep it\n if (imageSrc.startsWith('/')) return imageSrc;\n\n // If it's in images folder, normalize to /images/filename\n const filename = path.basename(imageSrc);\n\n if (imageSrc.includes('images/')) {\n return `/images/${filename}`;\n }\n\n // Default: assume it's in public root\n return `/${filename}`;\n}\n\n/**\n * Convert extracted content to Strapi seed format\n */\nexport function formatForStrapi(extracted: ExtractedContent): Record<string, any> {\n const seedData: Record<string, any> = {};\n\n for (const [pageName, content] of Object.entries(extracted.pages)) {\n // Format single type fields\n if (Object.keys(content.fields).length > 0) {\n const formattedFields: Record<string, any> = {};\n\n for (const [fieldName, value] of Object.entries(content.fields)) {\n // Normalize image paths\n if (fieldName.includes('image') || fieldName.includes('bg')) {\n formattedFields[fieldName] = normalizeImagePath(value);\n } else {\n formattedFields[fieldName] = value;\n }\n }\n\n seedData[pageName] = formattedFields;\n }\n\n // Format collection types\n for (const [collectionName, items] of Object.entries(content.collections)) {\n const formattedItems = items.map(item => {\n const formattedItem: Record<string, any> = {};\n\n for (const [fieldName, value] of Object.entries(item)) {\n // Normalize image paths\n if (fieldName === 'image' || fieldName.includes('image')) {\n formattedItem[fieldName] = normalizeImagePath(value);\n } else {\n formattedItem[fieldName] = value;\n }\n }\n\n return formattedItem;\n });\n\n seedData[collectionName] = formattedItems;\n }\n }\n\n return seedData;\n}\n","/**\n * Seed Data Writer\n * Writes extracted content to seed data files\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\n\n/**\n * Write seed data to JSON file\n */\nexport async function writeSeedData(\n outputDir: string,\n seedData: Record<string, any>\n): Promise<void> {\n const seedDir = path.join(outputDir, 'cms-seed');\n await fs.ensureDir(seedDir);\n\n const seedPath = path.join(seedDir, 'seed-data.json');\n await fs.writeJson(seedPath, seedData, { spaces: 2 });\n}\n\n/**\n * Create README for seed data\n */\nexport async function createSeedReadme(outputDir: string): Promise<void> {\n const readmePath = path.join(outputDir, 'cms-seed', 'README.md');\n\n const content = `# CMS Seed Data\n\nAuto-extracted content from your Webflow export, ready to seed into Strapi.\n\n## What's in this folder?\n\n\\`seed-data.json\\` contains the actual content extracted from your HTML:\n- **Single types** - Page-specific content (homepage, about page, etc.)\n- **Collection types** - Repeating items (portfolio cards, team members, etc.)\n\n## Structure\n\n\\`\\`\\`json\n{\n \"index\": {\n \"hero_heading_container\": \"Actual heading from HTML\",\n \"hero_bg_image\": \"/images/hero.jpg\",\n ...\n },\n \"portfolio_cards\": [\n {\n \"image\": \"/images/card1.jpg\",\n \"tag\": \"Technology\",\n \"description\": \"Card description\"\n }\n ]\n}\n\\`\\`\\`\n\n## How to Seed Strapi\n\n### Option 1: Manual Entry\n1. Open Strapi admin panel\n2. Go to Content Manager\n3. Create entries using the data from \\`seed-data.json\\`\n\n### Option 2: Automated Seeding (Coming Soon)\nWe'll provide a seeding script that:\n1. Uploads images to Strapi media library\n2. Creates content entries via Strapi API\n3. Handles relationships between content types\n\n## Image Paths\n\nImage paths in the seed data reference files in your Nuxt \\`public/\\` directory:\n- \\`/images/hero.jpg\\` → \\`public/images/hero.jpg\\`\n\nWhen seeding Strapi, these images will be uploaded to Strapi's media library.\n\n## Next Steps\n\n1. Review the extracted data for accuracy\n2. Set up your Strapi instance with the schemas from \\`cms-schemas/\\`\n3. Use this seed data to populate your CMS\n`;\n\n await fs.writeFile(readmePath, content, 'utf-8');\n}\n","/**\n * Strapi Complete Setup Script\n * Installs schemas, uploads images, and seeds content - all in one command\n */\n\nimport fs from \"fs-extra\";\nimport path from \"path\";\nimport { glob } from \"glob\";\nimport * as readline from \"readline\";\n\n// @ts-ignore\ninterface SchemaFile {\n name: string;\n path: string;\n schema: any;\n}\n\ninterface SetupOptions {\n projectDir: string;\n strapiDir: string;\n strapiUrl?: string;\n apiToken?: string;\n ignoreSavedToken?: boolean;\n}\n\nconst ENV_FILE = \".env\";\n\n/**\n * Load config from .env file in project directory\n */\nasync function loadConfig(projectDir: string): Promise<{ apiToken?: string; strapiUrl?: string }> {\n const envPath = path.join(projectDir, ENV_FILE);\n if (await fs.pathExists(envPath)) {\n try {\n const content = await fs.readFile(envPath, \"utf-8\");\n const config: { apiToken?: string; strapiUrl?: string } = {};\n\n for (const line of content.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n\n const [key, ...valueParts] = trimmed.split(\"=\");\n const value = valueParts.join(\"=\").trim();\n\n if (key === \"STRAPI_API_TOKEN\") {\n config.apiToken = value;\n } else if (key === \"STRAPI_URL\") {\n config.strapiUrl = value;\n }\n }\n return config;\n } catch {\n return {};\n }\n }\n return {};\n}\n\n/**\n * Save/append config to .env file in project directory\n */\nasync function saveConfig(projectDir: string, config: { apiToken?: string; strapiUrl?: string }): Promise<void> {\n const envPath = path.join(projectDir, ENV_FILE);\n let content = \"\";\n\n // Read existing content if file exists\n if (await fs.pathExists(envPath)) {\n content = await fs.readFile(envPath, \"utf-8\");\n\n // Remove existing STRAPI_ entries to avoid duplicates\n content = content\n .split(\"\\n\")\n .filter(line => !line.startsWith(\"STRAPI_API_TOKEN=\") && !line.startsWith(\"STRAPI_URL=\"))\n .join(\"\\n\");\n\n if (content && !content.endsWith(\"\\n\")) {\n content += \"\\n\";\n }\n }\n\n // Add new values\n if (config.strapiUrl) {\n content += `STRAPI_URL=${config.strapiUrl}\\n`;\n }\n if (config.apiToken) {\n content += `STRAPI_API_TOKEN=${config.apiToken}\\n`;\n }\n\n await fs.writeFile(envPath, content);\n}\n\n\n/**\n * Main setup function\n * Exported for use by CLI and direct execution\n */\nexport async function completeSetup(options: SetupOptions): Promise<void> {\n const { projectDir, strapiDir, strapiUrl: optionUrl, apiToken: optionToken, ignoreSavedToken } = options;\n\n // Load saved config\n const savedConfig = await loadConfig(projectDir);\n const strapiUrl = optionUrl || savedConfig.strapiUrl || \"http://localhost:1337\";\n\n console.log(\"🚀 Starting complete Strapi setup...\\n\");\n\n // Step 1: Install schemas\n console.log(\"📦 Step 1: Installing schemas...\");\n await installSchemas(projectDir, strapiDir);\n console.log(\"✓ Schemas installed\\n\");\n\n // Step 2: Wait for user to restart Strapi\n console.log(\"⏸️ Step 2: Restart Strapi to load schemas\");\n console.log(\" Run: npm run develop (in Strapi directory)\");\n console.log(\" Press Enter when Strapi is running...\");\n\n await waitForEnter();\n\n // Step 3: Check Strapi is running\n console.log(\"\\n🔍 Step 3: Checking Strapi connection...\");\n const isRunning = await checkStrapiRunning(strapiUrl);\n\n if (!isRunning) {\n console.error(\"❌ Cannot connect to Strapi at\", strapiUrl);\n console.log(\" Make sure Strapi is running: npm run develop\");\n process.exit(1);\n }\n\n console.log(\"✓ Connected to Strapi\\n\");\n\n // Step 4: Get API token\n let token = optionToken || (!ignoreSavedToken ? savedConfig.apiToken : undefined);\n if (token && !ignoreSavedToken) {\n console.log(\"🔑 Step 4: Using saved API token\");\n } else if (token && optionToken) {\n console.log(\"🔑 Step 4: Using provided API token\");\n } else {\n console.log(\"🔑 Step 4: API Token needed\");\n console.log(\" 1. Open Strapi admin: http://localhost:1337/admin\");\n console.log(\" 2. Go to Settings > API Tokens > Create new API Token\");\n console.log(\" 3. Name: \\\"Seed Script\\\", Type: \\\"Full access\\\", Duration: \\\"Unlimited\\\"\");\n console.log(\" 4. Copy the token and paste it here:\\n\");\n\n token = await promptForToken();\n\n // Ask to save token\n const saveToken = await promptYesNo(\" Save token for future use?\");\n if (saveToken) {\n await saveConfig(projectDir, { ...savedConfig, apiToken: token, strapiUrl });\n console.log(\" ✓ Token saved to .env\");\n }\n console.log(\"\");\n }\n\n // Step 5: Upload images\n console.log(\"📸 Step 5: Uploading images...\");\n const mediaMap = await uploadAllImages(projectDir, strapiUrl, token);\n console.log(`✓ Uploaded ${Object.keys(mediaMap).length} images\\n`);\n\n // Step 6: Seed content\n console.log(\"📝 Step 6: Seeding content...\");\n await seedContent(projectDir, strapiUrl, token, mediaMap);\n console.log(\"✓ Content seeded\\n\");\n\n console.log(\"✅ Complete setup finished!\");\n console.log(\"\\n📋 Next steps:\");\n console.log(\" 1. Open Strapi admin: http://localhost:1337/admin\");\n console.log(\" 2. Check Content Manager - your content should be there!\");\n console.log(\" 3. Connect your Nuxt app to Strapi API\");\n}\n\n/**\n * Install all schemas from cms-schemas folder into Strapi\n */\nasync function installSchemas(\n projectDir: string,\n strapiDir: string\n): Promise<void> {\n // Validate strapi directory exists\n if (!(await fs.pathExists(strapiDir))) {\n console.error(` ✗ Strapi directory not found: ${strapiDir}`);\n console.error(` Resolved to: ${path.resolve(strapiDir)}`);\n throw new Error(`Strapi directory not found: ${strapiDir}`);\n }\n // Check it's actually a Strapi project\n const packageJsonPath = path.join(strapiDir, \"package.json\");\n if (await fs.pathExists(packageJsonPath)) {\n const pkg = await fs.readJson(packageJsonPath);\n if (!pkg.dependencies?.[\"@strapi/strapi\"]) {\n console.warn(` ⚠️ Warning: ${strapiDir} may not be a Strapi project`);\n }\n }\n\n const schemaDir = path.join(projectDir, \"cms-schemas\");\n\n const schemaFiles = await glob(\"*.json\", {\n cwd: schemaDir,\n absolute: false\n });\n\n if (schemaFiles.length === 0) {\n console.log(\"⚠️ No schema files found\");\n return;\n }\n\n console.log(` Found ${schemaFiles.length} schema file(s)`);\n\n for (const file of schemaFiles) {\n const schemaPath = path.join(schemaDir, file);\n const schema = await fs.readJson(schemaPath);\n const singularName =\n schema.info?.singularName || path.basename(file, \".json\");\n console.log(` Installing ${singularName}...`);\n try {\n // Create the Strapi API structure manually (strapi generate is interactive)\n const apiPath = path.join(strapiDir, \"src\", \"api\", singularName);\n const contentTypesPath = path.join(\n apiPath,\n \"content-types\",\n singularName\n );\n const targetPath = path.join(contentTypesPath, \"schema.json\");\n\n // Create directories\n await fs.ensureDir(contentTypesPath);\n await fs.ensureDir(path.join(apiPath, \"routes\"));\n await fs.ensureDir(path.join(apiPath, \"controllers\"));\n await fs.ensureDir(path.join(apiPath, \"services\"));\n\n // Write the schema\n await fs.writeJson(targetPath, schema, { spaces: 2 });\n\n // Create TypeScript route file (Strapi 5 format)\n const routeContent = `import { factories } from '@strapi/strapi';\n export default factories.createCoreRouter('api::${singularName}.${singularName}');\n `;\n await fs.writeFile(\n path.join(apiPath, \"routes\", `${singularName}.ts`),\n routeContent\n );\n\n // Create TypeScript controller file\n const controllerContent = `import { factories } from '@strapi/strapi';\n export default factories.createCoreController('api::${singularName}.${singularName}');\n `;\n await fs.writeFile(\n path.join(apiPath, \"controllers\", `${singularName}.ts`),\n controllerContent\n );\n\n // Create TypeScript service file\n const serviceContent = `import { factories } from '@strapi/strapi';\n export default factories.createCoreService('api::${singularName}.${singularName}');\n `;\n await fs.writeFile(\n path.join(apiPath, \"services\", `${singularName}.ts`),\n serviceContent\n );\n } catch (error: any) {\n console.error(` ✗ Failed to install ${singularName}: ${error.message}`);\n }\n }\n}\n\n/**\n * Check if Strapi is running\n */\nasync function checkStrapiRunning(strapiUrl: string): Promise<boolean> {\n try {\n const response = await fetch(`${strapiUrl}/_health`);\n return response.ok;\n } catch {\n return false;\n }\n}\n\nfunction createReadline(): readline.Interface {\n return readline.createInterface({\n input: process.stdin,\n output: process.stdout\n });\n}\n\n/**\n * Wait for user to press Enter\n */\nasync function waitForEnter(): Promise<void> {\n const rl = createReadline();\n return new Promise((resolve) => {\n rl.question(\"\", () => {\n rl.close();\n resolve();\n });\n });\n}\n\n/**\n * Prompt user for API token\n */\nasync function promptForToken(): Promise<string> {\n const rl = createReadline();\n\n return new Promise((resolve) => {\n rl.question(\" Token: \", (answer) => {\n rl.close();\n resolve(answer.trim());\n });\n });\n}\n\n/**\n * Prompt user for yes/no\n */\nasync function promptYesNo(question: string): Promise<boolean> {\n const rl = createReadline();\n return new Promise((resolve) => {\n rl.question(`${question} (y/n): `, (answer) => {\n rl.close();\n resolve(answer.trim().toLowerCase() === \"y\" || answer.trim().toLowerCase() === \"yes\");\n });\n });\n}\n\n/**\n * Fetch existing media from Strapi\n * Returns a map of filename to media ID\n */\n\nasync function getExistingMedia(\n strapiUrl: string,\n apiToken: string\n): Promise<Map<string, number>> {\n\n const existingMedia = new Map<string, number>();\n try {\n // Fetch all files from Strapi media library (paginated)\n let page = 1;\n const pageSize = 100;\n let hasMore = true;\n\n while (hasMore) {\n const response = await fetch(\n `${strapiUrl}/api/upload/files?pagination[page]=${page}&pagination[pageSize]=${pageSize}`,\n {\n headers: {\n Authorization: `Bearer ${apiToken}`\n }\n }\n );\n\n if (!response.ok) {\n break;\n }\n\n const data = await response.json();\n // @ts-ignore\n const files = Array.isArray(data) ? data : data.results || [];\n\n for (const file of files) {\n if (file.name) {\n existingMedia.set(file.name, file.id);\n }\n }\n\n hasMore = files.length === pageSize;\n page++;\n }\n } catch (error) {\n // Silently continue - we'll just upload all images\n }\n return existingMedia;\n}\n\n/**\n * Upload all images to Strapi media library\n * Returns a map of original paths to Strapi media IDs\n */\nasync function uploadAllImages(\n projectDir: string,\n strapiUrl: string,\n apiToken: string\n): Promise<Map<string, number>> {\n const mediaMap = new Map<string, number>();\n const imagesDir = path.join(projectDir, \"public\", \"assets\", \"images\");\n\n if (!(await fs.pathExists(imagesDir))) {\n console.log(\" No images directory found\");\n return mediaMap;\n }\n\n const imageFiles = await glob(\"**/*.{jpg,jpeg,png,gif,webp,svg}\", {\n cwd: imagesDir,\n absolute: false\n });\n\n // Fetch existing media to skip duplicates\n console.log(` Checking for existing media...`);\n const existingMedia = await getExistingMedia(strapiUrl, apiToken);\n let uploadedCount = 0;\n let skippedCount = 0;\n console.log(` Processing ${imageFiles.length} images...`);\n\n for (const imageFile of imageFiles) {\n const fileName = path.basename(imageFile);\n\n // Check if file already exists\n const existingId = existingMedia.get(fileName);\n\n if (existingId) {\n // Use existing media ID\n mediaMap.set(`/images/${imageFile}`, existingId);\n mediaMap.set(imageFile, existingId);\n skippedCount++;\n continue;\n }\n\n // Upload new image\n const imagePath = path.join(imagesDir, imageFile);\n const mediaId = await uploadImage(imagePath, imageFile, strapiUrl, apiToken);\n\n if (mediaId) {\n mediaMap.set(`/images/${imageFile}`, mediaId);\n mediaMap.set(imageFile, mediaId);\n uploadedCount++;\n console.log(` ✓ ${imageFile}`);\n }\n }\n console.log(` Uploaded: ${uploadedCount}, Skipped (existing): ${skippedCount}`);\n return mediaMap;\n}\n\n/**\n * Upload a single image to Strapi\n */\nasync function uploadImage(\n filePath: string,\n fileName: string,\n strapiUrl: string,\n apiToken: string\n): Promise<number | null> {\n try {\n // Read file as buffer and create Blob\n const fileBuffer = await fs.readFile(filePath);\n const mimeType = getMimeType(fileName);\n const blob = new Blob([fileBuffer], { type: mimeType });\n\n // Use native FormData (works with native fetch)\n const formData = new globalThis.FormData();\n formData.append(\"files\", blob, fileName);\n\n const response = await fetch(`${strapiUrl}/api/upload`, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiToken}`\n },\n body: formData\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(\n ` ✗ Failed to upload ${fileName}: ${response.status} - ${errorText}`\n );\n return null;\n }\n const data = await response.json();\n\n // @ts-ignore\n return data[0]?.id || null;\n } catch (error) {\n console.error(` ✗ Error uploading ${fileName}:`, error);\n return null;\n }\n}\n\n\nfunction getMimeType(fileName: string): string {\n const ext = path.extname(fileName).toLowerCase();\n const mimeTypes: Record<string, string> = {\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".png\": \"image/png\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\"\n };\n return mimeTypes[ext] || \"application/octet-stream\";\n}\n\n/**\n * Seed all content from seed-data.json\n */\nasync function seedContent(\n projectDir: string,\n strapiUrl: string,\n apiToken: string,\n mediaMap: Map<string, number>\n): Promise<void> {\n const seedPath = path.join(projectDir, \"cms-seed\", \"seed-data.json\");\n\n if (!(await fs.pathExists(seedPath))) {\n console.log(\" No seed data found\");\n return;\n }\n\n const seedData = await fs.readJson(seedPath);\n\n const schemasDir = path.join(projectDir, \"cms-schemas\");\n const schemas = new Map<string, any>();\n\n const schemaFiles = await glob(\"*.json\", { cwd: schemasDir });\n for (const file of schemaFiles) {\n const schema = await fs.readJson(path.join(schemasDir, file));\n const name = path.basename(file, \".json\");\n schemas.set(name, schema);\n }\n\n let successCount = 0;\n let totalCount = 0;\n\n for (const [contentType, data] of Object.entries(seedData)) {\n const schema = schemas.get(contentType);\n\n if (!schema) {\n console.log(` ⚠️ No schema found for ${contentType}, skipping...`);\n continue;\n }\n\n const singularName = schema.info.singularName;\n const pluralName = schema.info.pluralName;\n\n // Check if it's a collection (array) or single type (object)\n if (Array.isArray(data)) {\n // Collection type - use pluralName\n console.log(` Seeding ${contentType} (${data.length} items)...`);\n\n for (const item of data) {\n totalCount++;\n const processedItem = processMediaFields(item, mediaMap);\n const success = await createEntry(\n pluralName,\n processedItem,\n strapiUrl,\n apiToken\n );\n if (success) successCount++;\n }\n } else {\n // Single type - use singularName\n console.log(` Seeding ${contentType}...`);\n totalCount++;\n const processedData = processMediaFields(data, mediaMap);\n const success = await createOrUpdateSingleType(\n singularName,\n processedData,\n strapiUrl,\n apiToken\n );\n if (success) successCount++;\n }\n }\n\n console.log(` ✓ Successfully seeded ${successCount}/${totalCount} entries`);\n}\n\n/**\n * Process an object to replace image paths with media IDs\n */\nfunction processMediaFields(data: any, mediaMap: Map<string, number>): any {\n const processed: any = {};\n\n for (const [key, value] of Object.entries(data)) {\n if (typeof value === \"string\") {\n // Check if this is an image path\n if (\n key.includes(\"image\") ||\n key.includes(\"bg\") ||\n value.startsWith(\"/images/\")\n ) {\n const mediaId = mediaMap.get(value);\n if (mediaId) {\n processed[key] = mediaId;\n } else {\n processed[key] = value; // Keep original if not found\n }\n } else {\n processed[key] = value;\n }\n } else {\n processed[key] = value;\n }\n }\n\n return processed;\n}\n\n/**\n * Create a collection entry\n */\nasync function createEntry(\n contentType: string,\n data: any,\n strapiUrl: string,\n apiToken: string\n): Promise<boolean> {\n try {\n const response = await fetch(`${strapiUrl}/api/${contentType}`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiToken}`\n },\n body: JSON.stringify({ data })\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(\n ` ✗ Failed to create ${contentType}: ${response.status} - ${errorText}`\n );\n return false;\n }\n\n return true;\n } catch (error) {\n console.error(` ✗ Error creating ${contentType}:`, error);\n return false;\n }\n}\n\n/**\n * Create or update a single type entry\n */\nasync function createOrUpdateSingleType(\n contentType: string,\n data: any,\n strapiUrl: string,\n apiToken: string\n): Promise<boolean> {\n try {\n const response = await fetch(`${strapiUrl}/api/${contentType}`, {\n method: \"PUT\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiToken}`\n },\n body: JSON.stringify({ data })\n });\n\n if (!response.ok) {\n const errorText = await response.text();\n console.error(\n ` ✗ Failed to update ${contentType}: ${response.status} - ${errorText}`\n );\n return false;\n }\n\n return true;\n } catch (error) {\n console.error(` ✗ Error updating ${contentType}:`, error);\n return false;\n }\n}\n\n/**\n * CLI wrapper\n */\nasync function main() {\n const args = process.argv.slice(2);\n\n if (args.length < 2) {\n console.log(\n \"Usage: tsx strapi-setup.ts <project-dir> <strapi-dir> [strapi-url] [api-token]\"\n );\n console.log(\"\");\n console.log(\"Example:\");\n console.log(\" tsx strapi-setup.ts ./nuxt-project ./strapi-dev\");\n console.log(\n \" tsx strapi-setup.ts ./nuxt-project ./strapi-dev http://localhost:1337 abc123\"\n );\n process.exit(1);\n }\n\n const [projectDir, strapiDir, strapiUrl, apiToken] = args;\n\n await completeSetup({\n projectDir,\n strapiDir,\n strapiUrl,\n apiToken\n });\n}\n\n// Run if executed directly (ESM compatible)\n// When imported, this won't run. When executed directly, it will.\nconst isMainModule =\n process.argv[1] && process.argv[1].endsWith(\"strapi-setup.ts\");\nif (isMainModule) {\n main().catch((error) => {\n console.error(\"❌ Setup failed:\", error.message);\n process.exit(1);\n });\n}\n"],"mappings":"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","names":["pc","readline","fs","path","pc","path","fs","path","fs","path","fs","path","fs","path","execSync","pc","fs","path","cheerio","fs","path","path","fs","fs","path","cheerio","path","fs","path","pc","fs","path","fs","path","glob","pc","fs","path"]}
|