@omniharmonic/openspace-cli 0.1.13 → 0.1.15

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.
Files changed (30) hide show
  1. package/dist/{agents-md-QBMFXTIQ.js → agents-md-OWDSHBGF.js} +2 -2
  2. package/dist/bin.js +3 -3
  3. package/dist/{chunk-IXN2CNGL.js → chunk-GMKHKHUR.js} +206 -39
  4. package/dist/chunk-GMKHKHUR.js.map +1 -0
  5. package/dist/{chunk-B5C7S4S5.js → chunk-PBN36VUE.js} +2775 -184
  6. package/dist/chunk-PBN36VUE.js.map +1 -0
  7. package/dist/{chunk-EFSGZWAO.js → chunk-YAPLQ4OA.js} +155 -16
  8. package/dist/chunk-YAPLQ4OA.js.map +1 -0
  9. package/dist/{crawl-TAADG5BR.js → crawl-WQQDFI7W.js} +2 -2
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.js +3 -3
  12. package/dist/starter/site/AGENTS.md +4 -4
  13. package/dist/templates/darkroom/content/pages/about.json +2 -2
  14. package/dist/templates/encore/content/pages/home.json +1 -1
  15. package/dist/templates/folio/content/pages/home.json +2 -2
  16. package/dist/templates/gather/content/pages/home.json +2 -2
  17. package/dist/templates/harbor/content/pages/home.json +1 -1
  18. package/dist/templates/hearth/content/pages/home.json +6 -6
  19. package/dist/templates/inkwell/content/pages/about.json +2 -2
  20. package/dist/templates/inkwell/content/pages/books.json +1 -1
  21. package/dist/templates/keystone/content/pages/about.json +2 -2
  22. package/dist/templates/kiln/content/pages/home.json +7 -5
  23. package/dist/templates/ledger/content/pages/about.json +4 -4
  24. package/dist/templates/vow/content/pages/home.json +1 -1
  25. package/package.json +8 -8
  26. package/dist/chunk-B5C7S4S5.js.map +0 -1
  27. package/dist/chunk-EFSGZWAO.js.map +0 -1
  28. package/dist/chunk-IXN2CNGL.js.map +0 -1
  29. /package/dist/{agents-md-QBMFXTIQ.js.map → agents-md-OWDSHBGF.js.map} +0 -0
  30. /package/dist/{crawl-TAADG5BR.js.map → crawl-WQQDFI7W.js.map} +0 -0
@@ -8511,6 +8511,15 @@ function scriptText(el) {
8511
8511
  }
8512
8512
 
8513
8513
  // ../import/src/squarespace/blocks.ts
