@sonordev/site-kit 1.5.3 → 1.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -36418,9 +36418,17 @@ async function syncPagesToPortal(apiUrl, apiKey, dryRun) {
36418
36418
  }
36419
36419
  const pages = discoverPages(appDir);
36420
36420
  spinner.succeed(`Found ${pages.length} pages`);
36421
+ const contentSpinner = ora("Extracting page content from build...").start();
36422
+ const enrichedCount = enrichPagesWithContent(pages);
36423
+ if (enrichedCount > 0) {
36424
+ contentSpinner.succeed(`Extracted content from ${enrichedCount}/${pages.length} pages`);
36425
+ } else {
36426
+ contentSpinner.warn("No build output found \u2014 run after `next build` for content extraction");
36427
+ }
36421
36428
  console.log(source_default.bold(" Pages to sync:"));
36422
36429
  for (const page of pages.slice(0, 10)) {
36423
- console.log(source_default.gray(` ${page.path} (priority: ${page.priority})`));
36430
+ const contentTag = page.content ? source_default.green(`${page.content.wordCount}w`) : source_default.gray("no content");
36431
+ console.log(source_default.gray(` ${page.path} (${contentTag})`));
36424
36432
  }
36425
36433
  if (pages.length > 10) {
36426
36434
  console.log(source_default.gray(` ... and ${pages.length - 10} more`));
@@ -36442,7 +36450,15 @@ async function syncPagesToPortal(apiUrl, apiKey, dryRun) {
36442
36450
  entries: pages.map((p) => ({
36443
36451
  path: p.path,
36444
36452
  priority: p.priority,
36445
- changefreq: p.changeFreq
36453
+ changefreq: p.changeFreq,
36454
+ // Build-time content extraction
36455
+ ...p.content ? {
36456
+ content_text: p.content.text,
36457
+ content_title: p.content.title,
36458
+ content_h1: p.content.h1,
36459
+ content_headings: p.content.headings,
36460
+ content_word_count: p.content.wordCount
36461
+ } : {}
36446
36462
  })),
36447
36463
  mode: "full-replace"
36448
36464
  })
@@ -36451,7 +36467,7 @@ async function syncPagesToPortal(apiUrl, apiKey, dryRun) {
36451
36467
  throw new Error(`HTTP ${response.status}: ${await response.text()}`);
36452
36468
  }
36453
36469
  const result = await response.json();
36454
- syncSpinner.succeed(`Synced pages: ${result.created || 0} created, ${result.updated || 0} updated`);
36470
+ syncSpinner.succeed(`Synced pages: ${result.created || 0} created, ${result.updated || 0} updated, ${result.content_updated || 0} with content`);
36455
36471
  } catch (error) {
36456
36472
  syncSpinner.fail(`Sync failed: ${error.message}`);
36457
36473
  }
@@ -36509,6 +36525,136 @@ function discoverPages(appDir, currentPath = "", pages = []) {
36509
36525
  }
36510
36526
  return pages;
36511
36527
  }
