framer-export 4.2.1 → 4.3.0
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/index.js +544 -307
- package/dist/cli/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -15,7 +15,7 @@ var init_package = __esm({
|
|
|
15
15
|
"package.json"() {
|
|
16
16
|
package_default = {
|
|
17
17
|
name: "framer-export",
|
|
18
|
-
version: "4.
|
|
18
|
+
version: "4.3.0",
|
|
19
19
|
description: "Export any Framer, Webflow, or Wix site into a fully working local mirror. Downloads all assets, strips badges, rewrites URLs, and pretty-prints JS.",
|
|
20
20
|
type: "module",
|
|
21
21
|
main: "dist/cli/index.js",
|
|
@@ -92,16 +92,16 @@ function showBanner() {
|
|
|
92
92
|
const isSmall = width < 65;
|
|
93
93
|
if (isSmall) {
|
|
94
94
|
console.log(`
|
|
95
|
-
${chalk.
|
|
95
|
+
${chalk.hex("#D4A017").bold("F-EXPORT")} ${chalk.gray(`v${package_default.version}`)}`);
|
|
96
96
|
console.log(` ${chalk.white.bold("Framer \xB7 Webflow \xB7 Wix Exporter")}
|
|
97
97
|
`);
|
|
98
98
|
return;
|
|
99
99
|
}
|
|
100
|
-
const
|
|
100
|
+
const gold = chalk.hex("#D4A017").bold;
|
|
101
101
|
const gray = chalk.gray;
|
|
102
102
|
console.log("");
|
|
103
103
|
ASCII_ART.forEach((line2) => {
|
|
104
|
-
console.log(" " +
|
|
104
|
+
console.log(" " + gold(line2));
|
|
105
105
|
});
|
|
106
106
|
console.log("");
|
|
107
107
|
console.log(` ${gray(`v${package_default.version}`)} ${chalk.white.bold("Framer \xB7 Webflow \xB7 Wix Exporter")}
|
|
@@ -263,6 +263,13 @@ import chalk3 from "chalk";
|
|
|
263
263
|
function setCooking(spinner) {
|
|
264
264
|
_cooking = spinner;
|
|
265
265
|
}
|
|
266
|
+
function nextMsgColor() {
|
|
267
|
+
return MSG_COLORS[_msgIdx++ % MSG_COLORS.length];
|
|
268
|
+
}
|
|
269
|
+
function trunc(text, max) {
|
|
270
|
+
if (text.length <= max) return text;
|
|
271
|
+
return text.slice(0, max - 2) + "\u2026";
|
|
272
|
+
}
|
|
266
273
|
function output(line2) {
|
|
267
274
|
if (_cooking) {
|
|
268
275
|
_cooking.log(line2);
|
|
@@ -270,20 +277,317 @@ function output(line2) {
|
|
|
270
277
|
console.log(line2);
|
|
271
278
|
}
|
|
272
279
|
}
|
|
273
|
-
var _cooking, T, log, info, warn, success;
|
|
280
|
+
var _cooking, T, TIME_COLORS, TAG_ROTATION, MSG_COLORS, _msgIdx, log, info, warn, success;
|
|
274
281
|
var init_logger = __esm({
|
|
275
282
|
"src/logger/index.ts"() {
|
|
276
283
|
"use strict";
|
|
277
284
|
_cooking = null;
|
|
278
285
|
T = () => (/* @__PURE__ */ new Date()).toISOString().slice(11, 19);
|
|
279
|
-
|
|
280
|
-
|
|
286
|
+
TIME_COLORS = [
|
|
287
|
+
chalk3.gray,
|
|
288
|
+
chalk3.hex("#9e9e9e"),
|
|
289
|
+
chalk3.hex("#757575"),
|
|
290
|
+
chalk3.hex("#6d6d6d")
|
|
291
|
+
];
|
|
292
|
+
TAG_ROTATION = [
|
|
293
|
+
(s) => chalk3.hex("#D4A017")(s),
|
|
294
|
+
(s) => chalk3.hex("#E0A030")(s),
|
|
295
|
+
(s) => chalk3.hex("#DAA520")(s),
|
|
296
|
+
(s) => chalk3.hex("#C4953A")(s),
|
|
297
|
+
(s) => chalk3.hex("#F0C040")(s)
|
|
298
|
+
];
|
|
299
|
+
MSG_COLORS = [
|
|
300
|
+
(s) => chalk3.hex("#D4A017")(s),
|
|
301
|
+
(s) => chalk3.hex("#C8A951")(s),
|
|
302
|
+
(s) => chalk3.hex("#B8960A")(s),
|
|
303
|
+
(s) => chalk3.hex("#d4a76a")(s),
|
|
304
|
+
(s) => chalk3.hex("#c0a060")(s),
|
|
305
|
+
(s) => chalk3.hex("#dab660")(s)
|
|
306
|
+
];
|
|
307
|
+
_msgIdx = 0;
|
|
308
|
+
log = (m) => {
|
|
309
|
+
const timeColor = TIME_COLORS[Math.floor(Math.random() * TIME_COLORS.length)];
|
|
310
|
+
const t = timeColor(`[${T()}]`);
|
|
311
|
+
const tag = TAG_ROTATION[0]("[LOG]");
|
|
312
|
+
const msg = nextMsgColor()(trunc(m, 120));
|
|
313
|
+
output(`${t} ${tag} ${msg}`);
|
|
314
|
+
};
|
|
315
|
+
info = (m) => {
|
|
316
|
+
const timeColor = chalk3.gray;
|
|
317
|
+
const t = timeColor(`[${T()}]`);
|
|
318
|
+
const tag = chalk3.hex("#E8A317")("[INFO]");
|
|
319
|
+
output(`${t} ${tag} ${chalk3.bold(trunc(m, 120))}`);
|
|
320
|
+
};
|
|
281
321
|
warn = (m) => {
|
|
282
|
-
const line2 = `${chalk3.gray(`[${T()}]`)} ${chalk3.
|
|
322
|
+
const line2 = `${chalk3.gray(`[${T()}]`)} ${chalk3.hex("#CC7722").bold("[WARN]")} ${chalk3.hex("#CC7722")(trunc(m, 120))}`;
|
|
283
323
|
if (_cooking) _cooking.log(line2);
|
|
284
324
|
else console.warn(line2);
|
|
285
325
|
};
|
|
286
|
-
success = (m) =>
|
|
326
|
+
success = (m) => {
|
|
327
|
+
const t = chalk3.hex("#8a8a8a")(`[${T()}]`);
|
|
328
|
+
const tag = chalk3.greenBright("[OK]");
|
|
329
|
+
const msg = chalk3.green(trunc(m, 120));
|
|
330
|
+
output(`${t} ${tag} ${msg}`);
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
|
|
335
|
+
// src/platforms/framer.ts
|
|
336
|
+
var FONT_EXTS, framer;
|
|
337
|
+
var init_framer = __esm({
|
|
338
|
+
"src/platforms/framer.ts"() {
|
|
339
|
+
"use strict";
|
|
340
|
+
FONT_EXTS = [".woff2", ".woff", ".ttf", ".otf"];
|
|
341
|
+
framer = {
|
|
342
|
+
name: "framer",
|
|
343
|
+
displayName: "Framer",
|
|
344
|
+
detectByUrl(url) {
|
|
345
|
+
return /\.framer\.(app|website)|framercanvas\.com/.test(url);
|
|
346
|
+
},
|
|
347
|
+
detectByHtml(html) {
|
|
348
|
+
return html.includes('id="main"') && (html.includes("framerstatic.com") || html.includes("framerusercontent.com"));
|
|
349
|
+
},
|
|
350
|
+
stripDomains: ["events.framer.com", "api.framer.com", "collect.frameranalytics.com"],
|
|
351
|
+
stripSelectors: [
|
|
352
|
+
'script[src*="events.framer.com"]',
|
|
353
|
+
"#__framer-badge-container",
|
|
354
|
+
"#__framer-badge",
|
|
355
|
+
'link[href*="canvas-sandbox"]',
|
|
356
|
+
'script[src*="framer.com/bootstrap"]'
|
|
357
|
+
],
|
|
358
|
+
stripPatterns: [
|
|
359
|
+
/<div id="__framer-badge-container"[^>]*><\/div>/g,
|
|
360
|
+
/<script>try\{if\(localStorage\.get\("__framer_force_showing_editorbar_since"\)\)[^<]*<\/script>/g
|
|
361
|
+
],
|
|
362
|
+
hydrationTimeout: 1e4,
|
|
363
|
+
needsHydrationCheck: true,
|
|
364
|
+
mapAssetDir(host, pathname, ext) {
|
|
365
|
+
if (host.includes("framerusercontent.com")) {
|
|
366
|
+
if (pathname.startsWith("/images/")) return "assets/images";
|
|
367
|
+
if (pathname.startsWith("/assets/")) {
|
|
368
|
+
return FONT_EXTS.includes(ext) ? "assets/fonts" : "assets/misc";
|
|
369
|
+
}
|
|
370
|
+
if (pathname.startsWith("/sites/")) {
|
|
371
|
+
if (ext === ".mjs" || ext === ".js") return "scripts/vendor";
|
|
372
|
+
if (ext === ".json") return "data";
|
|
373
|
+
if (ext === ".css") return "styles";
|
|
374
|
+
if (ext === ".framercms") return "data";
|
|
375
|
+
return "assets/misc";
|
|
376
|
+
}
|
|
377
|
+
if (pathname.startsWith("/modules/")) {
|
|
378
|
+
return ext === ".framercms" ? "data" : "scripts/modules";
|
|
379
|
+
}
|
|
380
|
+
return "assets/misc";
|
|
381
|
+
}
|
|
382
|
+
if (host.includes("app.framerstatic.com")) {
|
|
383
|
+
if (ext === ".css") return "styles";
|
|
384
|
+
if (ext === ".mjs" || ext === ".js") return "scripts/vendor";
|
|
385
|
+
if (ext === ".woff2" || ext === ".woff") return "assets/fonts";
|
|
386
|
+
if (ext === ".png" || ext === ".svg") return "assets/images";
|
|
387
|
+
return "assets/misc";
|
|
388
|
+
}
|
|
389
|
+
if (host.includes("framercanvas.com") || host.includes("framer.com")) {
|
|
390
|
+
if (ext === ".mjs" || ext === ".js") return "scripts/vendor";
|
|
391
|
+
if (ext === ".css") return "styles";
|
|
392
|
+
return "assets/misc";
|
|
393
|
+
}
|
|
394
|
+
return null;
|
|
395
|
+
}
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
// src/platforms/webflow.ts
|
|
401
|
+
var IMG_EXTS, FONT_EXTS2, VIDEO_EXTS, webflow;
|
|
402
|
+
var init_webflow = __esm({
|
|
403
|
+
"src/platforms/webflow.ts"() {
|
|
404
|
+
"use strict";
|
|
405
|
+
IMG_EXTS = [".jpg", ".jpeg", ".png", ".gif", ".svg", ".webp", ".avif"];
|
|
406
|
+
FONT_EXTS2 = [".woff2", ".woff", ".ttf", ".otf", ".eot"];
|
|
407
|
+
VIDEO_EXTS = [".mp4", ".webm", ".ogg"];
|
|
408
|
+
webflow = {
|
|
409
|
+
name: "webflow",
|
|
410
|
+
displayName: "Webflow",
|
|
411
|
+
detectByUrl(url) {
|
|
412
|
+
return /\.webflow\.(io|com)/.test(url);
|
|
413
|
+
},
|
|
414
|
+
detectByHtml(html) {
|
|
415
|
+
return html.includes("data-wf-site") || html.includes("w-webflow-badge") || html.includes("Webflow") || html.includes("webflow.js");
|
|
416
|
+
},
|
|
417
|
+
stripDomains: ["js-agent.newrelic.com", "cdn.heapanalytics.com", "tr.snapchat.com"],
|
|
418
|
+
stripSelectors: [".w-webflow-badge", 'link[href*="editorbar"]'],
|
|
419
|
+
stripPatterns: [
|
|
420
|
+
/<a[^>]*class="[^"]*w-webflow-badge[^"]*"[^>]*>[\s\S]*?<\/a>/g,
|
|
421
|
+
/<a[^>]*href="[^"]*webflow\.com\?utm_campaign=brandjs[^"]*"[^>]*>[\s\S]*?<\/a>/g,
|
|
422
|
+
/<style>[^<]*\.w-webflow-badge[^<]*<\/style>/g,
|
|
423
|
+
/Powered by <a[^>]*href="[^"]*webflow\.com"[^>]*>[^<]*<\/a>/g,
|
|
424
|
+
/<!-- This site was created in Webflow\.[^>]*-->/g,
|
|
425
|
+
/<html([^>]*) data-wf-domain="[^"]*"/g,
|
|
426
|
+
/<html([^>]*) data-wf-page="[^"]*"/g,
|
|
427
|
+
/<html([^>]*) data-wf-site="[^"]*"/g,
|
|
428
|
+
/<html([^>]*) data-wf-status="[^"]*"/g,
|
|
429
|
+
/<meta[^>]*content="Webflow"[^>]*>/g
|
|
430
|
+
],
|
|
431
|
+
hydrationTimeout: 2e3,
|
|
432
|
+
needsHydrationCheck: false,
|
|
433
|
+
mapAssetDir(host, pathname, ext) {
|
|
434
|
+
if (host.includes("website-files.com") || host.includes("webflow.com") || host.includes("uploads-ssl.webflow.com")) {
|
|
435
|
+
if (VIDEO_EXTS.includes(ext)) return "assets/videos";
|
|
436
|
+
if (pathname.includes("/images/") || IMG_EXTS.includes(ext)) return "assets/images";
|
|
437
|
+
if (pathname.includes("/css/") || ext === ".css") return "styles";
|
|
438
|
+
if (pathname.includes("/js/") || ext === ".js") return "scripts/vendor";
|
|
439
|
+
if (pathname.includes("/gsap/") || pathname.includes("/plugins/")) return "scripts/vendor";
|
|
440
|
+
if (FONT_EXTS2.includes(ext)) return "assets/fonts";
|
|
441
|
+
return "assets/misc";
|
|
442
|
+
}
|
|
443
|
+
if (host.includes("d3e54v103j8qbb.cloudfront.net")) {
|
|
444
|
+
if (ext === ".js") return "scripts/vendor";
|
|
445
|
+
if (ext === ".css") return "styles";
|
|
446
|
+
if (IMG_EXTS.includes(ext)) return "assets/images";
|
|
447
|
+
return "assets/misc";
|
|
448
|
+
}
|
|
449
|
+
return null;
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
// src/platforms/wix.ts
|
|
456
|
+
var IMG_EXTS2, FONT_EXTS3, VIDEO_EXTS2, wix;
|
|
457
|
+
var init_wix = __esm({
|
|
458
|
+
"src/platforms/wix.ts"() {
|
|
459
|
+
"use strict";
|
|
460
|
+
IMG_EXTS2 = [".jpg", ".jpeg", ".png", ".gif", ".svg", ".webp", ".avif", ".ico"];
|
|
461
|
+
FONT_EXTS3 = [".woff2", ".woff", ".ttf", ".otf", ".eot"];
|
|
462
|
+
VIDEO_EXTS2 = [".mp4", ".webm", ".ogg"];
|
|
463
|
+
wix = {
|
|
464
|
+
name: "wix",
|
|
465
|
+
displayName: "Wix",
|
|
466
|
+
detectByUrl(url) {
|
|
467
|
+
return /\.wixsite\.com|\.wix\.com/.test(url);
|
|
468
|
+
},
|
|
469
|
+
detectByHtml(html) {
|
|
470
|
+
return html.includes("wix-viewer-model") || html.includes('id="WIX_ADS"') || html.includes("X-Wix-") || html.includes("Wix.com") || html.includes("wixcode-sdk") || html.includes("data-wix") || html.includes("wix-code") || html.includes("WixCode") || /\bwix\.com\b/.test(html) || /meta\s+name=["']generator["']\s+content=["'][^"']*Wix[^"']*["']/i.test(html) || /_wix_/i.test(html) || /wix-ecom/i.test(html);
|
|
471
|
+
},
|
|
472
|
+
stripDomains: [
|
|
473
|
+
"frog.wix.com",
|
|
474
|
+
"bi.wixapi.com",
|
|
475
|
+
"fed.wixcodescheduler.com",
|
|
476
|
+
"editor.wix.com",
|
|
477
|
+
"panorama.wixapps.net"
|
|
478
|
+
],
|
|
479
|
+
stripSelectors: ["#WIX_ADS", ".wix-ads", "#wix-badge", "#SCROLL_TO_TOP"],
|
|
480
|
+
stripPatterns: [
|
|
481
|
+
/<div[^>]*class="[^"]*wix-ads[^"]*"[^>]*>[\s\S]*?<\/div>/g
|
|
482
|
+
],
|
|
483
|
+
hydrationTimeout: 3e3,
|
|
484
|
+
needsHydrationCheck: false,
|
|
485
|
+
mapAssetDir(host, pathname, ext) {
|
|
486
|
+
if (host === "video.wixstatic.com") {
|
|
487
|
+
return "assets/videos";
|
|
488
|
+
}
|
|
489
|
+
if (host.includes("wixstatic.com")) {
|
|
490
|
+
if (VIDEO_EXTS2.includes(ext)) return "assets/videos";
|
|
491
|
+
if (pathname.includes("/images/") || IMG_EXTS2.includes(ext)) return "assets/images";
|
|
492
|
+
if (ext === ".css") return "styles";
|
|
493
|
+
if (ext === ".js") return "scripts/vendor";
|
|
494
|
+
if (FONT_EXTS3.includes(ext)) return "assets/fonts";
|
|
495
|
+
return "assets/misc";
|
|
496
|
+
}
|
|
497
|
+
if (host.includes("parastorage.com")) {
|
|
498
|
+
if (ext === ".js") return "scripts/vendor";
|
|
499
|
+
if (ext === ".css") return "styles";
|
|
500
|
+
if (FONT_EXTS3.includes(ext)) return "assets/fonts";
|
|
501
|
+
if (IMG_EXTS2.includes(ext)) return "assets/images";
|
|
502
|
+
return "assets/misc";
|
|
503
|
+
}
|
|
504
|
+
return null;
|
|
505
|
+
}
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
});
|
|
509
|
+
|
|
510
|
+
// src/platforms/detect.ts
|
|
511
|
+
function detectByUrl(url) {
|
|
512
|
+
for (const platform of ALL_PLATFORMS) {
|
|
513
|
+
if (platform.detectByUrl(url)) return platform;
|
|
514
|
+
}
|
|
515
|
+
return null;
|
|
516
|
+
}
|
|
517
|
+
function detectByHtml(html) {
|
|
518
|
+
for (const platform of ALL_PLATFORMS) {
|
|
519
|
+
if (platform.detectByHtml(html)) return platform;
|
|
520
|
+
}
|
|
521
|
+
return null;
|
|
522
|
+
}
|
|
523
|
+
function detectPlatform(url, html) {
|
|
524
|
+
const byUrl = detectByUrl(url);
|
|
525
|
+
if (byUrl) return byUrl;
|
|
526
|
+
if (html) {
|
|
527
|
+
const byHtml = detectByHtml(html);
|
|
528
|
+
if (byHtml) return byHtml;
|
|
529
|
+
}
|
|
530
|
+
return framer;
|
|
531
|
+
}
|
|
532
|
+
async function detectByDom(page) {
|
|
533
|
+
try {
|
|
534
|
+
const signal = await page.evaluate(() => {
|
|
535
|
+
const html = document.documentElement.outerHTML || "";
|
|
536
|
+
if (/wix-viewer-model|_wix_|wix-ecom/i.test(html)) return "wix";
|
|
537
|
+
if (/data-wf-|w-webflow-badge|webflow\.js/i.test(html)) return "webflow";
|
|
538
|
+
if (/framerusercontent|framercanvas|framerstatic/i.test(html)) return "framer";
|
|
539
|
+
const srcs = [];
|
|
540
|
+
const scripts = document.querySelectorAll("script[src]");
|
|
541
|
+
scripts.forEach((s) => {
|
|
542
|
+
if (s.src) srcs.push(s.src);
|
|
543
|
+
});
|
|
544
|
+
const allSrcs = srcs.join(" ");
|
|
545
|
+
if (/wixstatic\.com|parastorage\.com/.test(allSrcs)) return "wix";
|
|
546
|
+
if (/website-files\.com|webflow\.com/.test(allSrcs)) return "webflow";
|
|
547
|
+
if (/framerusercontent\.com|framerstatic\.com|framer\.app/.test(allSrcs)) return "framer";
|
|
548
|
+
return "";
|
|
549
|
+
});
|
|
550
|
+
if (signal === "wix") return wix;
|
|
551
|
+
if (signal === "webflow") return webflow;
|
|
552
|
+
if (signal === "framer") return framer;
|
|
553
|
+
} catch {
|
|
554
|
+
}
|
|
555
|
+
return null;
|
|
556
|
+
}
|
|
557
|
+
function getPlatformByName(name) {
|
|
558
|
+
const map = { framer, webflow, wix };
|
|
559
|
+
return map[name] || framer;
|
|
560
|
+
}
|
|
561
|
+
var ALL_PLATFORMS;
|
|
562
|
+
var init_detect = __esm({
|
|
563
|
+
"src/platforms/detect.ts"() {
|
|
564
|
+
"use strict";
|
|
565
|
+
init_framer();
|
|
566
|
+
init_webflow();
|
|
567
|
+
init_wix();
|
|
568
|
+
ALL_PLATFORMS = [framer, webflow, wix];
|
|
569
|
+
}
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
// src/platforms/index.ts
|
|
573
|
+
var platforms_exports = {};
|
|
574
|
+
__export(platforms_exports, {
|
|
575
|
+
detectByDom: () => detectByDom,
|
|
576
|
+
detectByHtml: () => detectByHtml,
|
|
577
|
+
detectByUrl: () => detectByUrl,
|
|
578
|
+
detectPlatform: () => detectPlatform,
|
|
579
|
+
framer: () => framer,
|
|
580
|
+
getPlatformByName: () => getPlatformByName,
|
|
581
|
+
webflow: () => webflow,
|
|
582
|
+
wix: () => wix
|
|
583
|
+
});
|
|
584
|
+
var init_platforms = __esm({
|
|
585
|
+
"src/platforms/index.ts"() {
|
|
586
|
+
"use strict";
|
|
587
|
+
init_framer();
|
|
588
|
+
init_webflow();
|
|
589
|
+
init_wix();
|
|
590
|
+
init_detect();
|
|
287
591
|
}
|
|
288
592
|
});
|
|
289
593
|
|
|
@@ -342,6 +646,12 @@ async function launchAndCapture(exporter) {
|
|
|
342
646
|
});
|
|
343
647
|
success("Page loaded (networkidle2)");
|
|
344
648
|
log("Intercepted " + intercepted + " resources, blocked " + blocked + " tracking requests");
|
|
649
|
+
log("Checking DOM-based platform detection...");
|
|
650
|
+
const domDetected = await detectByDom(exporter.page);
|
|
651
|
+
if (domDetected && domDetected.name !== exporter.platform.name) {
|
|
652
|
+
log("Platform refined from DOM: " + domDetected.displayName + " (override: " + exporter.platform.name + ")");
|
|
653
|
+
exporter.platform = domDetected;
|
|
654
|
+
}
|
|
345
655
|
exporter.cooking?.update("Waiting for " + exporter.platform.displayName + " hydration...");
|
|
346
656
|
if (exporter.platform.needsHydrationCheck) {
|
|
347
657
|
log("Checking for #main element hydration...");
|
|
@@ -403,15 +713,42 @@ async function launchAndCapture(exporter) {
|
|
|
403
713
|
const imgCount = [...exporter.assets.entries.values()].filter((e) => e.localPath.startsWith("assets/images")).length;
|
|
404
714
|
const fontCount = [...exporter.assets.entries.values()].filter((e) => e.localPath.startsWith("assets/fonts")).length;
|
|
405
715
|
log(" CSS: " + cssCount + " | JS: " + jsCount + " | Images: " + imgCount + " | Fonts: " + fontCount);
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
716
|
+
}
|
|
717
|
+
async function closeBrowser(exporter) {
|
|
718
|
+
if (exporter.browser) {
|
|
719
|
+
await exporter.browser.close();
|
|
720
|
+
exporter.browser = null;
|
|
721
|
+
log("Browser closed");
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
async function captureSubpage(page, url, platform) {
|
|
725
|
+
log(" Navigating to sub-page: " + url);
|
|
726
|
+
await page.goto(url, { waitUntil: "networkidle2", timeout: CFG.timeout });
|
|
727
|
+
if (platform.needsHydrationCheck) {
|
|
728
|
+
await page.evaluate(
|
|
729
|
+
`new Promise(function(r) {
|
|
730
|
+
var t = Date.now();
|
|
731
|
+
(function tick() {
|
|
732
|
+
var m = document.getElementById('main') || document.body;
|
|
733
|
+
if (m && m.children.length > 0) setTimeout(r, 500);
|
|
734
|
+
else if (Date.now() - t > ${platform.hydrationTimeout}) r();
|
|
735
|
+
else setTimeout(tick, 200);
|
|
736
|
+
})();
|
|
737
|
+
})`
|
|
738
|
+
);
|
|
739
|
+
} else {
|
|
740
|
+
await new Promise((r) => setTimeout(r, 1e3));
|
|
741
|
+
}
|
|
742
|
+
const html = await page.evaluate(() => document.documentElement.outerHTML || document.body.innerHTML);
|
|
743
|
+
log(" Sub-page fetched: " + (html.length / 1024).toFixed(1) + " KB");
|
|
744
|
+
return html;
|
|
409
745
|
}
|
|
410
746
|
var init_capture = __esm({
|
|
411
747
|
"src/exporter/capture.ts"() {
|
|
412
748
|
"use strict";
|
|
413
749
|
init_config();
|
|
414
750
|
init_logger();
|
|
751
|
+
init_platforms();
|
|
415
752
|
}
|
|
416
753
|
});
|
|
417
754
|
|
|
@@ -870,11 +1207,12 @@ async function printSummary(exporter) {
|
|
|
870
1207
|
count("styles"),
|
|
871
1208
|
count("data")
|
|
872
1209
|
]);
|
|
1210
|
+
const G = chalk4.hex("#D4A017");
|
|
873
1211
|
console.log("");
|
|
874
1212
|
if (!isSmall) {
|
|
875
|
-
console.log(
|
|
876
|
-
console.log(
|
|
877
|
-
console.log(
|
|
1213
|
+
console.log(G(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"));
|
|
1214
|
+
console.log(G(" \u2502") + chalk4.bold.white(" Export Summary ") + G("\u2502"));
|
|
1215
|
+
console.log(G(" \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524"));
|
|
878
1216
|
} else {
|
|
879
1217
|
console.log(chalk4.bold.white(" Export Summary:"));
|
|
880
1218
|
}
|
|
@@ -885,7 +1223,7 @@ async function printSummary(exporter) {
|
|
|
885
1223
|
if (isSmall) {
|
|
886
1224
|
console.log(` ${chalk4.yellow(label)} ${chalk4.white(String(count2))} ${chalk4.gray(type)}`);
|
|
887
1225
|
} else {
|
|
888
|
-
console.log(` ${
|
|
1226
|
+
console.log(` ${G("\u2502")} ${chalk4.yellow(l)} ${chalk4.white(c)} ${chalk4.gray(type.padEnd(20))} ${G("\u2502")}`);
|
|
889
1227
|
}
|
|
890
1228
|
};
|
|
891
1229
|
row("styles/", styles, "CSS files");
|
|
@@ -897,19 +1235,19 @@ async function printSummary(exporter) {
|
|
|
897
1235
|
row("assets/misc/", misc, "misc files");
|
|
898
1236
|
row("data/", data, "data files");
|
|
899
1237
|
if (!isSmall) {
|
|
900
|
-
console.log(
|
|
1238
|
+
console.log(G(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"));
|
|
901
1239
|
}
|
|
902
1240
|
console.log("");
|
|
903
1241
|
const quotedDir = `"${exporter.outDir}"`;
|
|
904
1242
|
if (!isSmall) {
|
|
905
|
-
console.log(
|
|
906
|
-
console.log(
|
|
907
|
-
console.log(
|
|
908
|
-
console.log(` ${
|
|
909
|
-
console.log(
|
|
1243
|
+
console.log(G(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"));
|
|
1244
|
+
console.log(G(" \u2502") + chalk4.bold.white(" To serve locally ") + G("\u2502"));
|
|
1245
|
+
console.log(G(" \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524"));
|
|
1246
|
+
console.log(` ${G("\u2502")} ${chalk4.hex("#D4A017")("cd " + path4.basename(exporter.outDir) + " && node serve.cjs").padEnd(44)} ${G("\u2502")}`);
|
|
1247
|
+
console.log(G(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"));
|
|
910
1248
|
} else {
|
|
911
1249
|
console.log(chalk4.bold.white(" To serve locally:"));
|
|
912
|
-
console.log(` ${chalk4.
|
|
1250
|
+
console.log(` ${chalk4.hex("#D4A017")("cd " + path4.basename(exporter.outDir) + " && node serve.cjs")}`);
|
|
913
1251
|
}
|
|
914
1252
|
console.log("");
|
|
915
1253
|
console.log(chalk4.gray(" NOTE: Must be served via HTTP for JS modules to work."));
|
|
@@ -921,263 +1259,52 @@ var init_summary = __esm({
|
|
|
921
1259
|
}
|
|
922
1260
|
});
|
|
923
1261
|
|
|
924
|
-
// src/platforms/framer.ts
|
|
925
|
-
var FONT_EXTS, framer;
|
|
926
|
-
var init_framer = __esm({
|
|
927
|
-
"src/platforms/framer.ts"() {
|
|
928
|
-
"use strict";
|
|
929
|
-
FONT_EXTS = [".woff2", ".woff", ".ttf", ".otf"];
|
|
930
|
-
framer = {
|
|
931
|
-
name: "framer",
|
|
932
|
-
displayName: "Framer",
|
|
933
|
-
detectByUrl(url) {
|
|
934
|
-
return /\.framer\.(app|website)|framercanvas\.com/.test(url);
|
|
935
|
-
},
|
|
936
|
-
detectByHtml(html) {
|
|
937
|
-
return html.includes('id="main"') && (html.includes("framerstatic.com") || html.includes("framerusercontent.com"));
|
|
938
|
-
},
|
|
939
|
-
stripDomains: ["events.framer.com", "api.framer.com", "collect.frameranalytics.com"],
|
|
940
|
-
stripSelectors: [
|
|
941
|
-
'script[src*="events.framer.com"]',
|
|
942
|
-
"#__framer-badge-container",
|
|
943
|
-
"#__framer-badge",
|
|
944
|
-
'link[href*="canvas-sandbox"]',
|
|
945
|
-
'script[src*="framer.com/bootstrap"]'
|
|
946
|
-
],
|
|
947
|
-
stripPatterns: [
|
|
948
|
-
/<div id="__framer-badge-container"[^>]*><\/div>/g,
|
|
949
|
-
/<script>try\{if\(localStorage\.get\("__framer_force_showing_editorbar_since"\)\)[^<]*<\/script>/g
|
|
950
|
-
],
|
|
951
|
-
hydrationTimeout: 1e4,
|
|
952
|
-
needsHydrationCheck: true,
|
|
953
|
-
mapAssetDir(host, pathname, ext) {
|
|
954
|
-
if (host.includes("framerusercontent.com")) {
|
|
955
|
-
if (pathname.startsWith("/images/")) return "assets/images";
|
|
956
|
-
if (pathname.startsWith("/assets/")) {
|
|
957
|
-
return FONT_EXTS.includes(ext) ? "assets/fonts" : "assets/misc";
|
|
958
|
-
}
|
|
959
|
-
if (pathname.startsWith("/sites/")) {
|
|
960
|
-
if (ext === ".mjs" || ext === ".js") return "scripts/vendor";
|
|
961
|
-
if (ext === ".json") return "data";
|
|
962
|
-
if (ext === ".css") return "styles";
|
|
963
|
-
if (ext === ".framercms") return "data";
|
|
964
|
-
return "assets/misc";
|
|
965
|
-
}
|
|
966
|
-
if (pathname.startsWith("/modules/")) {
|
|
967
|
-
return ext === ".framercms" ? "data" : "scripts/modules";
|
|
968
|
-
}
|
|
969
|
-
return "assets/misc";
|
|
970
|
-
}
|
|
971
|
-
if (host.includes("app.framerstatic.com")) {
|
|
972
|
-
if (ext === ".css") return "styles";
|
|
973
|
-
if (ext === ".mjs" || ext === ".js") return "scripts/vendor";
|
|
974
|
-
if (ext === ".woff2" || ext === ".woff") return "assets/fonts";
|
|
975
|
-
if (ext === ".png" || ext === ".svg") return "assets/images";
|
|
976
|
-
return "assets/misc";
|
|
977
|
-
}
|
|
978
|
-
if (host.includes("framercanvas.com") || host.includes("framer.com")) {
|
|
979
|
-
if (ext === ".mjs" || ext === ".js") return "scripts/vendor";
|
|
980
|
-
if (ext === ".css") return "styles";
|
|
981
|
-
return "assets/misc";
|
|
982
|
-
}
|
|
983
|
-
return null;
|
|
984
|
-
}
|
|
985
|
-
};
|
|
986
|
-
}
|
|
987
|
-
});
|
|
988
|
-
|
|
989
|
-
// src/platforms/webflow.ts
|
|
990
|
-
var IMG_EXTS, FONT_EXTS2, VIDEO_EXTS, webflow;
|
|
991
|
-
var init_webflow = __esm({
|
|
992
|
-
"src/platforms/webflow.ts"() {
|
|
993
|
-
"use strict";
|
|
994
|
-
IMG_EXTS = [".jpg", ".jpeg", ".png", ".gif", ".svg", ".webp", ".avif"];
|
|
995
|
-
FONT_EXTS2 = [".woff2", ".woff", ".ttf", ".otf", ".eot"];
|
|
996
|
-
VIDEO_EXTS = [".mp4", ".webm", ".ogg"];
|
|
997
|
-
webflow = {
|
|
998
|
-
name: "webflow",
|
|
999
|
-
displayName: "Webflow",
|
|
1000
|
-
detectByUrl(url) {
|
|
1001
|
-
return /\.webflow\.(io|com)/.test(url);
|
|
1002
|
-
},
|
|
1003
|
-
detectByHtml(html) {
|
|
1004
|
-
return html.includes("data-wf-site") || html.includes("w-webflow-badge") || html.includes("Webflow") || html.includes("webflow.js");
|
|
1005
|
-
},
|
|
1006
|
-
stripDomains: ["js-agent.newrelic.com", "cdn.heapanalytics.com", "tr.snapchat.com"],
|
|
1007
|
-
stripSelectors: [".w-webflow-badge", 'link[href*="editorbar"]'],
|
|
1008
|
-
stripPatterns: [
|
|
1009
|
-
/<a[^>]*class="[^"]*w-webflow-badge[^"]*"[^>]*>[\s\S]*?<\/a>/g,
|
|
1010
|
-
/<a[^>]*href="[^"]*webflow\.com\?utm_campaign=brandjs[^"]*"[^>]*>[\s\S]*?<\/a>/g,
|
|
1011
|
-
/<style>[^<]*\.w-webflow-badge[^<]*<\/style>/g,
|
|
1012
|
-
/Powered by <a[^>]*href="[^"]*webflow\.com"[^>]*>[^<]*<\/a>/g,
|
|
1013
|
-
/<!-- This site was created in Webflow\.[^>]*-->/g,
|
|
1014
|
-
/<html([^>]*) data-wf-domain="[^"]*"/g,
|
|
1015
|
-
/<html([^>]*) data-wf-page="[^"]*"/g,
|
|
1016
|
-
/<html([^>]*) data-wf-site="[^"]*"/g,
|
|
1017
|
-
/<html([^>]*) data-wf-status="[^"]*"/g,
|
|
1018
|
-
/<meta[^>]*content="Webflow"[^>]*>/g
|
|
1019
|
-
],
|
|
1020
|
-
hydrationTimeout: 2e3,
|
|
1021
|
-
needsHydrationCheck: false,
|
|
1022
|
-
mapAssetDir(host, pathname, ext) {
|
|
1023
|
-
if (host.includes("website-files.com") || host.includes("webflow.com") || host.includes("uploads-ssl.webflow.com")) {
|
|
1024
|
-
if (VIDEO_EXTS.includes(ext)) return "assets/videos";
|
|
1025
|
-
if (pathname.includes("/images/") || IMG_EXTS.includes(ext)) return "assets/images";
|
|
1026
|
-
if (pathname.includes("/css/") || ext === ".css") return "styles";
|
|
1027
|
-
if (pathname.includes("/js/") || ext === ".js") return "scripts/vendor";
|
|
1028
|
-
if (pathname.includes("/gsap/") || pathname.includes("/plugins/")) return "scripts/vendor";
|
|
1029
|
-
if (FONT_EXTS2.includes(ext)) return "assets/fonts";
|
|
1030
|
-
return "assets/misc";
|
|
1031
|
-
}
|
|
1032
|
-
if (host.includes("d3e54v103j8qbb.cloudfront.net")) {
|
|
1033
|
-
if (ext === ".js") return "scripts/vendor";
|
|
1034
|
-
if (ext === ".css") return "styles";
|
|
1035
|
-
if (IMG_EXTS.includes(ext)) return "assets/images";
|
|
1036
|
-
return "assets/misc";
|
|
1037
|
-
}
|
|
1038
|
-
return null;
|
|
1039
|
-
}
|
|
1040
|
-
};
|
|
1041
|
-
}
|
|
1042
|
-
});
|
|
1043
|
-
|
|
1044
|
-
// src/platforms/wix.ts
|
|
1045
|
-
var IMG_EXTS2, FONT_EXTS3, VIDEO_EXTS2, wix;
|
|
1046
|
-
var init_wix = __esm({
|
|
1047
|
-
"src/platforms/wix.ts"() {
|
|
1048
|
-
"use strict";
|
|
1049
|
-
IMG_EXTS2 = [".jpg", ".jpeg", ".png", ".gif", ".svg", ".webp", ".avif", ".ico"];
|
|
1050
|
-
FONT_EXTS3 = [".woff2", ".woff", ".ttf", ".otf", ".eot"];
|
|
1051
|
-
VIDEO_EXTS2 = [".mp4", ".webm", ".ogg"];
|
|
1052
|
-
wix = {
|
|
1053
|
-
name: "wix",
|
|
1054
|
-
displayName: "Wix",
|
|
1055
|
-
detectByUrl(url) {
|
|
1056
|
-
return /\.wixsite\.com|\.wix\.com/.test(url);
|
|
1057
|
-
},
|
|
1058
|
-
detectByHtml(html) {
|
|
1059
|
-
return html.includes("wix-viewer-model") || html.includes('id="WIX_ADS"') || html.includes("X-Wix-") || html.includes("Wix.com") || html.includes("wixcode-sdk");
|
|
1060
|
-
},
|
|
1061
|
-
stripDomains: [
|
|
1062
|
-
"frog.wix.com",
|
|
1063
|
-
"bi.wixapi.com",
|
|
1064
|
-
"fed.wixcodescheduler.com",
|
|
1065
|
-
"editor.wix.com",
|
|
1066
|
-
"panorama.wixapps.net"
|
|
1067
|
-
],
|
|
1068
|
-
stripSelectors: ["#WIX_ADS", ".wix-ads", "#wix-badge", "#SCROLL_TO_TOP"],
|
|
1069
|
-
stripPatterns: [
|
|
1070
|
-
/<div[^>]*class="[^"]*wix-ads[^"]*"[^>]*>[\s\S]*?<\/div>/g
|
|
1071
|
-
],
|
|
1072
|
-
hydrationTimeout: 3e3,
|
|
1073
|
-
needsHydrationCheck: false,
|
|
1074
|
-
mapAssetDir(host, pathname, ext) {
|
|
1075
|
-
if (host === "video.wixstatic.com") {
|
|
1076
|
-
return "assets/videos";
|
|
1077
|
-
}
|
|
1078
|
-
if (host.includes("wixstatic.com")) {
|
|
1079
|
-
if (VIDEO_EXTS2.includes(ext)) return "assets/videos";
|
|
1080
|
-
if (pathname.includes("/images/") || IMG_EXTS2.includes(ext)) return "assets/images";
|
|
1081
|
-
if (ext === ".css") return "styles";
|
|
1082
|
-
if (ext === ".js") return "scripts/vendor";
|
|
1083
|
-
if (FONT_EXTS3.includes(ext)) return "assets/fonts";
|
|
1084
|
-
return "assets/misc";
|
|
1085
|
-
}
|
|
1086
|
-
if (host.includes("parastorage.com")) {
|
|
1087
|
-
if (ext === ".js") return "scripts/vendor";
|
|
1088
|
-
if (ext === ".css") return "styles";
|
|
1089
|
-
if (FONT_EXTS3.includes(ext)) return "assets/fonts";
|
|
1090
|
-
if (IMG_EXTS2.includes(ext)) return "assets/images";
|
|
1091
|
-
return "assets/misc";
|
|
1092
|
-
}
|
|
1093
|
-
return null;
|
|
1094
|
-
}
|
|
1095
|
-
};
|
|
1096
|
-
}
|
|
1097
|
-
});
|
|
1098
|
-
|
|
1099
|
-
// src/platforms/detect.ts
|
|
1100
|
-
function detectByUrl(url) {
|
|
1101
|
-
for (const platform of ALL_PLATFORMS) {
|
|
1102
|
-
if (platform.detectByUrl(url)) return platform;
|
|
1103
|
-
}
|
|
1104
|
-
return null;
|
|
1105
|
-
}
|
|
1106
|
-
function detectByHtml(html) {
|
|
1107
|
-
for (const platform of ALL_PLATFORMS) {
|
|
1108
|
-
if (platform.detectByHtml(html)) return platform;
|
|
1109
|
-
}
|
|
1110
|
-
return null;
|
|
1111
|
-
}
|
|
1112
|
-
function detectPlatform(url, html) {
|
|
1113
|
-
const byUrl = detectByUrl(url);
|
|
1114
|
-
if (byUrl) return byUrl;
|
|
1115
|
-
if (html) {
|
|
1116
|
-
const byHtml = detectByHtml(html);
|
|
1117
|
-
if (byHtml) return byHtml;
|
|
1118
|
-
}
|
|
1119
|
-
return framer;
|
|
1120
|
-
}
|
|
1121
|
-
function getPlatformByName(name) {
|
|
1122
|
-
const map = { framer, webflow, wix };
|
|
1123
|
-
return map[name] || framer;
|
|
1124
|
-
}
|
|
1125
|
-
var ALL_PLATFORMS;
|
|
1126
|
-
var init_detect = __esm({
|
|
1127
|
-
"src/platforms/detect.ts"() {
|
|
1128
|
-
"use strict";
|
|
1129
|
-
init_framer();
|
|
1130
|
-
init_webflow();
|
|
1131
|
-
init_wix();
|
|
1132
|
-
ALL_PLATFORMS = [framer, webflow, wix];
|
|
1133
|
-
}
|
|
1134
|
-
});
|
|
1135
|
-
|
|
1136
|
-
// src/platforms/index.ts
|
|
1137
|
-
var platforms_exports = {};
|
|
1138
|
-
__export(platforms_exports, {
|
|
1139
|
-
detectByHtml: () => detectByHtml,
|
|
1140
|
-
detectByUrl: () => detectByUrl,
|
|
1141
|
-
detectPlatform: () => detectPlatform,
|
|
1142
|
-
framer: () => framer,
|
|
1143
|
-
getPlatformByName: () => getPlatformByName,
|
|
1144
|
-
webflow: () => webflow,
|
|
1145
|
-
wix: () => wix
|
|
1146
|
-
});
|
|
1147
|
-
var init_platforms = __esm({
|
|
1148
|
-
"src/platforms/index.ts"() {
|
|
1149
|
-
"use strict";
|
|
1150
|
-
init_framer();
|
|
1151
|
-
init_webflow();
|
|
1152
|
-
init_wix();
|
|
1153
|
-
init_detect();
|
|
1154
|
-
}
|
|
1155
|
-
});
|
|
1156
|
-
|
|
1157
1262
|
// src/cli/cooking.ts
|
|
1158
1263
|
import chalk5 from "chalk";
|
|
1159
|
-
var SHINE_WIDTH, CookingSpinner;
|
|
1264
|
+
var SHINE_WIDTH, FRAME_INTERVAL, SPINNER_FRAMES, PALETTE, CookingSpinner;
|
|
1160
1265
|
var init_cooking = __esm({
|
|
1161
1266
|
"src/cli/cooking.ts"() {
|
|
1162
1267
|
"use strict";
|
|
1163
|
-
SHINE_WIDTH =
|
|
1268
|
+
SHINE_WIDTH = 10;
|
|
1269
|
+
FRAME_INTERVAL = 140;
|
|
1270
|
+
SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
1271
|
+
PALETTE = [
|
|
1272
|
+
(s) => chalk5.hex("#D4A017")(s),
|
|
1273
|
+
(s) => chalk5.hex("#E8A317")(s),
|
|
1274
|
+
(s) => chalk5.hex("#DAA520")(s),
|
|
1275
|
+
(s) => chalk5.hex("#F0C040")(s),
|
|
1276
|
+
(s) => chalk5.hex("#C4953A")(s),
|
|
1277
|
+
(s) => chalk5.hex("#E6B83C")(s),
|
|
1278
|
+
(s) => chalk5.hex("#C8A951")(s),
|
|
1279
|
+
(s) => chalk5.hex("#D9B44D")(s)
|
|
1280
|
+
];
|
|
1164
1281
|
CookingSpinner = class {
|
|
1165
1282
|
interval = null;
|
|
1283
|
+
bgInterval = null;
|
|
1166
1284
|
frame = 0;
|
|
1167
1285
|
phase = "";
|
|
1168
1286
|
active = false;
|
|
1287
|
+
bar = 0;
|
|
1288
|
+
barDir = 1;
|
|
1169
1289
|
start(phase = "") {
|
|
1170
1290
|
this.phase = phase;
|
|
1171
1291
|
this.frame = 0;
|
|
1292
|
+
this.bar = 0;
|
|
1293
|
+
this.barDir = 1;
|
|
1172
1294
|
this.active = true;
|
|
1173
1295
|
this.draw();
|
|
1174
1296
|
this.interval = setInterval(() => {
|
|
1175
1297
|
this.frame++;
|
|
1176
1298
|
this.draw();
|
|
1177
|
-
},
|
|
1299
|
+
}, FRAME_INTERVAL);
|
|
1300
|
+
this.bgInterval = setInterval(() => {
|
|
1301
|
+
this.bar++;
|
|
1302
|
+
this.draw();
|
|
1303
|
+
}, 800);
|
|
1178
1304
|
}
|
|
1179
1305
|
update(phase) {
|
|
1180
1306
|
this.phase = phase;
|
|
1307
|
+
if (!this.active) this.draw();
|
|
1181
1308
|
}
|
|
1182
1309
|
log(message) {
|
|
1183
1310
|
if (this.active) {
|
|
@@ -1194,18 +1321,27 @@ var init_cooking = __esm({
|
|
|
1194
1321
|
clearInterval(this.interval);
|
|
1195
1322
|
this.interval = null;
|
|
1196
1323
|
}
|
|
1324
|
+
if (this.bgInterval) {
|
|
1325
|
+
clearInterval(this.bgInterval);
|
|
1326
|
+
this.bgInterval = null;
|
|
1327
|
+
}
|
|
1197
1328
|
process.stdout.write("\r\x1B[2K");
|
|
1198
1329
|
}
|
|
1199
1330
|
draw() {
|
|
1200
1331
|
if (!this.active) return;
|
|
1201
|
-
const
|
|
1202
|
-
const
|
|
1203
|
-
const
|
|
1204
|
-
const
|
|
1205
|
-
const shimmer = this.renderShimmer(
|
|
1206
|
-
const
|
|
1207
|
-
const
|
|
1208
|
-
|
|
1332
|
+
const spinner = SPINNER_FRAMES[this.frame % SPINNER_FRAMES.length];
|
|
1333
|
+
const paletteFn = PALETTE[this.frame % PALETTE.length];
|
|
1334
|
+
const dotPhase = Math.floor(this.frame / 3) % 4;
|
|
1335
|
+
const dotStr = dotPhase === 0 ? " " : dotPhase === 1 ? ". " : dotPhase === 2 ? ".. " : "...";
|
|
1336
|
+
const shimmer = this.renderShimmer("Cooking");
|
|
1337
|
+
const spinnerChar = chalk5.hex("#F0C040")(spinner);
|
|
1338
|
+
const barLen = 12;
|
|
1339
|
+
const barPos = this.bar % (barLen * 2);
|
|
1340
|
+
const barStr = this.renderBar(barLen, barPos);
|
|
1341
|
+
const phaseStr = this.phase ? ` ${chalk5.gray(this.limitLen(this.phase, 38))}` : "";
|
|
1342
|
+
process.stdout.write(
|
|
1343
|
+
`\r\x1B[2K ${spinnerChar} ${shimmer} ${paletteFn(dotStr)} ${barStr}${phaseStr}`
|
|
1344
|
+
);
|
|
1209
1345
|
}
|
|
1210
1346
|
renderShimmer(text) {
|
|
1211
1347
|
let result = "";
|
|
@@ -1214,14 +1350,36 @@ var init_cooking = __esm({
|
|
|
1214
1350
|
const dist = Math.abs(i - pos);
|
|
1215
1351
|
if (dist < SHINE_WIDTH) {
|
|
1216
1352
|
const t = 1 - dist / SHINE_WIDTH;
|
|
1217
|
-
const
|
|
1218
|
-
result += chalk5.rgb(
|
|
1353
|
+
const g = Math.floor(160 + t * 95);
|
|
1354
|
+
result += chalk5.rgb(g, g, g)(text[i]);
|
|
1219
1355
|
} else {
|
|
1220
|
-
result += chalk5.rgb(
|
|
1356
|
+
result += chalk5.rgb(160, 160, 160)(text[i]);
|
|
1221
1357
|
}
|
|
1222
1358
|
}
|
|
1223
1359
|
return result;
|
|
1224
1360
|
}
|
|
1361
|
+
renderBar(len, pos) {
|
|
1362
|
+
let s = "";
|
|
1363
|
+
for (let i = 0; i < len; i++) {
|
|
1364
|
+
const dist = Math.abs(i - pos);
|
|
1365
|
+
if (dist < 3) {
|
|
1366
|
+
const t = 1 - dist / 3;
|
|
1367
|
+
const r = Math.floor(200 + t * 55);
|
|
1368
|
+
const g = Math.floor(160 + t * 50);
|
|
1369
|
+
const b = Math.floor(20 + t * 30);
|
|
1370
|
+
s += chalk5.rgb(r, g, b)("\u258C");
|
|
1371
|
+
} else if (dist < 6) {
|
|
1372
|
+
s += chalk5.rgb(140, 100, 20)("\u258C");
|
|
1373
|
+
} else {
|
|
1374
|
+
s += chalk5.rgb(50, 35, 10)(" ");
|
|
1375
|
+
}
|
|
1376
|
+
}
|
|
1377
|
+
return `[${s}]`;
|
|
1378
|
+
}
|
|
1379
|
+
limitLen(s, max) {
|
|
1380
|
+
if (s.length <= max) return s;
|
|
1381
|
+
return s.slice(0, max - 3) + "\u2026";
|
|
1382
|
+
}
|
|
1225
1383
|
};
|
|
1226
1384
|
}
|
|
1227
1385
|
});
|
|
@@ -1292,11 +1450,14 @@ var init_exporter = __esm({
|
|
|
1292
1450
|
this.platform = detectPlatform(siteUrl);
|
|
1293
1451
|
}
|
|
1294
1452
|
}
|
|
1295
|
-
async run() {
|
|
1296
|
-
console.log(chalk6.bold.
|
|
1453
|
+
async run(includeSubpages = false) {
|
|
1454
|
+
console.log(chalk6.bold.hex("#D4A017")("\n Cooksite v4 - Full Mirror & Clean Export\n"));
|
|
1297
1455
|
info("Source : " + chalk6.underline(this.siteUrl));
|
|
1298
1456
|
info("Output : " + chalk6.yellow(this.outDir));
|
|
1299
|
-
info("Platform : " + chalk6.
|
|
1457
|
+
info("Platform : " + chalk6.hex("#D4A017")(this.platform.displayName));
|
|
1458
|
+
if (includeSubpages) {
|
|
1459
|
+
info("Subpages : " + chalk6.green("enabled"));
|
|
1460
|
+
}
|
|
1300
1461
|
console.log("");
|
|
1301
1462
|
this.cooking = new CookingSpinner();
|
|
1302
1463
|
setCooking(this.cooking);
|
|
@@ -1310,7 +1471,8 @@ var init_exporter = __esm({
|
|
|
1310
1471
|
"styles",
|
|
1311
1472
|
"scripts/vendor",
|
|
1312
1473
|
"scripts/modules",
|
|
1313
|
-
"data"
|
|
1474
|
+
"data",
|
|
1475
|
+
"subpages"
|
|
1314
1476
|
]) {
|
|
1315
1477
|
await fs4.mkdir(path5.join(this.outDir, d), { recursive: true });
|
|
1316
1478
|
}
|
|
@@ -1327,9 +1489,13 @@ var init_exporter = __esm({
|
|
|
1327
1489
|
const htmlDetected = detectPlatform(this.siteUrl, this.ssrHTML);
|
|
1328
1490
|
if (htmlDetected.name !== this.platform.name) {
|
|
1329
1491
|
this.platform = htmlDetected;
|
|
1330
|
-
log("Platform refined: " + chalk6.
|
|
1492
|
+
log("Platform refined: " + chalk6.hex("#D4A017")(this.platform.displayName) + " (from HTML analysis)");
|
|
1331
1493
|
}
|
|
1332
1494
|
await launchAndCapture(this);
|
|
1495
|
+
if (includeSubpages && this.page) {
|
|
1496
|
+
await this.crawlSubpages();
|
|
1497
|
+
}
|
|
1498
|
+
await closeBrowser(this);
|
|
1333
1499
|
this.cooking.update("Downloading assets...");
|
|
1334
1500
|
await downloadAll(this);
|
|
1335
1501
|
this.cooking.update("Building output...");
|
|
@@ -1340,6 +1506,64 @@ var init_exporter = __esm({
|
|
|
1340
1506
|
success("Export complete!");
|
|
1341
1507
|
await printSummary(this);
|
|
1342
1508
|
}
|
|
1509
|
+
async crawlSubpages() {
|
|
1510
|
+
this.cooking?.update("Discovering sub-pages...");
|
|
1511
|
+
log("Scanning page for internal links...");
|
|
1512
|
+
const page = this.page;
|
|
1513
|
+
const baseUrl = new URL(this.siteUrl);
|
|
1514
|
+
const baseHost = baseUrl.hostname.replace(/^www\./, "");
|
|
1515
|
+
const links = await page.evaluate((host) => {
|
|
1516
|
+
const anchors = Array.from(document.querySelectorAll("a[href]"));
|
|
1517
|
+
const hrefs = /* @__PURE__ */ new Set();
|
|
1518
|
+
for (const a of anchors) {
|
|
1519
|
+
const href = a.href;
|
|
1520
|
+
if (!href || href.startsWith("javascript:") || href.startsWith("mailto:") || href.startsWith("tel:") || href.startsWith("#")) continue;
|
|
1521
|
+
try {
|
|
1522
|
+
const u = new URL(href);
|
|
1523
|
+
const h = u.hostname.replace(/^www\./, "");
|
|
1524
|
+
if (h === host && u.pathname !== "/" && u.pathname !== "" && !u.pathname.startsWith("/#")) {
|
|
1525
|
+
hrefs.add(href.split("#")[0]);
|
|
1526
|
+
}
|
|
1527
|
+
} catch {
|
|
1528
|
+
}
|
|
1529
|
+
}
|
|
1530
|
+
return Array.from(hrefs);
|
|
1531
|
+
}, baseHost);
|
|
1532
|
+
log("Found " + links.length + " sub-page links");
|
|
1533
|
+
const uniqueLinks = [...new Set(links)].slice(0, 50);
|
|
1534
|
+
if (uniqueLinks.length === 0) {
|
|
1535
|
+
log("No sub-pages to crawl");
|
|
1536
|
+
return;
|
|
1537
|
+
}
|
|
1538
|
+
for (let i = 0; i < uniqueLinks.length; i++) {
|
|
1539
|
+
const link = uniqueLinks[i];
|
|
1540
|
+
this.cooking?.update("Crawling sub-page " + (i + 1) + "/" + uniqueLinks.length);
|
|
1541
|
+
try {
|
|
1542
|
+
const html = await captureSubpage(page, link, {
|
|
1543
|
+
needsHydrationCheck: this.platform.needsHydrationCheck,
|
|
1544
|
+
hydrationTimeout: this.platform.hydrationTimeout
|
|
1545
|
+
});
|
|
1546
|
+
const slug = this.deriveSlug(link, baseUrl);
|
|
1547
|
+
const filename = slug + ".html";
|
|
1548
|
+
const filepath = path5.join(this.outDir, "subpages", filename);
|
|
1549
|
+
await fs4.writeFile(filepath, html, "utf-8");
|
|
1550
|
+
log(" Saved: subpages/" + filename);
|
|
1551
|
+
} catch (e) {
|
|
1552
|
+
log(" Skipped " + link + ": " + e.message);
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
success("Sub-pages crawled: " + uniqueLinks.length);
|
|
1556
|
+
}
|
|
1557
|
+
deriveSlug(link, baseUrl) {
|
|
1558
|
+
try {
|
|
1559
|
+
const u = new URL(link);
|
|
1560
|
+
let pathname = u.pathname.replace(/\/+$/, "").replace(/^\//, "");
|
|
1561
|
+
if (!pathname) return "index";
|
|
1562
|
+
return pathname.replace(/[^a-zA-Z0-9_-]/g, "_").replace(/_+/g, "_") || "page";
|
|
1563
|
+
} catch {
|
|
1564
|
+
return "page";
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1343
1567
|
};
|
|
1344
1568
|
}
|
|
1345
1569
|
});
|
|
@@ -1356,10 +1580,10 @@ async function select(question, options, defaultIndex = 0) {
|
|
|
1356
1580
|
stdout.write(`\x1B[${options.length + 1}A`);
|
|
1357
1581
|
stdout.write("\x1B[J");
|
|
1358
1582
|
}
|
|
1359
|
-
console.log(` ${chalk7.
|
|
1583
|
+
console.log(` ${chalk7.hex("#D4A017")("?")} ${chalk7.white.bold(question)}`);
|
|
1360
1584
|
for (let i = 0; i < options.length; i++) {
|
|
1361
1585
|
if (i === selected) {
|
|
1362
|
-
console.log(` ${chalk7.
|
|
1586
|
+
console.log(` ${chalk7.hex("#D4A017")(">")} ${chalk7.white.bold(options[i].label)}`);
|
|
1363
1587
|
} else {
|
|
1364
1588
|
console.log(` ${chalk7.gray(options[i].label)}`);
|
|
1365
1589
|
}
|
|
@@ -1383,7 +1607,7 @@ async function select(question, options, defaultIndex = 0) {
|
|
|
1383
1607
|
stdin.pause();
|
|
1384
1608
|
stdout.write(`\x1B[${options.length + 1}A`);
|
|
1385
1609
|
stdout.write("\x1B[J");
|
|
1386
|
-
console.log(` ${chalk7.green("\u2713")} ${chalk7.white.bold(question)} ${chalk7.
|
|
1610
|
+
console.log(` ${chalk7.green("\u2713")} ${chalk7.white.bold(question)} ${chalk7.hex("#D4A017")(options[selected].label)}
|
|
1387
1611
|
`);
|
|
1388
1612
|
resolve(options[selected].value);
|
|
1389
1613
|
} else if (key.ctrl && key.name === "c" || key.name === "escape") {
|
|
@@ -1418,7 +1642,7 @@ function getWidth3() {
|
|
|
1418
1642
|
function drawHeader(title) {
|
|
1419
1643
|
const width = getWidth3();
|
|
1420
1644
|
const isSmall = width < 50;
|
|
1421
|
-
const magenta = chalk8.
|
|
1645
|
+
const magenta = chalk8.hex("#D4A017");
|
|
1422
1646
|
const boldWhite = chalk8.bold.white;
|
|
1423
1647
|
if (isSmall) {
|
|
1424
1648
|
console.log(`
|
|
@@ -1436,7 +1660,7 @@ ${magenta("\u25CF")} ${boldWhite(title)}`);
|
|
|
1436
1660
|
function line(label, value) {
|
|
1437
1661
|
const width = getWidth3();
|
|
1438
1662
|
const isSmall = width < 50;
|
|
1439
|
-
const magenta = chalk8.
|
|
1663
|
+
const magenta = chalk8.hex("#D4A017");
|
|
1440
1664
|
if (isSmall) {
|
|
1441
1665
|
console.log(` ${chalk8.bold(label)}: ${chalk8.yellow(value)}`);
|
|
1442
1666
|
return;
|
|
@@ -1450,7 +1674,7 @@ async function runSetup(legacyMode = false) {
|
|
|
1450
1674
|
const rl = readline2.createInterface({ input: stdin2, output: stdout2 });
|
|
1451
1675
|
const ask = async (question, defaultVal) => {
|
|
1452
1676
|
const suffix = defaultVal ? chalk8.gray(` (${defaultVal})`) : "";
|
|
1453
|
-
const prompt = ` ${chalk8.
|
|
1677
|
+
const prompt = ` ${chalk8.hex("#D4A017")("?")} ${chalk8.white.bold(question)}${suffix} ${chalk8.gray(">")} `;
|
|
1454
1678
|
const answer = await rl.question(prompt);
|
|
1455
1679
|
return answer.trim() || defaultVal || "";
|
|
1456
1680
|
};
|
|
@@ -1472,10 +1696,10 @@ async function runSetup(legacyMode = false) {
|
|
|
1472
1696
|
const detected = detectPlatform(siteUrl);
|
|
1473
1697
|
let platformName;
|
|
1474
1698
|
if (legacyMode) {
|
|
1475
|
-
console.log(` ${chalk8.blue("i")} Auto-detected: ${chalk8.
|
|
1699
|
+
console.log(` ${chalk8.blue("i")} Auto-detected: ${chalk8.hex("#D4A017")(detected.displayName)}`);
|
|
1476
1700
|
const platformInput = await ask("Platform (framer/webflow/wix)", detected.name);
|
|
1477
1701
|
platformName = ["framer", "webflow", "wix"].includes(platformInput) ? platformInput : detected.name;
|
|
1478
|
-
console.log(` ${chalk8.green("\u2713")} ${chalk8.green("Platform:")} ${chalk8.
|
|
1702
|
+
console.log(` ${chalk8.green("\u2713")} ${chalk8.green("Platform:")} ${chalk8.hex("#D4A017")(platformName)}
|
|
1479
1703
|
`);
|
|
1480
1704
|
} else {
|
|
1481
1705
|
rl.close();
|
|
@@ -1490,7 +1714,7 @@ async function runSetup(legacyMode = false) {
|
|
|
1490
1714
|
const rl2 = legacyMode ? rl : readline2.createInterface({ input: stdin2, output: stdout2 });
|
|
1491
1715
|
const ask2 = async (question, defaultVal) => {
|
|
1492
1716
|
const suffix = defaultVal ? chalk8.gray(` (${defaultVal})`) : "";
|
|
1493
|
-
const prompt = ` ${chalk8.
|
|
1717
|
+
const prompt = ` ${chalk8.hex("#D4A017")("?")} ${chalk8.white.bold(question)}${suffix} ${chalk8.gray(">")} `;
|
|
1494
1718
|
const answer = await rl2.question(prompt);
|
|
1495
1719
|
return answer.trim() || defaultVal || "";
|
|
1496
1720
|
};
|
|
@@ -1502,10 +1726,15 @@ async function runSetup(legacyMode = false) {
|
|
|
1502
1726
|
drawHeader("Step 4 : Options");
|
|
1503
1727
|
let prettyPrint;
|
|
1504
1728
|
let concurrency;
|
|
1729
|
+
let includeSubpages;
|
|
1505
1730
|
if (legacyMode) {
|
|
1506
1731
|
const prettyAnswer = await ask2("Pretty-print JS files? (y/n)", "y");
|
|
1507
1732
|
prettyPrint = prettyAnswer.toLowerCase().startsWith("y");
|
|
1508
1733
|
console.log(` ${chalk8.green("\u2713")} Pretty-print: ${prettyPrint ? chalk8.green("yes") : chalk8.red("no")}
|
|
1734
|
+
`);
|
|
1735
|
+
const subpagesAnswer = await ask2("Export sub-pages? (y/n)", "n");
|
|
1736
|
+
includeSubpages = subpagesAnswer.toLowerCase().startsWith("y");
|
|
1737
|
+
console.log(` ${chalk8.green("\u2713")} Sub-pages: ${includeSubpages ? chalk8.green("yes") : chalk8.red("no")}
|
|
1509
1738
|
`);
|
|
1510
1739
|
const concurrencyAnswer = await ask2("Download concurrency", "12");
|
|
1511
1740
|
concurrency = parseInt(concurrencyAnswer, 10) || 12;
|
|
@@ -1518,6 +1747,11 @@ async function runSetup(legacyMode = false) {
|
|
|
1518
1747
|
{ label: "No", value: "no" }
|
|
1519
1748
|
]);
|
|
1520
1749
|
prettyPrint = prettyVal === "yes";
|
|
1750
|
+
const subpagesVal = await select("Export sub-pages?", [
|
|
1751
|
+
{ label: "No", value: "no" },
|
|
1752
|
+
{ label: "Yes, crawl and export", value: "yes" }
|
|
1753
|
+
], 0);
|
|
1754
|
+
includeSubpages = subpagesVal === "yes";
|
|
1521
1755
|
const concurrencyVal = await select("Download concurrency", [
|
|
1522
1756
|
{ label: "6 (slow connection)", value: "6" },
|
|
1523
1757
|
{ label: "12 (default)", value: "12" },
|
|
@@ -1529,9 +1763,9 @@ async function runSetup(legacyMode = false) {
|
|
|
1529
1763
|
const width = getWidth3();
|
|
1530
1764
|
const isSmall = width < 50;
|
|
1531
1765
|
if (!isSmall) {
|
|
1532
|
-
console.log(chalk8.
|
|
1533
|
-
console.log(chalk8.
|
|
1534
|
-
console.log(chalk8.
|
|
1766
|
+
console.log(chalk8.hex("#D4A017")(" \u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510"));
|
|
1767
|
+
console.log(chalk8.hex("#D4A017")(" \u2502") + chalk8.bold.white(" Summary ") + chalk8.hex("#D4A017")("\u2502"));
|
|
1768
|
+
console.log(chalk8.hex("#D4A017")(" \u251C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524"));
|
|
1535
1769
|
} else {
|
|
1536
1770
|
console.log(chalk8.bold.white(" Summary:"));
|
|
1537
1771
|
}
|
|
@@ -1539,9 +1773,10 @@ async function runSetup(legacyMode = false) {
|
|
|
1539
1773
|
line("Platform", platformName);
|
|
1540
1774
|
line("Output", path6.resolve(outDir));
|
|
1541
1775
|
line("Pretty-print", prettyPrint ? "yes" : "no");
|
|
1776
|
+
line("Sub-pages", includeSubpages ? "yes" : "no");
|
|
1542
1777
|
line("Concurrency", String(concurrency));
|
|
1543
1778
|
if (!isSmall) {
|
|
1544
|
-
console.log(chalk8.
|
|
1779
|
+
console.log(chalk8.hex("#D4A017")(" \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518"));
|
|
1545
1780
|
}
|
|
1546
1781
|
console.log("");
|
|
1547
1782
|
let startExport;
|
|
@@ -1567,7 +1802,7 @@ async function runSetup(legacyMode = false) {
|
|
|
1567
1802
|
CFG2.concurrency = concurrency;
|
|
1568
1803
|
const exporter = new FramerExporter(siteUrl, path6.resolve(outDir), platformName);
|
|
1569
1804
|
exporter.prettyPrint = prettyPrint;
|
|
1570
|
-
await exporter.run();
|
|
1805
|
+
await exporter.run(includeSubpages);
|
|
1571
1806
|
}
|
|
1572
1807
|
var init_setup = __esm({
|
|
1573
1808
|
"src/cli/setup.ts"() {
|
|
@@ -1590,14 +1825,14 @@ import chalk2 from "chalk";
|
|
|
1590
1825
|
function showHelp() {
|
|
1591
1826
|
showBanner();
|
|
1592
1827
|
console.log(chalk2.white.bold(" USAGE\n"));
|
|
1593
|
-
console.log(` ${chalk2.
|
|
1594
|
-
console.log(` ${chalk2.
|
|
1595
|
-
console.log(` ${chalk2.cyan("framer-export")} ${chalk2.yellow("<url>")} ${chalk2.gray("[output-dir]")}`);
|
|
1828
|
+
console.log(` ${chalk2.hex("#D4A017")("framer-export")} ${chalk2.yellow("<url>")} ${chalk2.gray("[output-dir]")}`);
|
|
1829
|
+
console.log(` ${chalk2.hex("#D4A017")("fexport")} ${chalk2.yellow("<url>")} ${chalk2.gray("[output-dir]")}`);
|
|
1596
1830
|
console.log("");
|
|
1597
1831
|
console.log(chalk2.white.bold(" OPTIONS\n"));
|
|
1598
1832
|
const opts = [
|
|
1599
1833
|
["--setup", "Launch the interactive setup assistant"],
|
|
1600
1834
|
["--platform <p>", "Force platform: framer, webflow, wix"],
|
|
1835
|
+
["--subpages", "Crawl and export sub-pages"],
|
|
1601
1836
|
["--legacy-mode", "Use text input instead of arrow selection"],
|
|
1602
1837
|
["--help, -h", "Show this help message"]
|
|
1603
1838
|
];
|
|
@@ -1607,21 +1842,22 @@ function showHelp() {
|
|
|
1607
1842
|
console.log("");
|
|
1608
1843
|
console.log(chalk2.white.bold(" SUPPORTED PLATFORMS\n"));
|
|
1609
1844
|
const platforms = [
|
|
1610
|
-
["Framer", "Auto-detected via .framer.app / .framer.
|
|
1845
|
+
["Framer", "Auto-detected via .framer.app / .framer.website URLs"],
|
|
1611
1846
|
["Webflow", "Auto-detected via .webflow.io URLs"],
|
|
1612
|
-
["Wix", "Auto-detected via .wixsite.com URLs"]
|
|
1847
|
+
["Wix", "Auto-detected via .wixsite.com URLs + HTML analysis"]
|
|
1613
1848
|
];
|
|
1614
1849
|
for (const [name, desc] of platforms) {
|
|
1615
|
-
console.log(` ${chalk2.
|
|
1850
|
+
console.log(` ${chalk2.hex("#D4A017")(name.padEnd(12))} ${chalk2.gray(desc)}`);
|
|
1616
1851
|
}
|
|
1617
1852
|
console.log("");
|
|
1618
1853
|
console.log(chalk2.white.bold(" EXAMPLES\n"));
|
|
1619
|
-
console.log(` ${chalk2.gray("$")} ${chalk2.
|
|
1620
|
-
console.log(` ${chalk2.gray("$")} ${chalk2.
|
|
1621
|
-
console.log(` ${chalk2.gray("$")} ${chalk2.
|
|
1622
|
-
console.log(` ${chalk2.gray("$")} ${chalk2.
|
|
1623
|
-
console.log(` ${chalk2.gray("$")} ${chalk2.
|
|
1624
|
-
console.log(` ${chalk2.gray("$")} ${chalk2.
|
|
1854
|
+
console.log(` ${chalk2.gray("$")} ${chalk2.hex("#D4A017")("framer-export")} ${chalk2.yellow("https://mysite.framer.app")}`);
|
|
1855
|
+
console.log(` ${chalk2.gray("$")} ${chalk2.hex("#D4A017")("framer-export")} ${chalk2.yellow("https://mysite.webflow.io")}`);
|
|
1856
|
+
console.log(` ${chalk2.gray("$")} ${chalk2.hex("#D4A017")("framer-export")} ${chalk2.yellow("https://user.wixsite.com/my-site")}`);
|
|
1857
|
+
console.log(` ${chalk2.gray("$")} ${chalk2.hex("#D4A017")("framer-export")} ${chalk2.green("--platform webflow")} ${chalk2.yellow("https://custom.com")}`);
|
|
1858
|
+
console.log(` ${chalk2.gray("$")} ${chalk2.hex("#D4A017")("framer-export")} ${chalk2.green("--subpages")} ${chalk2.yellow("https://mysite.com")}`);
|
|
1859
|
+
console.log(` ${chalk2.gray("$")} ${chalk2.hex("#D4A017")("framer-export")} ${chalk2.green("--setup")}`);
|
|
1860
|
+
console.log(` ${chalk2.gray("$")} ${chalk2.hex("#D4A017")("framer-export")} ${chalk2.green("--setup --legacy-mode")}`);
|
|
1625
1861
|
console.log("");
|
|
1626
1862
|
}
|
|
1627
1863
|
|
|
@@ -1686,10 +1922,10 @@ async function main() {
|
|
|
1686
1922
|
console.log(` ${chalk9.white.bold("Framer Export")} ${chalk9.gray(`v${package_default.version}`)}`);
|
|
1687
1923
|
console.log(` ${chalk9.white(package_default.description)}
|
|
1688
1924
|
`);
|
|
1689
|
-
console.log(` ${chalk9.white.bold("Author")} ${chalk9.
|
|
1690
|
-
console.log(` ${chalk9.white.bold("Portfolio")} ${chalk9.underline.
|
|
1691
|
-
console.log(` ${chalk9.white.bold("GitHub")} ${chalk9.underline.
|
|
1692
|
-
console.log(` ${chalk9.white.bold("npm")} ${chalk9.underline.
|
|
1925
|
+
console.log(` ${chalk9.white.bold("Author")} ${chalk9.hex("#D4A017")("Dany (danbenba)")}`);
|
|
1926
|
+
console.log(` ${chalk9.white.bold("Portfolio")} ${chalk9.underline.hex("#D4A017")("https://github.com/danbenba")}`);
|
|
1927
|
+
console.log(` ${chalk9.white.bold("GitHub")} ${chalk9.underline.hex("#D4A017")(package_default.repository.url.replace("git+", "").replace(".git", ""))}`);
|
|
1928
|
+
console.log(` ${chalk9.white.bold("npm")} ${chalk9.underline.hex("#D4A017")(`https://www.npmjs.com/package/${package_default.name}`)}`);
|
|
1693
1929
|
console.log(` ${chalk9.white.bold("License")} ${chalk9.green(package_default.license)}`);
|
|
1694
1930
|
console.log(` ${chalk9.white.bold("Node")} ${chalk9.gray(`>=${package_default.engines.node}`)}`);
|
|
1695
1931
|
console.log("");
|
|
@@ -1702,7 +1938,7 @@ async function main() {
|
|
|
1702
1938
|
console.log(
|
|
1703
1939
|
` ${chalk9.default.yellow("\u21B3")} Update available: ${chalk9.default.gray(VERSION)} \u2192 ${chalk9.default.green(latest)}`
|
|
1704
1940
|
);
|
|
1705
|
-
console.log(` ${chalk9.default.
|
|
1941
|
+
console.log(` ${chalk9.default.hex("#D4A017")(" Run:")} ${chalk9.default.hex("#B8860B")("npm i -g framer-export@latest")}`);
|
|
1706
1942
|
console.log("");
|
|
1707
1943
|
});
|
|
1708
1944
|
});
|
|
@@ -1723,6 +1959,7 @@ async function main() {
|
|
|
1723
1959
|
return;
|
|
1724
1960
|
}
|
|
1725
1961
|
const platformOverride = extractFlag(args, "--platform");
|
|
1962
|
+
const includeSubpages = hasFlag(args, "--subpages");
|
|
1726
1963
|
showBanner();
|
|
1727
1964
|
const url = args[0];
|
|
1728
1965
|
try {
|
|
@@ -1740,7 +1977,7 @@ async function main() {
|
|
|
1740
1977
|
const defaultDir = deriveOutputName2(url, detected);
|
|
1741
1978
|
const out = args[1] || `./${defaultDir}`;
|
|
1742
1979
|
try {
|
|
1743
|
-
await new FramerExporter2(url, path7.resolve(out), platformOverride || void 0).run();
|
|
1980
|
+
await new FramerExporter2(url, path7.resolve(out), platformOverride || void 0).run(includeSubpages);
|
|
1744
1981
|
} catch (e) {
|
|
1745
1982
|
const chalk9 = (await import("chalk")).default;
|
|
1746
1983
|
console.log(`
|