8514
+ function signupAsksName(form) {
8515
+ return !!find(form, (e) => {
8516
+ if (e.tagName !== "input") return false;
8517
+ const t = (attr(e, "type") ?? "text").toLowerCase();
8518
+ if (t !== "text" || attr(e, "tabindex") === "-1") return false;
8519
+ const key = `${attr(e, "name") ?? ""} ${attr(e, "id") ?? ""} ${attr(e, "autocomplete") ?? ""}`;
8520
+ return /first.?name|given-name|\bfname\b|full.?name|(?:^|[\s_-])name(?:$|[\s_-])/i.test(key);
8521
+ });
8522
+ }
8514
8523
  function cleanImageUrl(raw) {
8515
8524
  let url = raw.trim();
8516
8525
  if (url.startsWith("//")) url = `https:${url}`;
@@ -8816,6 +8825,7 @@ function parseBlock(el) {
8816
8825
  const success = text(find(el, (e) => classes(e).some((c) => /form-submission-text/.test(c))));
8817
8826
  return {
8818
8827
  kind: "newsletter",
8828
+ ...signupAsksName(el) ? { askName: true } : {},
8819
8829
  ...heading ? { heading } : {},
8820
8830
  ...description ? { description } : {},
8821
8831
  ...button ? { buttonLabel: button } : {},
@@ -8931,7 +8941,20 @@ function parseBlock(el) {
8931
8941
  const image = img ? imageFrom(img) : void 0;
8932
8942
  if (image) return { kind: "image", image, ...href ? { href } : {} };
8933
8943
  }
8934
- return { kind: "product", ...href ? { path: href } : {} };
8944
+ const shows = (part) => {
8945
+ const m = new RegExp(`--product-block-display-${part}\\s*:\\s*([a-z-]+)`).exec(styles);
8946
+ return m ? m[1] !== "none" : void 0;
8947
+ };
8948
+ const show = {
8949
+ ...shows("price") === false ? { price: false } : {},
8950
+ ...shows("excerpt") === false ? { excerpt: false } : {},
8951
+ ...shows("purchase-controls") === false ? { buy: false } : {}
8952
+ };
8953
+ return {
8954
+ kind: "product",
8955
+ ...href ? { path: href } : {},
8956
+ ...Object.keys(show).length ? { show } : {}
8957
+ };
8935
8958
  }
8936
8959
  case "shape":
8937
8960
  return void 0;
@@ -9101,7 +9124,7 @@ function parseTheme(css, bodyClasses = []) {
9101
9124
  if (style === "solid" || style === "outline" || style === "raised") theme.buttons.style = style;
9102
9125
  if (has2("tweak-fixed-header") || has2("tweak-fixed-header-style-basic") || has2("tweak-fixed-header-style-scroll-back"))
9103
9126
  theme.headerFixed = true;
9104
- if (has2("tweak-transparent-header")) theme.headerTransparent = true;
9127
+ if (has2("tweak-transparent-header") || has2("transparent-header")) theme.headerTransparent = true;
9105
9128
  return theme;
9106
9129
  }
9107
9130
 
@@ -9391,7 +9414,7 @@ var INLINE_TAGS = /* @__PURE__ */ new Set([
9391
9414
  "font",
9392
9415
  "wbr"
9393
9416
  ]);
9394
- var BOILERPLATE = /(?:^|[\s_-])(?:cookie|consent|gdpr|cc-window|popup|modal|skip-link|skip-to|screen-reader|sr-only|visually-hidden|visuallyhidden|w-nav-overlay|mobile-menu|menu-overlay|offcanvas|breadcrumbs?|pagination|nav-links|post-navigation|comments?-area|comment-respond|share-buttons|sharedaddy|jp-relatedposts|wp-block-navigation|search-form|searchform|announcement-bar|back-to-top|wixui-anchor-menu|elementor-hidden|w-form-done|w-form-fail|w-webflow-badge)(?:$|[\s_-])/i;
9417
+ var BOILERPLATE = /(?:^|[\s_-])(?:cookie|consent|gdpr|cc-window|popup|modal|skip-link|skip-to|screen-reader|sr-only|visually-hidden|visuallyhidden|w-nav-overlay|mobile-menu|menu-overlay|offcanvas|breadcrumbs?|pagination|nav-links|post-navigation|comments?-area|comment-respond|share-buttons|sharedaddy|jp-relatedposts|wp-block-navigation|search-form|searchform|announcement-bar|back-to-top|wixui-anchor-menu|elementor-hidden|w-form-done|w-form-fail|w-webflow-badge|contact-form-submission|contact-form-success)(?:$|[\s_-])/i;
9395
9418
  var hiddenClasses = /* @__PURE__ */ new Set();
9396
9419
  function hiddenClassesFromCss(css) {
9397
9420
  const out = /* @__PURE__ */ new Set();
@@ -9848,6 +9871,7 @@ function leafBlocks(el, ctx, out) {
9848
9871
  );
9849
9872
  out.push({
9850
9873
  kind: "newsletter",
9874
+ ...signupAsksName(el) ? { askName: true } : {},
9851
9875
  ...btn && (text(btn) || attr(btn, "value")) ? { buttonLabel: text(btn) || attr(btn, "value") } : {},
9852
9876
  ...input && attr(input, "placeholder") ? { placeholder: attr(input, "placeholder") } : {}
9853
9877
  });
@@ -9943,13 +9967,30 @@ function leafBlocks(el, ctx, out) {
9943
9967
  }
9944
9968
  if (imgEl) {
9945
9969
  const im = imageFromImg(imgEl, ctx.base);
9946
- const cap = text(find(el, (e) => e.tagName === "figcaption"));
9970
+ const capEl = find(el, (e) => e.tagName === "figcaption");
9971
+ const structured = capEl && !!find(capEl, (e) => HEADINGS.has(e.tagName) || e.tagName === "p");
9972
+ if (structured && im) {
9973
+ const declared2 = Number(attr(imgEl, "width") ?? 0);
9974
+ const a2 = find(el, (e) => e.tagName === "a" && !!find(e, (x) => x === imgEl));
9975
+ const href2 = a2 ? attr(a2, "href") : void 0;
9976
+ out.push({
9977
+ kind: "image",
9978
+ image: im,
9979
+ ...declared2 > 0 && declared2 <= 400 ? { natural: true } : {},
9980
+ ...href2 && !/\.(?:jpe?g|png|webp|gif|avif)(?:\?|$)/i.test(href2) && !href2.startsWith("#") ? { href: href2 } : {}
9981
+ });
9982
+ walk(capEl, ctx, out, 1);
9983
+ return;
9984
+ }
9985
+ const cap = text(capEl);
9947
9986
  const a = tag2 === "a" ? el : find(el, (e) => e.tagName === "a" && !!find(e, (x) => x === imgEl));
9948
9987
  const href = a ? attr(a, "href") : void 0;
9988
+ const declared = Number(attr(imgEl, "width") ?? 0);
9949
9989
  if (im)
9950
9990
  out.push({
9951
9991
  kind: "image",
9952
9992
  image: im,
9993
+ ...declared > 0 && declared <= 400 ? { natural: true } : {},
9953
9994
  ...cap ? { caption: cap } : {},
9954
9995
  ...href && !/\.(?:jpe?g|png|webp|gif|avif)(?:\?|$)/i.test(href) && !href.startsWith("#") ? { href } : {}
9955
9996
  });
@@ -10244,10 +10285,34 @@ function liftHeading(sec) {
10244
10285
  return;
10245
10286
  }
10246
10287
  }
10288
+ function thumbnailRuns(blocks) {
10289
+ const out = [];
10290
+ let run = [];
10291
+ const flush = () => {
10292
+ if (run.length >= 3)
10293
+ out.push({
10294
+ kind: "gallery",
10295
+ layout: "grid",
10296
+ images: run.map((b) => b.image)
10297
+ });
10298
+ else out.push(...run);
10299
+ run = [];
10300
+ };
10301
+ for (const b of blocks) {
10302
+ if (b.kind === "image" && !b.caption && (b.image.width ?? 999) <= 240) run.push(b);
10303
+ else {
10304
+ flush();
10305
+ out.push(b);
10306
+ }
10307
+ }
10308
+ flush();
10309
+ return out;
10310
+ }
10247
10311
  function toSection(el, ctx) {
10248
10312
  const bg = sectionBackground(el, ctx.base);
10249
10313
  const inner = withoutBackground(el, bg, ctx.base);
10250
10314
  const rows = rowsOf(inner, ctx).filter((r) => r.columns.some((c) => c.blocks.length));
10315
+ for (const r of rows) for (const c of r.columns) c.blocks = thumbnailRuns(c.blocks);
10251
10316
  if (!rows.length && !bg) return void 0;
10252
10317
  const style = attr(el, "style") ?? "";
10253
10318
  const tall = /min-height\s*:\s*(\d+)(vh|px)/i.exec(style);
@@ -10317,6 +10382,23 @@ function sectionsFrom(main, base, opts = {}) {
10317
10382
  }
10318
10383
  out.push(s);
10319
10384
  }
10385
+ return mergeTitleSections(out);
10386
+ }
10387
+ function mergeTitleSections(sections) {
10388
+ const out = [];
10389
+ for (let i = 0; i < sections.length; i++) {
10390
+ const s = sections[i];
10391
+ const next = sections[i + 1];
10392
+ const blocks = s.layout.mode === "classic" ? s.layout.rows.flatMap((r) => r.columns.flatMap((c) => c.blocks)) : [];
10393
+ const onlyTitle = blocks.length === 1 && !s.background && !s.role && (blocks[0]?.kind === "heading" && blocks[0].level <= 2 || blocks[0]?.kind === "text" && /^\s*<h[12][^>]*>[^<]*(?:<[^h/][^>]*>[^<]*<\/[^>]+>[^<]*)*<\/h[12]>\s*$/i.test(
10394
+ blocks[0].html
10395
+ ));
10396
+ if (onlyTitle && next && !next.background && !next.role && next.layout.mode === "classic" && next.layout.rows[0]?.columns.length === 1) {
10397
+ next.layout.rows[0].columns[0]?.blocks.unshift(blocks[0]);
10398
+ continue;
10399
+ }
10400
+ out.push(s);
10401
+ }
10320
10402
  return out;
10321
10403
  }
10322
10404
  var SOCIAL_HOSTS = /(?:^|\.)(?:instagram\.com|facebook\.com|fb\.com|twitter\.com|x\.com|threads\.net|bsky\.app|linkedin\.com|youtube\.com|youtu\.be|tiktok\.com|pinterest\.[a-z.]+|github\.com|spotify\.com|soundcloud\.com|bandcamp\.com|vimeo\.com|behance\.net|dribbble\.com|substack\.com|patreon\.com|yelp\.[a-z.]+|tripadvisor\.[a-z.]+|mastodon\.social|tumblr\.com|medium\.com|whatsapp\.com|wa\.me|t\.me|discord\.gg)$/i;
@@ -11160,6 +11242,16 @@ function platformInfo(p) {
11160
11242
  return PLATFORMS[p ?? "squarespace"];
11161
11243
  }
11162
11244
  var platformLabel = (p) => platformInfo(p).label;
11245
+ var NO_SUBSCRIBER_LIST = /* @__PURE__ */ new Set([
11246
+ "github",
11247
+ "jekyll",
11248
+ "hugo",
11249
+ "eleventy",
11250
+ "generic"
11251
+ ]);
11252
+ function subscribersAdvice(p) {
11253
+ return p && NO_SUBSCRIBER_LIST.has(p) ? "Sign-up forms came across, and new sign-ups are kept for you in OpenSpace. Your old site didn't keep a subscriber list itself: if its form sent sign-ups to an email service (like Mailchimp or Buttondown), download the list there and add it in Inbox \u2192 Subscribers \u2192 Import." : `Sign-up forms came across, but subscribers stay with ${platformLabel(p)}. Export them there and import them here.`;
11254
+ }
11163
11255
  var RULES = [
11164
11256
  {
11165
11257
  platform: "squarespace",
@@ -11316,7 +11408,7 @@ function parsePlatform(s) {
11316
11408
  function parseLayout(layout) {
11317
11409
  const rows = [];
11318
11410
  for (const row of children(layout).filter((e) => hasClass(e, "sqs-row")))
11319
- rows.push(parseRow(row));
11411
+ rows.push(...expandRow(row));
11320
11412
  const loose = children(layout).filter((e) => hasClass(e, "sqs-block"));
11321
11413
  if (loose.length) {
11322
11414
  const blocks = loose.map(parseBlock).filter((b) => !!b);
@@ -11324,6 +11416,37 @@ function parseLayout(layout) {
11324
11416
  }
11325
11417
  return expandImageCards(rows.filter((r) => r.columns.some((c) => c.blocks.length)));
11326
11418
  }
11419
+ function expandRow(row) {
11420
+ const cols = children(row).filter((e) => classes(e).some((c) => /^sqs-col-\d+$/.test(c)));
11421
+ if (cols.length !== 1) return [parseRow(row)];
11422
+ const span = Number(classValue(cols[0], "span-") ?? 12);
11423
+ if (span < 12) return [parseRow(row)];
11424
+ const out = [];
11425
+ let run = [];
11426
+ let split = false;
11427
+ const flush = () => {
11428
+ if (run.length) out.push({ columns: [{ span: 12, blocks: run }] });
11429
+ run = [];
11430
+ };
11431
+ const visit = (el) => {
11432
+ for (const c of children(el)) {
11433
+ if (hasClass(c, "sqs-block")) {
11434
+ const b = parseBlock(c);
11435
+ if (b) run.push(b);
11436
+ } else if (hasClass(c, "sqs-row")) {
11437
+ const nested = expandRow(c);
11438
+ if (nested.some((r) => r.columns.filter((x) => x.blocks.length).length > 1)) {
11439
+ split = true;
11440
+ flush();
11441
+ out.push(...nested);
11442
+ } else for (const r of nested) for (const x of r.columns) run.push(...x.blocks);
11443
+ } else visit(c);
11444
+ }
11445
+ };
11446
+ visit(cols[0]);
11447
+ flush();
11448
+ return split ? out : [parseRow(row)];
11449
+ }
11327
11450
  function columnBlocks(col) {
11328
11451
  const out = [];
11329
11452
  for (const c of children(col)) {
@@ -11402,12 +11525,19 @@ function cardBlocks(card) {
11402
11525
  return out;
11403
11526
  }
11404
11527
  function parseRow(row) {
11405
- const columns = children(row).filter((e) => classes(e).some((c) => /^sqs-col-\d+$/.test(c))).map((col) => {
11528
+ const columns = children(row).filter((e) => classes(e).some((c) => /^sqs-col-\d+$/.test(c))).flatMap((col) => {
11406
11529
  const span = Number(classValue(col, "span-") ?? classValue(col, "sqs-col-") ?? 12);
11407
- return {
11408
- span: Number.isFinite(span) && span > 0 ? Math.min(12, span) : 12,
11409
- blocks: columnBlocks(col)
11410
- };
11530
+ const inner = children(col).filter((c) => !/^(?:SCRIPT|STYLE)$/i.test(c.tagName));
11531
+ if (inner.length === 1 && hasClass(inner[0], "sqs-row")) {
11532
+ const nested = parseRow(inner[0]).columns.filter((c) => c.blocks.length);
11533
+ if (nested.length > 1) return nested;
11534
+ }
11535
+ return [
11536
+ {
11537
+ span: Number.isFinite(span) && span > 0 ? Math.min(12, span) : 12,
11538
+ blocks: columnBlocks(col)
11539
+ }
11540
+ ];
11411
11541
  });
11412
11542
  if (!columns.length) return { columns: [{ span: 12, blocks: columnBlocks(row) }] };
11413
11543
  return { columns };
@@ -11480,7 +11610,8 @@ function gallerySectionBlock(section) {
11480
11610
  }
11481
11611
  if (!images.length) return void 0;
11482
11612
  const layout = /slideshow|fullscreen/.test(cls) ? "slideshow" : /reel/.test(cls) ? "carousel" : /strips/.test(cls) ? "strips" : /masonry/.test(cls) ? "masonry" : "grid";
11483
- return { kind: "gallery", images, layout };
11613
+ const contain = layout === "slideshow" && !!find(section, (e) => classes(e).some((c) => c === "content-fit"));
11614
+ return { kind: "gallery", images, layout, ...contain ? { fit: "contain" } : {} };
11484
11615
  }
11485
11616
  function listSectionBlocks(section) {
11486
11617
  const out = [];
@@ -11588,6 +11719,7 @@ function parseSection(section) {
11588
11719
  const layouts = findAll(content, (e) => hasClass(e, "sqs-layout"), { deep: false });
11589
11720
  const rows = layouts.flatMap(parseLayout);
11590
11721
  out.layout = { mode: "classic", rows };
11722
+ if (rows.length > 1) out.together = true;
11591
11723
  return rows.length || out.background ? out : void 0;
11592
11724
  }
11593
11725
  function navFrom(root) {
@@ -11677,7 +11809,7 @@ function parsePage(html) {
11677
11809
  headerEl2,
11678
11810
  (e) => e.tagName === "img" && !!closest(
11679
11811
  e,
11680
- (p) => classes(p).some(
11812
+ (p) => attr(p, "id") === "logoImage" || attr(p, "id") === "logo" || classes(p).some(
11681
11813
  (c) => c === "header-title-logo" || c === "logo-image" || c === "site-logo" || c === "logo"
11682
11814
  )
11683
11815
  )
@@ -11886,7 +12018,9 @@ function bannerSection(body, skip) {
11886
12018
  level: 2,
11887
12019
  ...before.length === 1 && text(before[0]).length <= 60 ? { eyebrow: text(before[0]) } : {},
11888
12020
  ...after.length && after.map((p) => text(p)).join(" ").length <= 280 ? { subheading: after.map((p) => text(p)).join(" ") } : {},
11889
- align: "center"
12021
+ align: "center",
12022
+ // The banner's title is set larger than any heading (the display size).
12023
+ display: true
11890
12024
  });
11891
12025
  links.forEach((p, i) => {
11892
12026
  const a = p.tagName === "a" ? p : find(p, byTag("a"));
@@ -12288,7 +12422,7 @@ function itemFromHtml(path, page, kind) {
12288
12422
  const p = ldOf(page, "Product");
12289
12423
  const rawOffers = p?.offers;
12290
12424
  const offers = Array.isArray(rawOffers) ? rawOffers[0] : rawOffers;
12291
- const price = Number(offers?.price);
12425
+ const price = Number(offers?.price ?? offers?.lowPrice);
12292
12426
  item.product = {
12293
12427
  price: Number.isFinite(price) ? Math.round(price * 100) : 0,
12294
12428
  currency: typeof offers?.priceCurrency === "string" ? offers.priceCurrency : "USD",
@@ -12511,7 +12645,10 @@ ${r.text}`;
12511
12645
  const itemPaths = all.filter(
12512
12646
  (p) => (path === "/" ? (
12513
12647
  // A shop as the home page lists items under its own address too (`/shop/p/x`).
12514
- (kind === "products" ? /^\/(?:[^/]+\/)?p\/[^/]+$/ : /^\/(?:p\/[^/]+|\d{4}\/\d{1,2}\/\d{1,2}\/[^/]+)$/).test(p)
12648
+ (kind === "products" ? (
12649
+ // Variant products keep a slash in their slug (`/shop/p/linen-top-/-blue`).
12650
+ /^\/(?:[^/]+\/)?p\/[^/].*$/
12651
+ ) : /^\/(?:p\/[^/]+|\d{4}\/\d{1,2}\/\d{1,2}\/[^/]+)$/).test(p)
12515
12652
  ) : p.startsWith(`${path}/`)) && !handled.has(p) && !/\/(?:category|tag|tags|categories)\//.test(p.slice(path.length))
12516
12653
  );
12517
12654
  for (const ip of itemPaths) {
@@ -12965,6 +13102,7 @@ var escapeHtml2 = (s) => s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(
12965
13102
  export {
12966
13103
  platformInfo,
12967
13104
  platformLabel,
13105
+ subscribersAdvice,
12968
13106
  detectPlatform,
12969
13107
  parsePlatform,
12970
13108
  RobotsDisallowed,
@@ -12977,6 +13115,7 @@ export {
12977
13115
  findAll,
12978
13116
  find,
12979
13117
  text,
13118
+ signupAsksName,
12980
13119
  videoUrl,
12981
13120
  stripTags,
12982
13121
  hiddenClassesFromCss,
@@ -12993,4 +13132,4 @@ export {
12993
13132
  crawlSquarespace,
12994
13133
  crawlGeneric
12995
13134
  };
12996
- //# sourceMappingURL=chunk-EFSGZWAO.js.map
13135
+ //# sourceMappingURL=chunk-YAPLQ4OA.js.map