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 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.2",
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 * SHINE_SPEED % travel - shineWidth;
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 visible = stripAnsi(text).length;
342
- if (visible >= w) return text;
343
- return text + " ".repeat(w - visible);
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 visible = labelPlain.length + 1 + value.length;
383
- if (visible > inner) {
384
- const avail = inner - labelPlain.length - 2;
385
- const truncated = value.length > avail ? value.slice(0, avail - 1) + ".." : value;
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 frameLine(label, value) {
1691
- const text = ' ' + label.padEnd(10) + value;
1692
- const pad = Math.max(0, 56 - text.length);
1693
- console.log(' ' + color('border', '\u2502 ') + color('muted', label.padEnd(10)) + color('text', value) + ' '.repeat(pad) + color('border', ' \u2502'));
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 step = steps[Math.min(steps.length - 1, Math.floor(i / 6))];
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('text', step) + dots);
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 = false;
2257
+ let copyServeCommand = true;
2176
2258
  while (true) {
2177
2259
  const action = await select(
2178
2260
  "Export complete",