36528
+ function findNextBuildDir() {
36529
+ const cwd = process.cwd();
36530
+ const candidate = path4__default.default.join(cwd, ".next", "server", "app");
36531
+ return fs.existsSync(candidate) ? candidate : null;
36532
+ }
36533
+ function extractPageContent(buildDir, pagePath) {
36534
+ const baseName = pagePath === "/" ? "index" : pagePath.replace(/^\//, "");
36535
+ const htmlCandidates = [
36536
+ path4__default.default.join(buildDir, `${baseName}.html`),
36537
+ path4__default.default.join(buildDir, baseName, "index.html")
36538
+ ];
36539
+ let html = null;
36540
+ for (const candidate of htmlCandidates) {
36541
+ if (fs.existsSync(candidate)) {
36542
+ try {
36543
+ html = fs.readFileSync(candidate, "utf-8");
36544
+ break;
36545
+ } catch {
36546
+ continue;
36547
+ }
36548
+ }
36549
+ }
36550
+ const rscCandidates = [
36551
+ path4__default.default.join(buildDir, `${baseName}.rsc`),
36552
+ path4__default.default.join(buildDir, baseName, "index.rsc")
36553
+ ];
36554
+ let rsc = null;
36555
+ for (const candidate of rscCandidates) {
36556
+ if (fs.existsSync(candidate)) {
36557
+ try {
36558
+ rsc = fs.readFileSync(candidate, "utf-8");
36559
+ break;
36560
+ } catch {
36561
+ continue;
36562
+ }
36563
+ }
36564
+ }
36565
+ if (!html && !rsc) return null;
36566
+ let title;
36567
+ let metaDescription;
36568
+ if (html) {
36569
+ const titleMatch = html.match(/<title[^>]*>([^<]+)<\/title>/i);
36570
+ title = titleMatch?.[1]?.trim();
36571
+ const descMatch = html.match(/<meta\s+name="description"\s+content="([^"]+)"/i);
36572
+ metaDescription = descMatch?.[1]?.trim();
36573
+ }
36574
+ if (rsc) {
36575
+ return parseRscContent(rsc, title, metaDescription);
36576
+ }
36577
+ if (html) {
36578
+ return parseHtmlContent(html);
36579
+ }
36580
+ return null;
36581
+ }
36582
+ function parseRscContent(rsc, title, metaDescription) {
36583
+ const textParts = [];
36584
+ const headings = [];
36585
+ const childrenRegex = /,"children":"([^"]+)"/g;
36586
+ let match;
36587
+ while ((match = childrenRegex.exec(rsc)) !== null) {
36588
+ const text2 = match[1].trim();
36589
+ if (!text2) continue;
36590
+ if (/^[A-Z]?\[/.test(text2)) continue;
36591
+ if (/^\//.test(text2) && !text2.includes(" ")) continue;
36592
+ if (/^\$L[0-9a-f]+$/i.test(text2)) continue;
36593
+ if (/^\$/.test(text2) && text2.length < 10) continue;
36594
+ textParts.push(text2);
36595
+ }
36596
+ const h1Regex = /\["\$","h1",[^,]*,\{[^}]*"children":"([^"]+)"/g;
36597
+ let h1;
36598
+ while ((match = h1Regex.exec(rsc)) !== null) {
36599
+ const text2 = match[1].trim();
36600
+ if (text2) {
36601
+ if (!h1) h1 = text2;
36602
+ headings.push(text2);
36603
+ }
36604
+ }
36605
+ const hRegex = /\["\$","h[2-6]",[^,]*,\{[^}]*"children":"([^"]+)"/g;
36606
+ while ((match = hRegex.exec(rsc)) !== null) {
36607
+ const text2 = match[1].trim();
36608
+ if (text2) headings.push(text2);
36609
+ }
36610
+ let text = textParts.join(" ").replace(/\s+/g, " ").trim();
36611
+ if (metaDescription && !text.includes(metaDescription)) {
36612
+ text = metaDescription + " \u2014 " + text;
36613
+ }
36614
+ if (text.length > 1e4) {
36615
+ text = text.substring(0, 1e4) + "...";
36616
+ }
36617
+ const wordCount = text.split(/\s+/).filter(Boolean).length;
36618
+ return { text, title, h1, headings, wordCount };
36619
+ }
36620
+ function parseHtmlContent(html) {
36621
+ const titleMatch = html.match(/<title[^>]*>([^<]+)<\/title>/i);
36622
+ const title = titleMatch?.[1]?.trim();
36623
+ let cleaned = html.replace(/<script[\s\S]*?<\/script>/gi, "").replace(/<style[\s\S]*?<\/style>/gi, "").replace(/<svg[\s\S]*?<\/svg>/gi, "").replace(/<nav[\s\S]*?<\/nav>/gi, "").replace(/<footer[\s\S]*?<\/footer>/gi, "").replace(/<header[\s\S]*?<\/header>/gi, "").replace(/<[^>]+(?:hidden|display:\s*none|aria-hidden="true")[^>]*>[\s\S]*?<\/[^>]+>/gi, "");
36624
+ const h1Match = cleaned.match(/<h1[^>]*>([\s\S]*?)<\/h1>/i);
36625
+ const h1 = h1Match ? stripTags(h1Match[1]).trim() : void 0;
36626
+ const headingRegex = /<h[1-6][^>]*>([\s\S]*?)<\/h[1-6]>/gi;
36627
+ const headings = [];
36628
+ let match;
36629
+ while ((match = headingRegex.exec(cleaned)) !== null) {
36630
+ const text2 = stripTags(match[1]).trim();
36631
+ if (text2) headings.push(text2);
36632
+ }
36633
+ const mainMatch = cleaned.match(/<main[\s\S]*?>([\s\S]*?)<\/main>/i) || cleaned.match(/<article[\s\S]*?>([\s\S]*?)<\/article>/i);
36634
+ const contentHtml = mainMatch ? mainMatch[1] : cleaned;
36635
+ let text = stripTags(contentHtml).replace(/\s+/g, " ").trim();
36636
+ if (text.length > 1e4) {
36637
+ text = text.substring(0, 1e4) + "...";
36638
+ }
36639
+ const wordCount = text.split(/\s+/).filter(Boolean).length;
36640
+ return { text, title, h1, headings, wordCount };
36641
+ }
36642
+ function stripTags(html) {
36643
+ return html.replace(/<[^>]+>/g, " ").replace(/&nbsp;/g, " ").replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&#\d+;/g, "");
36644
+ }
36645
+ function enrichPagesWithContent(pages) {
36646
+ const buildDir = findNextBuildDir();
36647
+ if (!buildDir) return 0;
36648
+ let enriched = 0;
36649
+ for (const page of pages) {
36650
+ const content = extractPageContent(buildDir, page.path);
36651
+ if (content && content.wordCount > 10) {
36652
+ page.content = content;
36653
+ enriched++;
36654
+ }
36655
+ }
36656
+ return enriched;
36657
+ }
36512
36658
  var BLOG_DIRS = ["app/blog", "content/blog", "posts", "src/content/blog"];
36513
36659
  var BLOG_EXTENSIONS = [".mdx", ".md"];
36514
36660
  function findBlogDir() {