framer-export 4.4.2 → 4.4.3
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 +107 -25
- 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.4.
|
|
18
|
+
version: "4.4.3",
|
|
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",
|
|
@@ -215,7 +215,8 @@ async function showLoadingIntro(version) {
|
|
|
215
215
|
const title = renderShinyText(`Framer Export v${version}`, frame, {
|
|
216
216
|
baseColor: "#969696",
|
|
217
217
|
shineColor: "#ffffff",
|
|
218
|
-
shineWidth: 18
|
|
218
|
+
shineWidth: 18,
|
|
219
|
+
speed: 1.2
|
|
219
220
|
});
|
|
220
221
|
const dots = ".".repeat(frame % 4).padEnd(3, " ");
|
|
221
222
|
process.stdout.write(
|
|
@@ -237,8 +238,9 @@ function renderShinyText(text, frame, options = {}) {
|
|
|
237
238
|
const baseColor = options.baseColor || "#808080";
|
|
238
239
|
const shineColor = options.shineColor || "#ffffff";
|
|
239
240
|
const shineWidth = options.shineWidth || SHINE_WIDTH;
|
|
241
|
+
const speed = options.speed ?? SHINE_SPEED;
|
|
240
242
|
const travel = text.length + shineWidth * 2;
|
|
241
|
-
const pos = frame *
|
|
243
|
+
const pos = frame * speed % travel - shineWidth;
|
|
242
244
|
const base = hexToRgb(baseColor);
|
|
243
245
|
const shine = hexToRgb(shineColor);
|
|
244
246
|
let result = "";
|
|
@@ -338,9 +340,66 @@ function maxWidth() {
|
|
|
338
340
|
return Math.min(process.stdout.columns || 80, 76);
|
|
339
341
|
}
|
|
340
342
|
function padRight(text, w) {
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
|
|
343
|
+
const fitted = fitAnsi(text, w);
|
|
344
|
+
const visible = stripAnsi(fitted).length;
|
|
345
|
+
if (visible >= w) return fitted;
|
|
346
|
+
return fitted + " ".repeat(w - visible);
|
|
347
|
+
}
|
|
348
|
+
function fitAnsi(text, width) {
|
|
349
|
+
if (stripAnsi(text).length <= width) return text;
|
|
350
|
+
if (width <= 2) return ".".repeat(Math.max(0, width));
|
|
351
|
+
let out = "";
|
|
352
|
+
let visible = 0;
|
|
353
|
+
let i = 0;
|
|
354
|
+
const limit = width - 2;
|
|
355
|
+
while (i < text.length && visible < limit) {
|
|
356
|
+
if (text[i] === "\x1B") {
|
|
357
|
+
const match = text.slice(i).match(/^\x1B\[[0-9;]*[a-zA-Z]/);
|
|
358
|
+
if (match) {
|
|
359
|
+
out += match[0];
|
|
360
|
+
i += match[0].length;
|
|
361
|
+
continue;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
out += text[i];
|
|
365
|
+
visible++;
|
|
366
|
+
i++;
|
|
367
|
+
}
|
|
368
|
+
return out + "..\x1B[0m";
|
|
369
|
+
}
|
|
370
|
+
function fitValue(value, width) {
|
|
371
|
+
if (value.length <= width) return value;
|
|
372
|
+
const pathLike = value.includes("\\") || value.includes("/");
|
|
373
|
+
if (pathLike) {
|
|
374
|
+
const shortened = shortenPath(value, width);
|
|
375
|
+
if (shortened.length <= width) return shortened;
|
|
376
|
+
}
|
|
377
|
+
if (width <= 3) return ".".repeat(Math.max(0, width));
|
|
378
|
+
return value.slice(0, width - 2) + "..";
|
|
379
|
+
}
|
|
380
|
+
function shortenPath(value, width) {
|
|
381
|
+
if (width <= 12) {
|
|
382
|
+
return width <= 3 ? ".".repeat(Math.max(0, width)) : value.slice(0, width - 2) + "..";
|
|
383
|
+
}
|
|
384
|
+
const separator = value.includes("\\") ? "\\" : "/";
|
|
385
|
+
const parts = value.split(/[\\/]+/).filter(Boolean);
|
|
386
|
+
const prefix = value.startsWith(separator) ? separator : "";
|
|
387
|
+
const shortened = parts.map((part, index) => {
|
|
388
|
+
const isLast = index === parts.length - 1;
|
|
389
|
+
if (isLast) return part;
|
|
390
|
+
if (/^[A-Za-z]:$/.test(part)) return part;
|
|
391
|
+
return part.length > 5 ? part.slice(0, 3) + ".." : part;
|
|
392
|
+
}).join(separator);
|
|
393
|
+
const withPrefix = prefix + shortened;
|
|
394
|
+
if (withPrefix.length <= width) return withPrefix;
|
|
395
|
+
const last = parts.at(-1) || value;
|
|
396
|
+
const first = parts.slice(0, -1).map((part) => /^[A-Za-z]:$/.test(part) ? part : part.slice(0, 3) + "..");
|
|
397
|
+
const compact = prefix + [...first, last].join(separator);
|
|
398
|
+
if (compact.length <= width) return compact;
|
|
399
|
+
const tailSpace = Math.max(8, Math.floor(width * 0.45));
|
|
400
|
+
const headSpace = Math.max(0, width - tailSpace - 4);
|
|
401
|
+
const middle = compact.slice(0, headSpace) + separator + ".." + separator + compact.slice(-tailSpace);
|
|
402
|
+
return middle.length <= width ? middle : compact.slice(0, width - 2) + "..";
|
|
344
403
|
}
|
|
345
404
|
function boxTop(w) {
|
|
346
405
|
const inner = w - 4;
|
|
@@ -379,14 +438,10 @@ function panelSep(w) {
|
|
|
379
438
|
function boxRow(w, label, value) {
|
|
380
439
|
const inner = w - 4;
|
|
381
440
|
const labelPlain = stripAnsi(chalk3.bold(label));
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
return " " + ui.border("\u2502 ") + chalk3.bold(label) + ": " + ui.primary(truncated) + " ".repeat(Math.max(0, inner - labelPlain.length - 1 - truncated.length)) + ui.border(" \u2502");
|
|
387
|
-
}
|
|
388
|
-
const right = inner - labelPlain.length - 1 - value.length;
|
|
389
|
-
return " " + ui.border("\u2502 ") + chalk3.bold(label) + ": " + ui.primary(value) + " ".repeat(right) + ui.border(" \u2502");
|
|
441
|
+
const avail = Math.max(0, inner - labelPlain.length - 2);
|
|
442
|
+
const fittedValue = fitValue(value, avail);
|
|
443
|
+
const right = Math.max(0, inner - labelPlain.length - 2 - fittedValue.length);
|
|
444
|
+
return " " + ui.border("\u2502 ") + chalk3.bold(label) + ": " + ui.primary(fittedValue) + " ".repeat(right) + ui.border(" \u2502");
|
|
390
445
|
}
|
|
391
446
|
var init_box = __esm({
|
|
392
447
|
"src/cli/box.ts"() {
|
|
@@ -1680,6 +1735,9 @@ const ANSI = {
|
|
|
1680
1735
|
border: '\\x1b[38;2;72;72;72m',
|
|
1681
1736
|
success: '\\x1b[38;2;127;216;143m',
|
|
1682
1737
|
info: '\\x1b[38;2;86;182;194m',
|
|
1738
|
+
accent: '\\x1b[38;2;157;124;216m',
|
|
1739
|
+
warning: '\\x1b[38;2;245;167;66m',
|
|
1740
|
+
command: '\\x1b[38;2;255;192;159m',
|
|
1683
1741
|
error: '\\x1b[38;2;224;108;117m',
|
|
1684
1742
|
};
|
|
1685
1743
|
|
|
@@ -1687,10 +1745,32 @@ function color(name, value) {
|
|
|
1687
1745
|
return ANSI[name] + value + ANSI.reset;
|
|
1688
1746
|
}
|
|
1689
1747
|
|
|
1690
|
-
function
|
|
1691
|
-
const text =
|
|
1692
|
-
|
|
1693
|
-
|
|
1748
|
+
function fitValue(value, width) {
|
|
1749
|
+
const text = String(value);
|
|
1750
|
+
if (text.length <= width) return text;
|
|
1751
|
+
if ((text.includes('\\\\') || text.includes('/')) && width > 12) {
|
|
1752
|
+
const separator = text.includes('\\\\') ? '\\\\' : '/';
|
|
1753
|
+
const prefix = text.startsWith(separator) ? separator : '';
|
|
1754
|
+
const parts = text.split(/[\\\\/]+/).filter(Boolean);
|
|
1755
|
+
const compact = prefix + parts.map((part, index) => {
|
|
1756
|
+
if (index === parts.length - 1) return part;
|
|
1757
|
+
if (/^[A-Za-z]:$/.test(part)) return part;
|
|
1758
|
+
return part.length > 5 ? part.slice(0, 3) + '..' : part;
|
|
1759
|
+
}).join(separator);
|
|
1760
|
+
if (compact.length <= width) return compact;
|
|
1761
|
+
const tail = Math.max(8, Math.floor(width * 0.45));
|
|
1762
|
+
const head = Math.max(0, width - tail - 4);
|
|
1763
|
+
return compact.slice(0, head) + separator + '..' + separator + compact.slice(-tail);
|
|
1764
|
+
}
|
|
1765
|
+
return width <= 3 ? '.'.repeat(Math.max(0, width)) : text.slice(0, width - 2) + '..';
|
|
1766
|
+
}
|
|
1767
|
+
|
|
1768
|
+
function frameLine(label, value, colorName = 'text') {
|
|
1769
|
+
const labelText = label.padEnd(10);
|
|
1770
|
+
const valueWidth = Math.max(0, 56 - labelText.length);
|
|
1771
|
+
const shown = fitValue(value, valueWidth);
|
|
1772
|
+
const pad = Math.max(0, 56 - labelText.length - shown.length);
|
|
1773
|
+
console.log(' ' + color('border', '\u2502 ') + color('muted', labelText) + color(colorName, shown) + ' '.repeat(pad) + color('border', ' \u2502'));
|
|
1694
1774
|
}
|
|
1695
1775
|
|
|
1696
1776
|
function drawServerUi() {
|
|
@@ -1698,10 +1778,10 @@ function drawServerUi() {
|
|
|
1698
1778
|
console.log(' ' + color('border', '\u256D\u2500' + '\u2500'.repeat(56) + '\u2500\u256E'));
|
|
1699
1779
|
console.log(' ' + color('border', '\u2502 ') + color('text', ' Framer Export preview server') + ' '.repeat(26) + color('border', ' \u2502'));
|
|
1700
1780
|
console.log(' ' + color('border', '\u251C\u2500' + '\u2500'.repeat(56) + '\u2500\u2524'));
|
|
1701
|
-
frameLine('URL', 'http://localhost:' + PORT);
|
|
1702
|
-
frameLine('Root', ROOT);
|
|
1703
|
-
frameLine('Run', 'node serve.js');
|
|
1704
|
-
frameLine('Mode', 'static mirror + SPA fallback');
|
|
1781
|
+
frameLine('URL', 'http://localhost:' + PORT, 'primary');
|
|
1782
|
+
frameLine('Root', ROOT, 'soft');
|
|
1783
|
+
frameLine('Run', 'node serve.js', 'command');
|
|
1784
|
+
frameLine('Mode', 'static mirror + SPA fallback', 'accent');
|
|
1705
1785
|
console.log(' ' + color('border', '\u2570\u2500' + '\u2500'.repeat(56) + '\u2500\u256F'));
|
|
1706
1786
|
console.log('');
|
|
1707
1787
|
console.log(' ' + color('success', 'ready') + color('muted', ' press Ctrl+C to stop') + '\\n');
|
|
@@ -1710,11 +1790,13 @@ function drawServerUi() {
|
|
|
1710
1790
|
server.listen(PORT, () => {
|
|
1711
1791
|
const frames = ['\u280B', '\u2819', '\u2839', '\u2838', '\u283C', '\u2834', '\u2826', '\u2827', '\u2807', '\u280F'];
|
|
1712
1792
|
const steps = ['Preparing server', 'Checking exported files', 'Binding local port', 'Serving static mirror'];
|
|
1793
|
+
const stepColors = ['text', 'info', 'warning', 'success'];
|
|
1713
1794
|
let i = 0;
|
|
1714
1795
|
const timer = setInterval(() => {
|
|
1715
|
-
const
|
|
1796
|
+
const stepIndex = Math.min(steps.length - 1, Math.floor(i / 6));
|
|
1797
|
+
const step = steps[stepIndex];
|
|
1716
1798
|
const dots = color('error', '.'.repeat(i % 4).padEnd(3, ' '));
|
|
1717
|
-
process.stdout.write('\\r\\x1B[2K ' + color('primary', frames[i % frames.length]) + ' ' + color(
|
|
1799
|
+
process.stdout.write('\\r\\x1B[2K ' + color('primary', frames[i % frames.length]) + ' ' + color(stepColors[stepIndex], step) + dots);
|
|
1718
1800
|
i++;
|
|
1719
1801
|
}, 80);
|
|
1720
1802
|
|
|
@@ -2172,7 +2254,7 @@ function buildServeCommand(exporter) {
|
|
|
2172
2254
|
return `cd ${path5.basename(exporter.outDir)} && node serve.js`;
|
|
2173
2255
|
}
|
|
2174
2256
|
async function runExportCompletePrompt(exporter, serveCommand) {
|
|
2175
|
-
let copyServeCommand =
|
|
2257
|
+
let copyServeCommand = true;
|
|
2176
2258
|
while (true) {
|
|
2177
2259
|
const action = await select(
|
|
2178
2260
|
"Export complete",
|