aeorank 2.2.0 → 2.3.1

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/index.cjs CHANGED
@@ -324,6 +324,7 @@ __export(index_exports, {
324
324
  analyzeAllPages: () => analyzeAllPages,
325
325
  analyzePage: () => analyzePage,
326
326
  audit: () => audit,
327
+ auditSite: () => auditSite,
327
328
  auditSiteFromData: () => auditSiteFromData,
328
329
  buildDetailedFindings: () => buildDetailedFindings,
329
330
  buildLinkGraph: () => buildLinkGraph,
@@ -332,6 +333,7 @@ __export(index_exports, {
332
333
  calculateOverallScore: () => calculateOverallScore,
333
334
  classifyRendering: () => classifyRendering,
334
335
  compare: () => compare,
336
+ countRecentSitemapDates: () => countRecentSitemapDates,
335
337
  crawlFullSite: () => crawlFullSite,
336
338
  detectClusters: () => detectClusters,
337
339
  detectHubs: () => detectHubs,
@@ -566,18 +568,21 @@ async function prefetchSiteData(domain) {
566
568
  if (homepage) homepage.category = "homepage";
567
569
  return { domain, protocol, homepage, llmsTxt, robotsTxt, faqPage, sitemapXml, rssFeed, aiTxt, redirectedTo: null, parkedReason: null, blogSample };
568
570
  }
571
+ function stripScripts(html) {
572
+ return html.replace(/<script(?![^>]*type\s*=\s*["']application\/ld\+json["'])[^>]*>[\s\S]*?<\/script>/gi, "").replace(/<style[\s\S]*?<\/style>/gi, "");
573
+ }
569
574
  function getCombinedHtml(data) {
570
- const parts = [data.homepage?.text || ""];
575
+ const parts = [stripScripts(data.homepage?.text || "")];
571
576
  if (data.blogSample) {
572
577
  for (const page of data.blogSample) {
573
- parts.push(page.text);
578
+ parts.push(stripScripts(page.text));
574
579
  }
575
580
  }
576
581
  return parts.join("\n");
577
582
  }
578
583
  function getBlogHtml(data) {
579
584
  if (!data.blogSample || data.blogSample.length === 0) return "";
580
- return data.blogSample.map((p) => p.text).join("\n");
585
+ return data.blogSample.map((p) => stripScripts(p.text)).join("\n");
581
586
  }
582
587
  function checkLlmsTxt(data) {
583
588
  const findings = [];
@@ -1775,14 +1780,17 @@ function checkQueryAnswerAlignment(data) {
1775
1780
  }
1776
1781
  let answered = 0;
1777
1782
  for (const qHeading of questionHeadings) {
1778
- const escapedHeading = qHeading.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1779
- const pattern = new RegExp(escapedHeading + "[\\s\\S]{0,200}?<\\/h[23]>([\\s\\S]{0,1500}?)(?=<h[1-6]|$)", "i");
1780
- const match = pattern.exec(combinedHtml);
1781
- if (match) {
1782
- const afterContent = match[1].replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim();
1783
- if (afterContent.length >= 20) {
1784
- answered++;
1783
+ try {
1784
+ const escapedHeading = qHeading.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1785
+ const pattern = new RegExp(escapedHeading + "[\\s\\S]{0,200}?<\\/h[23]>([\\s\\S]{0,1500}?)(?=<h[1-6]|$)", "i");
1786
+ const match = pattern.exec(combinedHtml);
1787
+ if (match) {
1788
+ const afterContent = match[1].replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim();
1789
+ if (afterContent.length >= 20) {
1790
+ answered++;
1791
+ }
1785
1792
  }
1793
+ } catch {
1786
1794
  }
1787
1795
  }
1788
1796
  const rate = Math.round(answered / questionHeadings.length * 100);
@@ -2261,27 +2269,32 @@ function checkTopicCoherence(data) {
2261
2269
  const bigramFocusRatio = blogPages.length > 0 ? dominantBigramCount / blogPages.length : 0;
2262
2270
  let score = 0;
2263
2271
  const bestFocusRatio = Math.max(focusRatio, bigramFocusRatio);
2272
+ const dominantPageCount = Math.max(dominantTermCount, dominantBigramCount);
2273
+ const hasStrongAbsolutePresence = dominantPageCount >= 10;
2264
2274
  if (bestFocusRatio >= 0.8) {
2265
2275
  score += 7;
2266
2276
  } else if (bestFocusRatio >= 0.6) {
2267
2277
  score += 6;
2268
- } else if (bestFocusRatio >= 0.45) {
2278
+ } else if (bestFocusRatio >= 0.45 || hasStrongAbsolutePresence && bestFocusRatio >= 0.3) {
2269
2279
  score += 5;
2270
- } else if (bestFocusRatio >= 0.3) {
2271
- score += 3;
2280
+ } else if (bestFocusRatio >= 0.3 || hasStrongAbsolutePresence && bestFocusRatio >= 0.2) {
2281
+ score += 4;
2272
2282
  } else if (bestFocusRatio >= 0.15) {
2273
2283
  score += 2;
2274
2284
  } else {
2275
2285
  score += 1;
2276
2286
  }
2277
- const clusterPenaltyReduced = focusRatio >= 0.7;
2278
- if (topicClusterCount <= 3) {
2287
+ const clusterPenaltyReduced = focusRatio >= 0.7 || hasStrongAbsolutePresence;
2288
+ const scaledLow = Math.max(3, Math.floor(blogPages.length / 10));
2289
+ const scaledMid = Math.max(6, Math.floor(blogPages.length / 5));
2290
+ const scaledHigh = Math.max(10, Math.floor(blogPages.length / 3));
2291
+ if (topicClusterCount <= scaledLow) {
2279
2292
  score += 3;
2280
2293
  findings.push({ severity: "info", detail: `${topicClusterCount} topic cluster(s) - tightly focused content` });
2281
- } else if (topicClusterCount <= 6) {
2294
+ } else if (topicClusterCount <= scaledMid) {
2282
2295
  score += clusterPenaltyReduced ? 2 : 1;
2283
2296
  findings.push({ severity: "info", detail: `${topicClusterCount} topic clusters${clusterPenaltyReduced ? " within a focused niche" : " - moderately focused"}` });
2284
- } else if (topicClusterCount <= 10) {
2297
+ } else if (topicClusterCount <= scaledHigh) {
2285
2298
  score += clusterPenaltyReduced ? 1 : 0;
2286
2299
  if (!clusterPenaltyReduced) {
2287
2300
  findings.push({ severity: "low", detail: `${topicClusterCount} topic clusters - scattered content`, fix: "Reduce the number of distinct topics. Focus blog content on 2-3 core expertise areas." });
@@ -2423,6 +2436,12 @@ function auditSiteFromData(data) {
2423
2436
  checkContentDepth(data, topicCoherence.score)
2424
2437
  ];
2425
2438
  }
2439
+ async function auditSite(targetUrl) {
2440
+ const url = new URL(targetUrl.startsWith("http") ? targetUrl : `https://${targetUrl}`);
2441
+ const domain = url.hostname.replace(/^www\./, "");
2442
+ const data = await prefetchSiteData(domain);
2443
+ return auditSiteFromData(data);
2444
+ }
2426
2445
 
2427
2446
  // src/scoring.ts
2428
2447
  var WEIGHTS = {
@@ -5573,6 +5592,7 @@ async function compare(domainA, domainB, options) {
5573
5592
  analyzeAllPages,
5574
5593
  analyzePage,
5575
5594
  audit,
5595
+ auditSite,
5576
5596
  auditSiteFromData,
5577
5597
  buildDetailedFindings,
5578
5598
  buildLinkGraph,
@@ -5581,6 +5601,7 @@ async function compare(domainA, domainB, options) {
5581
5601
  calculateOverallScore,
5582
5602
  classifyRendering,
5583
5603
  compare,
5604
+ countRecentSitemapDates,
5584
5605
  crawlFullSite,
5585
5606
  detectClusters,
5586
5607
  detectHubs,