@houtini/seo-audit-console 0.9.0 → 0.10.0
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/README.md +16 -14
- package/dist/audit/checks.d.ts +0 -7
- package/dist/audit/checks.d.ts.map +1 -1
- package/dist/audit/checks.js +22 -282
- package/dist/audit/checks.js.map +1 -1
- package/dist/audit/drift.d.ts +0 -12
- package/dist/audit/drift.d.ts.map +1 -1
- package/dist/audit/drift.js +0 -15
- package/dist/audit/drift.js.map +1 -1
- package/dist/audit/engine.d.ts +0 -3
- package/dist/audit/engine.d.ts.map +1 -1
- package/dist/audit/engine.js +7 -42
- package/dist/audit/engine.js.map +1 -1
- package/dist/audit/keywordList.d.ts +0 -14
- package/dist/audit/keywordList.d.ts.map +1 -1
- package/dist/audit/keywordList.js +0 -5
- package/dist/audit/keywordList.js.map +1 -1
- package/dist/audit/opportunities.js +3 -26
- package/dist/audit/opportunities.js.map +1 -1
- package/dist/audit/recon.d.ts +0 -31
- package/dist/audit/recon.d.ts.map +1 -1
- package/dist/audit/recon.js +0 -27
- package/dist/audit/recon.js.map +1 -1
- package/dist/audit/report.d.ts +0 -4
- package/dist/audit/report.d.ts.map +1 -1
- package/dist/audit/report.js +0 -7
- package/dist/audit/report.js.map +1 -1
- package/dist/audit/schema-validate.d.ts +0 -26
- package/dist/audit/schema-validate.d.ts.map +1 -1
- package/dist/audit/schema-validate.js +8 -64
- package/dist/audit/schema-validate.js.map +1 -1
- package/dist/audit/templates.d.ts +0 -24
- package/dist/audit/templates.d.ts.map +1 -1
- package/dist/audit/templates.js +1 -21
- package/dist/audit/templates.js.map +1 -1
- package/dist/audit/topicGaps.d.ts +0 -1
- package/dist/audit/topicGaps.d.ts.map +1 -1
- package/dist/audit/topicGaps.js +3 -24
- package/dist/audit/topicGaps.js.map +1 -1
- package/dist/core/AuditDatabase.d.ts +0 -14
- package/dist/core/AuditDatabase.d.ts.map +1 -1
- package/dist/core/AuditDatabase.js +8 -61
- package/dist/core/AuditDatabase.js.map +1 -1
- package/dist/core/Backlinks.d.ts +0 -7
- package/dist/core/Backlinks.d.ts.map +1 -1
- package/dist/core/Backlinks.js +1 -23
- package/dist/core/Backlinks.js.map +1 -1
- package/dist/core/Crawler.d.ts +0 -1
- package/dist/core/Crawler.d.ts.map +1 -1
- package/dist/core/Crawler.js +24 -119
- package/dist/core/Crawler.js.map +1 -1
- package/dist/core/DataForSeoClient.d.ts +25 -74
- package/dist/core/DataForSeoClient.d.ts.map +1 -1
- package/dist/core/DataForSeoClient.js +65 -90
- package/dist/core/DataForSeoClient.js.map +1 -1
- package/dist/core/Entities.d.ts +0 -6
- package/dist/core/Entities.d.ts.map +1 -1
- package/dist/core/Entities.js +0 -8
- package/dist/core/Entities.js.map +1 -1
- package/dist/core/FirecrawlClient.d.ts +0 -18
- package/dist/core/FirecrawlClient.d.ts.map +1 -1
- package/dist/core/FirecrawlClient.js +1 -13
- package/dist/core/FirecrawlClient.js.map +1 -1
- package/dist/core/GscClient.d.ts +0 -7
- package/dist/core/GscClient.d.ts.map +1 -1
- package/dist/core/GscClient.js +1 -10
- package/dist/core/GscClient.js.map +1 -1
- package/dist/core/GscSync.d.ts +0 -4
- package/dist/core/GscSync.d.ts.map +1 -1
- package/dist/core/GscSync.js +2 -33
- package/dist/core/GscSync.js.map +1 -1
- package/dist/core/JobManager.d.ts +0 -5
- package/dist/core/JobManager.d.ts.map +1 -1
- package/dist/core/JobManager.js +0 -8
- package/dist/core/JobManager.js.map +1 -1
- package/dist/core/LinkIntersect.d.ts +0 -1
- package/dist/core/LinkIntersect.d.ts.map +1 -1
- package/dist/core/LinkIntersect.js +1 -37
- package/dist/core/LinkIntersect.js.map +1 -1
- package/dist/core/MajesticClient.d.ts +0 -26
- package/dist/core/MajesticClient.d.ts.map +1 -1
- package/dist/core/MajesticClient.js +0 -15
- package/dist/core/MajesticClient.js.map +1 -1
- package/dist/core/RankTracker.d.ts +0 -4
- package/dist/core/RankTracker.d.ts.map +1 -1
- package/dist/core/RankTracker.js +0 -9
- package/dist/core/RankTracker.js.map +1 -1
- package/dist/core/Refresh.d.ts +0 -6
- package/dist/core/Refresh.d.ts.map +1 -1
- package/dist/core/Refresh.js +0 -6
- package/dist/core/Refresh.js.map +1 -1
- package/dist/core/SupadataClient.d.ts +0 -11
- package/dist/core/SupadataClient.d.ts.map +1 -1
- package/dist/core/SupadataClient.js +0 -5
- package/dist/core/SupadataClient.js.map +1 -1
- package/dist/core/UrlInspector.d.ts +0 -5
- package/dist/core/UrlInspector.d.ts.map +1 -1
- package/dist/core/UrlInspector.js +0 -6
- package/dist/core/UrlInspector.js.map +1 -1
- package/dist/core/WikidataClient.d.ts +0 -2
- package/dist/core/WikidataClient.d.ts.map +1 -1
- package/dist/core/WikidataClient.js +0 -7
- package/dist/core/WikidataClient.js.map +1 -1
- package/dist/core/agentReadiness.d.ts +0 -9
- package/dist/core/agentReadiness.d.ts.map +1 -1
- package/dist/core/agentReadiness.js +0 -13
- package/dist/core/agentReadiness.js.map +1 -1
- package/dist/core/ctrModel.js +0 -3
- package/dist/core/ctrModel.js.map +1 -1
- package/dist/core/dashboardData.d.ts +0 -1
- package/dist/core/dashboardData.d.ts.map +1 -1
- package/dist/core/dashboardData.js +13 -95
- package/dist/core/dashboardData.js.map +1 -1
- package/dist/core/dataStorage.d.ts +0 -2
- package/dist/core/dataStorage.d.ts.map +1 -1
- package/dist/core/dataStorage.js +6 -19
- package/dist/core/dataStorage.js.map +1 -1
- package/dist/core/draftBrief.d.ts +0 -7
- package/dist/core/draftBrief.d.ts.map +1 -1
- package/dist/core/draftBrief.js +0 -10
- package/dist/core/draftBrief.js.map +1 -1
- package/dist/core/extract.d.ts +0 -11
- package/dist/core/extract.d.ts.map +1 -1
- package/dist/core/extract.js +1 -38
- package/dist/core/extract.js.map +1 -1
- package/dist/core/googleNews.d.ts +0 -11
- package/dist/core/googleNews.d.ts.map +1 -1
- package/dist/core/googleNews.js +0 -7
- package/dist/core/googleNews.js.map +1 -1
- package/dist/core/gscFreshness.d.ts +0 -10
- package/dist/core/gscFreshness.d.ts.map +1 -1
- package/dist/core/gscFreshness.js +0 -11
- package/dist/core/gscFreshness.js.map +1 -1
- package/dist/core/linkGraph.d.ts +0 -15
- package/dist/core/linkGraph.d.ts.map +1 -1
- package/dist/core/linkGraph.js +1 -23
- package/dist/core/linkGraph.js.map +1 -1
- package/dist/core/marketSizing.d.ts +0 -13
- package/dist/core/marketSizing.d.ts.map +1 -1
- package/dist/core/marketSizing.js +1 -1
- package/dist/core/marketSizing.js.map +1 -1
- package/dist/core/passageScore.d.ts +0 -13
- package/dist/core/passageScore.d.ts.map +1 -1
- package/dist/core/passageScore.js +1 -16
- package/dist/core/passageScore.js.map +1 -1
- package/dist/core/paths.d.ts +0 -3
- package/dist/core/paths.d.ts.map +1 -1
- package/dist/core/paths.js +0 -0
- package/dist/core/paths.js.map +1 -1
- package/dist/core/queryData.d.ts +0 -1
- package/dist/core/queryData.d.ts.map +1 -1
- package/dist/core/queryData.js +0 -18
- package/dist/core/queryData.js.map +1 -1
- package/dist/core/reconFetch.d.ts +0 -6
- package/dist/core/reconFetch.d.ts.map +1 -1
- package/dist/core/reconFetch.js +1 -4
- package/dist/core/reconFetch.js.map +1 -1
- package/dist/core/reconResearch.d.ts +0 -20
- package/dist/core/reconResearch.d.ts.map +1 -1
- package/dist/core/reconResearch.js +1 -16
- package/dist/core/reconResearch.js.map +1 -1
- package/dist/core/reranker.d.ts +0 -2
- package/dist/core/reranker.d.ts.map +1 -1
- package/dist/core/reranker.js +1 -11
- package/dist/core/reranker.js.map +1 -1
- package/dist/core/robots.d.ts +0 -6
- package/dist/core/robots.d.ts.map +1 -1
- package/dist/core/robots.js +1 -7
- package/dist/core/robots.js.map +1 -1
- package/dist/core/serpFootprint.d.ts +0 -12
- package/dist/core/serpFootprint.d.ts.map +1 -1
- package/dist/core/serpFootprint.js +0 -1
- package/dist/core/serpFootprint.js.map +1 -1
- package/dist/core/serpRecon.d.ts +0 -14
- package/dist/core/serpRecon.d.ts.map +1 -1
- package/dist/core/serpRecon.js +1 -13
- package/dist/core/serpRecon.js.map +1 -1
- package/dist/core/sitemap.js +3 -16
- package/dist/core/sitemap.js.map +1 -1
- package/dist/core/sql.d.ts +0 -4
- package/dist/core/sql.d.ts.map +1 -1
- package/dist/core/sql.js +0 -4
- package/dist/core/sql.js.map +1 -1
- package/dist/core/url-key.d.ts +0 -31
- package/dist/core/url-key.d.ts.map +1 -1
- package/dist/core/url-key.js +1 -38
- package/dist/core/url-key.js.map +1 -1
- package/dist/core/webHandlers.d.ts +0 -6
- package/dist/core/webHandlers.d.ts.map +1 -1
- package/dist/core/webHandlers.js +2 -5
- package/dist/core/webHandlers.js.map +1 -1
- package/dist/core/webServer.d.ts +0 -16
- package/dist/core/webServer.d.ts.map +1 -1
- package/dist/core/webServer.js +3 -17
- package/dist/core/webServer.js.map +1 -1
- package/dist/dashboard.js +0 -23
- package/dist/dashboard.js.map +1 -1
- package/dist/generators/index.d.ts +0 -7
- package/dist/generators/index.d.ts.map +1 -1
- package/dist/generators/index.js +1 -26
- package/dist/generators/index.js.map +1 -1
- package/dist/index.js +0 -2
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +190 -312
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/server.json +85 -85
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reranker.js","sourceRoot":"","sources":["../../src/core/reranker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,kCAAkC,EAAE,MAAM,2BAA2B,CAAC;AACnG,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"reranker.js","sourceRoot":"","sources":["../../src/core/reranker.ts"],"names":[],"mappings":"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"}
|
package/dist/core/robots.d.ts
CHANGED
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* robots.txt politeness gate. Honours both Disallow AND Allow with longest-prefix-match
|
|
3
|
-
* (most specific path wins; Allow wins ties) — so a broad `Disallow: /` paired with
|
|
4
|
-
* `Allow: /public/` doesn't wrongly empty the crawl. NB: prefix match only — `*`/`$`
|
|
5
|
-
* wildcard patterns (e.g. `Disallow: /*?`) are not yet interpreted (owned-site crawl).
|
|
6
|
-
*/
|
|
7
1
|
export interface RobotsRules {
|
|
8
2
|
isAllowed(pathname: string): boolean;
|
|
9
3
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"robots.d.ts","sourceRoot":"","sources":["../../src/core/robots.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"robots.d.ts","sourceRoot":"","sources":["../../src/core/robots.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;CACtC;AA0DD,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,SAAsB,GAAG,OAAO,CAAC,WAAW,CAAC,CAWxH"}
|
package/dist/core/robots.js
CHANGED
|
@@ -21,7 +21,6 @@ function parseRules(txt, uaToken) {
|
|
|
21
21
|
lastWasAgent = true;
|
|
22
22
|
}
|
|
23
23
|
else if ((field === 'disallow' || field === 'allow') && current) {
|
|
24
|
-
// An empty Disallow value means "allow everything" — carries no restriction.
|
|
25
24
|
if (value)
|
|
26
25
|
current.rules.push({ path: value, allow: field === 'allow' });
|
|
27
26
|
lastWasAgent = false;
|
|
@@ -30,10 +29,6 @@ function parseRules(txt, uaToken) {
|
|
|
30
29
|
lastWasAgent = false;
|
|
31
30
|
}
|
|
32
31
|
}
|
|
33
|
-
// RFC 9309 §2.2.1: only the MOST SPECIFIC matching group applies — a bot-specific group
|
|
34
|
-
// replaces the `*` group entirely (it does not merge with it). Otherwise a site that
|
|
35
|
-
// whitelists this bot (`User-agent: seo-audit-console / Allow: /`) alongside a broad
|
|
36
|
-
// `User-agent: * / Disallow: /` would still be blocked. Groups at equal specificity merge.
|
|
37
32
|
const ua = uaToken.toLowerCase();
|
|
38
33
|
const agentScore = (a) => (a === '*' ? 0 : ua.includes(a) ? a.length : -1);
|
|
39
34
|
const groupScore = (g) => Math.max(-1, ...g.agents.map(agentScore));
|
|
@@ -51,7 +46,6 @@ function makeRules(rules) {
|
|
|
51
46
|
for (const r of rules) {
|
|
52
47
|
if (!p.startsWith(r.path))
|
|
53
48
|
continue;
|
|
54
|
-
// longest match wins; Allow beats Disallow at equal length
|
|
55
49
|
if (!best || r.path.length > best.path.length || (r.path.length === best.path.length && r.allow))
|
|
56
50
|
best = r;
|
|
57
51
|
}
|
|
@@ -70,7 +64,7 @@ export async function fetchRobots(origin, userAgent, uaToken = 'seo-audit-consol
|
|
|
70
64
|
return makeRules(parseRules(await res.text(), uaToken));
|
|
71
65
|
}
|
|
72
66
|
catch {
|
|
73
|
-
return ALLOW_ALL;
|
|
67
|
+
return ALLOW_ALL;
|
|
74
68
|
}
|
|
75
69
|
}
|
|
76
70
|
//# sourceMappingURL=robots.js.map
|
package/dist/core/robots.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"robots.js","sourceRoot":"","sources":["../../src/core/robots.ts"],"names":[],"mappings":"AAWA,MAAM,SAAS,GAAgB,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC;AAEzD,SAAS,UAAU,CAAC,GAAW,EAAE,OAAe;IAC9C,MAAM,MAAM,GAA0C,EAAE,CAAC;IACzD,IAAI,OAAO,GAA+C,IAAI,CAAC;IAC/D,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,CAAC,IAAI;YAAE,SAAS;QACpB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC9B,IAAI,GAAG,KAAK,CAAC,CAAC;YAAE,SAAS;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACtD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAEzC,IAAI,KAAK,KAAK,YAAY,EAAE,CAAC;YAC3B,IAAI,CAAC,OAAO,IAAI,CAAC,YAAY,EAAE,CAAC;gBAAC,OAAO,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;gBAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAAC,CAAC;YAC7F,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;YACzC,YAAY,GAAG,IAAI,CAAC;QACtB,CAAC;aAAM,IAAI,CAAC,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,OAAO,CAAC,IAAI,OAAO,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"robots.js","sourceRoot":"","sources":["../../src/core/robots.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,16 +1,4 @@
|
|
|
1
1
|
import type Database from 'better-sqlite3';
|
|
2
|
-
/**
|
|
3
|
-
* SERP-feature footprint - "how much of my market is being eaten by SERP features?"
|
|
4
|
-
*
|
|
5
|
-
* Built from ONE cached DataForSEO Labs ranked_keywords pull (top-down, never SERP loops):
|
|
6
|
-
* each row carries keyword_data.serp_info.serp_item_types (the features PRESENT on that
|
|
7
|
-
* keyword's SERP) plus our rank. Aggregated volume-weighted, split by whether we rank
|
|
8
|
-
* page 1 on that keyword.
|
|
9
|
-
*
|
|
10
|
-
* Honesty: feature PRESENCE is deterministic (D - it's in the Labs index). Whether the
|
|
11
|
-
* feature helps or hurts US is a judgement proxy (N) - "we rank page 1" is the nearest
|
|
12
|
-
* cheap signal to ownership; true feature ownership needs per-keyword SERP calls.
|
|
13
|
-
*/
|
|
14
2
|
export interface FootprintRow {
|
|
15
3
|
feature: string;
|
|
16
4
|
label: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serpFootprint.d.ts","sourceRoot":"","sources":["../../src/core/serpFootprint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"serpFootprint.d.ts","sourceRoot":"","sources":["../../src/core/serpFootprint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAe3C,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAgCD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CAC/B;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,aAAa,CA4BpH;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAYhE;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,EAAE,EAAE,aAAa,GAAG,IAAI,CAInF;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,aAAa,GAAG,IAAI,CAe/E"}
|
|
@@ -24,7 +24,6 @@ const FEATURE_LABELS = {
|
|
|
24
24
|
product_considerations: 'Product considerations',
|
|
25
25
|
ai_mode: 'AI Mode',
|
|
26
26
|
};
|
|
27
|
-
// Ubiquitous furniture that says nothing about the market - excluded from the chart.
|
|
28
27
|
const NOISE = new Set(['organic', 'related_searches', 'people_also_search', 'paid', 'images']);
|
|
29
28
|
export function computeSerpFootprint(target, location, sample) {
|
|
30
29
|
const totVolume = sample.reduce((s, k) => s + (k.searchVolume ?? 0), 0);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serpFootprint.js","sourceRoot":"","sources":["../../src/core/serpFootprint.ts"],"names":[],"mappings":"AAmCA,MAAM,cAAc,GAA2B;IAC7C,WAAW,EAAE,aAAa;IAC1B,gBAAgB,EAAE,kBAAkB;IACpC,eAAe,EAAE,iBAAiB;IAClC,UAAU,EAAE,YAAY;IACxB,QAAQ,EAAE,UAAU;IACpB,gBAAgB,EAAE,kBAAkB;IACpC,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,QAAQ;IAChB,eAAe,EAAE,iBAAiB;IAClC,WAAW,EAAE,aAAa;IAC1B,gBAAgB,EAAE,kBAAkB;IACpC,kBAAkB,EAAE,wBAAwB;IAC5C,OAAO,EAAE,iBAAiB;IAC1B,IAAI,EAAE,UAAU;IAChB,QAAQ,EAAE,UAAU;IACpB,GAAG,EAAE,KAAK;IACV,OAAO,EAAE,aAAa;IACtB,sBAAsB,EAAE,sBAAsB;IAC9C,YAAY,EAAE,cAAc;IAC5B,eAAe,EAAE,qBAAqB;IACtC,YAAY,EAAE,kBAAkB;IAChC,YAAY,EAAE,cAAc;IAC5B,sBAAsB,EAAE,wBAAwB;IAChD,OAAO,EAAE,SAAS;CACnB,CAAC;
|
|
1
|
+
{"version":3,"file":"serpFootprint.js","sourceRoot":"","sources":["../../src/core/serpFootprint.ts"],"names":[],"mappings":"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"}
|
package/dist/core/serpRecon.d.ts
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
1
|
import type { DfsResponse } from './DataForSeoClient.js';
|
|
2
|
-
/**
|
|
3
|
-
* Parse a DataForSEO SERP-advanced response into the fields content recon needs:
|
|
4
|
-
* where WE actually rank in organic, whether the AI Overview cites us and who it does
|
|
5
|
-
* cite, and how much of the SERP is video/product (format signals). This is the single
|
|
6
|
-
* fetch that powers the organic-rank x AIO-citation verdict matrix.
|
|
7
|
-
*/
|
|
8
2
|
export interface SerpReconResult {
|
|
9
3
|
itemTypes: string[];
|
|
10
4
|
ourOrganicRank: number | null;
|
|
@@ -33,17 +27,9 @@ export interface SerpReconResult {
|
|
|
33
27
|
source: string;
|
|
34
28
|
}[];
|
|
35
29
|
}
|
|
36
|
-
/** Registrable-ish host: lowercase, strip scheme/path/www. Good enough to match a domain field. */
|
|
37
30
|
export declare function hostOf(s: string | undefined | null): string;
|
|
38
31
|
export declare function parseSerpForRecon(resp: DfsResponse, ownDomain: string, serpDepth?: number): SerpReconResult;
|
|
39
|
-
/**
|
|
40
|
-
* The deterministic verdict from organic rank x AIO citation (Richard's rule):
|
|
41
|
-
* strong organic but NOT in the AIO = a data-accuracy/freshness problem — Google ranks
|
|
42
|
-
* us but won't quote us.
|
|
43
|
-
*/
|
|
44
32
|
export type ReconVerdict = 'defend-and-deepen' | 'accuracy-or-freshness' | 'consolidate-weak-page' | 'competitive-gap' | 'page-cannot-rank';
|
|
45
|
-
/** How to say "we didn't find you" without implying a position we never measured. Rank 11 and
|
|
46
|
-
* rank 80 both come back as null, so the honest phrasing has to carry the depth we fetched. */
|
|
47
33
|
export declare const rankPhrase: (r: SerpReconResult) => string;
|
|
48
34
|
export declare function reconVerdict(r: SerpReconResult): {
|
|
49
35
|
verdict: ReconVerdict;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serpRecon.d.ts","sourceRoot":"","sources":["../../src/core/serpRecon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"serpRecon.d.ts","sourceRoot":"","sources":["../../src/core/serpRecon.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAQzD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,CAAA;KAAE,EAAE,CAAC;IACtG,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC7E,UAAU,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC9D;AAGD,wBAAgB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAG3D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,SAAK,GAAG,eAAe,CA2DvG;AAOD,MAAM,MAAM,YAAY,GAAG,mBAAmB,GAAG,uBAAuB,GAAG,uBAAuB,GAAG,iBAAiB,GAAG,kBAAkB,CAAC;AAI5I,eAAO,MAAM,UAAU,GAAI,GAAG,eAAe,KAAG,MACwH,CAAC;AAEzK,wBAAgB,YAAY,CAAC,CAAC,EAAE,eAAe,GAAG;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CA2BxF"}
|
package/dist/core/serpRecon.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/** Registrable-ish host: lowercase, strip scheme/path/www. Good enough to match a domain field. */
|
|
2
1
|
export function hostOf(s) {
|
|
3
2
|
if (!s)
|
|
4
3
|
return '';
|
|
@@ -18,7 +17,7 @@ export function parseSerpForRecon(resp, ownDomain, serpDepth = 20) {
|
|
|
18
17
|
const t = it.type;
|
|
19
18
|
if (t === 'organic') {
|
|
20
19
|
const domain = hostOf(it.domain || it.url);
|
|
21
|
-
const rank = Number(it.rank_group) || organic.length + 1;
|
|
20
|
+
const rank = Number(it.rank_group) || organic.length + 1;
|
|
22
21
|
organic.push({ rank, domain, url: it.url ?? '', title: it.title ?? '' });
|
|
23
22
|
if (own && domain === own && ourOrganicRank == null)
|
|
24
23
|
ourOrganicRank = rank;
|
|
@@ -26,9 +25,6 @@ export function parseSerpForRecon(resp, ownDomain, serpDepth = 20) {
|
|
|
26
25
|
else if (t === 'ai_overview') {
|
|
27
26
|
aioPresent = true;
|
|
28
27
|
aioAsync = !!it.asynchronous_ai_overview;
|
|
29
|
-
// Citations live in TWO places and the nested set is NOT a subset of the top-level one
|
|
30
|
-
// (verified against cached responses: "ai website builder" had 1 top-level reference and
|
|
31
|
-
// 3 further domains only present on the ai_overview_element chunks). Read both, dedupe.
|
|
32
28
|
const seenRef = new Set();
|
|
33
29
|
let i = 0;
|
|
34
30
|
const collect = (refs, nested) => {
|
|
@@ -52,21 +48,15 @@ export function parseSerpForRecon(resp, ownDomain, serpDepth = 20) {
|
|
|
52
48
|
}
|
|
53
49
|
}
|
|
54
50
|
}
|
|
55
|
-
// Citation is only knowable when the AIO actually resolved. An async AIO with no references
|
|
56
|
-
// is UNKNOWN, not "not cited" — 5 of 11 cached AIO SERPs came back that way, and reading them
|
|
57
|
-
// as "not cited" manufactured accuracy-or-freshness verdicts out of a missing fetch.
|
|
58
51
|
const aioResolved = aioPresent && aioReferences.length > 0;
|
|
59
52
|
const aioCitesUs = !aioPresent ? false
|
|
60
53
|
: aioResolved ? aioReferences.some(r => own && r.domain === own)
|
|
61
54
|
: null;
|
|
62
|
-
// Organic ranked above us (the ones actually beating us); if we're absent, the whole top block.
|
|
63
55
|
const organicAbove = ourOrganicRank == null
|
|
64
56
|
? organic.slice(0, 8)
|
|
65
57
|
: organic.filter(o => o.rank < ourOrganicRank);
|
|
66
58
|
return { itemTypes, ourOrganicRank, serpDepth, aioPresent, aioCitesUs, aioAsync, aioResolved, aioReferences, videoPresent, organicAbove, videoItems };
|
|
67
59
|
}
|
|
68
|
-
/** How to say "we didn't find you" without implying a position we never measured. Rank 11 and
|
|
69
|
-
* rank 80 both come back as null, so the honest phrasing has to carry the depth we fetched. */
|
|
70
60
|
export const rankPhrase = (r) => r.ourOrganicRank != null ? `#${r.ourOrganicRank}` : `absent from the top ${r.serpDepth} organic results (true position unknown, and unmeasured beyond ${r.serpDepth})`;
|
|
71
61
|
export function reconVerdict(r) {
|
|
72
62
|
const strongOrganic = r.ourOrganicRank != null && r.ourOrganicRank <= 5;
|
|
@@ -77,8 +67,6 @@ export function reconVerdict(r) {
|
|
|
77
67
|
? { verdict: 'defend-and-deepen', note: `No AI Overview on this SERP; you rank organic ${pos}. Defend and deepen.${shape}` }
|
|
78
68
|
: { verdict: 'competitive-gap', note: `No AI Overview; you rank organic ${pos}. Close the competitive gap.${shape}` };
|
|
79
69
|
}
|
|
80
|
-
// AIO present but unresolved (async, no references pulled): citation is UNKNOWN. Classify on
|
|
81
|
-
// organic strength alone and say so — never bill an unfetched AIO as "does not cite you".
|
|
82
70
|
if (r.aioCitesUs == null) {
|
|
83
71
|
const why = `An AI Overview is present but its citations were not resolved${r.aioAsync ? ' (Google loads it asynchronously)' : ''}, so whether it cites you is UNKNOWN — re-run with the async AI Overview loaded before treating this as an accuracy problem.`;
|
|
84
72
|
return strongOrganic
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serpRecon.js","sourceRoot":"","sources":["../../src/core/serpRecon.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"serpRecon.js","sourceRoot":"","sources":["../../src/core/serpRecon.ts"],"names":[],"mappings":"AAuBA,MAAM,UAAU,MAAM,CAAC,CAA4B;IACjD,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAClB,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;AACjH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAiB,EAAE,SAAiB,EAAE,SAAS,GAAG,EAAE;IACpF,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAClD,MAAM,KAAK,GAAU,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;IACxC,MAAM,SAAS,GAAa,MAAM,CAAC,UAAU,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEtF,IAAI,cAAc,GAAkB,IAAI,CAAC;IACzC,MAAM,OAAO,GAAmE,EAAE,CAAC;IACnF,IAAI,UAAU,GAAG,KAAK,EAAE,QAAQ,GAAG,KAAK,EAAE,YAAY,GAAG,KAAK,CAAC;IAC/D,MAAM,aAAa,GAAqC,EAAE,CAAC;IAC3D,MAAM,UAAU,GAAkC,EAAE,CAAC;IAErD,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;QAClB,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YACpB,MAAM,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;YAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YACzD,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC,CAAC;YACzE,IAAI,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,cAAc,IAAI,IAAI;gBAAE,cAAc,GAAG,IAAI,CAAC;QAC7E,CAAC;aAAM,IAAI,CAAC,KAAK,aAAa,EAAE,CAAC;YAC/B,UAAU,GAAG,IAAI,CAAC;YAClB,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC,wBAAwB,CAAC;YAIzC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;YAClC,IAAI,CAAC,GAAG,CAAC,CAAC;YACV,MAAM,OAAO,GAAG,CAAC,IAAW,EAAE,MAAe,EAAQ,EAAE;gBACrD,KAAK,MAAM,GAAG,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC;oBAC7B,MAAM,GAAG,GAAG,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;oBAC3B,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;wBAAE,SAAS;oBACvC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBACjB,aAAa,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;gBACzI,CAAC;YACH,CAAC,CAAC;YACF,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;YAC9B,KAAK,MAAM,EAAE,IAAI,EAAE,CAAC,KAAK,IAAI,EAAE;gBAAE,OAAO,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC;QACjE,CAAC;aAAM,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,cAAc,EAAE,CAAC;YACjD,YAAY,GAAG,IAAI,CAAC;YACpB,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;gBAC/B,IAAI,CAAC,EAAE,GAAG;oBAAE,UAAU,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACnH,CAAC;QACH,CAAC;IACH,CAAC;IAKD,MAAM,WAAW,GAAG,UAAU,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3D,MAAM,UAAU,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK;QACpC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,KAAK,GAAG,CAAC;YAChE,CAAC,CAAC,IAAI,CAAC;IAGT,MAAM,YAAY,GAAG,cAAc,IAAI,IAAI;QACzC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QACrB,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,cAAe,CAAC,CAAC;IAElD,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;AACxJ,CAAC;AAWD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAkB,EAAU,EAAE,CACvD,CAAC,CAAC,cAAc,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,SAAS,kEAAkE,CAAC,CAAC,SAAS,GAAG,CAAC;AAEzK,MAAM,UAAU,YAAY,CAAC,CAAkB;IAC7C,MAAM,aAAa,GAAG,CAAC,CAAC,cAAc,IAAI,IAAI,IAAI,CAAC,CAAC,cAAc,IAAI,CAAC,CAAC;IACxE,MAAM,KAAK,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,4EAA4E,CAAC,CAAC,CAAC,EAAE,CAAC;IACjH,MAAM,GAAG,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IAC1B,IAAI,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;QAClB,OAAO,aAAa;YAClB,CAAC,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,IAAI,EAAE,iDAAiD,GAAG,uBAAuB,KAAK,EAAE,EAAE;YAC5H,CAAC,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,oCAAoC,GAAG,+BAA+B,KAAK,EAAE,EAAE,CAAC;IAC1H,CAAC;IAGD,IAAI,CAAC,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,gEAAgE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,mCAAmC,CAAC,CAAC,CAAC,EAAE,8HAA8H,CAAC;QAChQ,OAAO,aAAa;YAClB,CAAC,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,IAAI,EAAE,oBAAoB,GAAG,KAAK,GAAG,GAAG,KAAK,EAAE,EAAE;YACnF,CAAC,CAAC,EAAE,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,oBAAoB,GAAG,KAAK,GAAG,GAAG,KAAK,EAAE,EAAE,CAAC;IACtF,CAAC;IACD,IAAI,aAAa,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;QAClC,OAAO,EAAE,OAAO,EAAE,mBAAmB,EAAE,IAAI,EAAE,oBAAoB,GAAG,+EAA+E,KAAK,EAAE,EAAE,CAAC;IAC/J,CAAC;IACD,IAAI,aAAa,IAAI,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;QACnC,OAAO,EAAE,OAAO,EAAE,uBAAuB,EAAE,IAAI,EAAE,oBAAoB,GAAG,mDAAmD,CAAC,CAAC,aAAa,CAAC,MAAM,0HAA0H,KAAK,EAAE,EAAE,CAAC;IACvR,CAAC;IACD,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC,UAAU,EAAE,CAAC;QACnC,OAAO,EAAE,OAAO,EAAE,uBAAuB,EAAE,IAAI,EAAE,4DAA4D,GAAG,0FAA0F,KAAK,EAAE,EAAE,CAAC;IACtN,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,yCAAyC,CAAC,CAAC,aAAa,CAAC,MAAM,oCAAoC,GAAG,sDAAsD,KAAK,EAAE,EAAE,CAAC;AACnN,CAAC"}
|
package/dist/core/sitemap.js
CHANGED
|
@@ -1,16 +1,6 @@
|
|
|
1
1
|
import { gunzipSync } from 'node:zlib';
|
|
2
2
|
import { urlKey } from './url-key.js';
|
|
3
|
-
/**
|
|
4
|
-
* Sitemap discovery + parse for reconciliation against the crawl. Finds sitemaps via robots.txt
|
|
5
|
-
* `Sitemap:` directives (falling back to /sitemap.xml), follows <sitemapindex> children, handles
|
|
6
|
-
* gzipped sitemaps, and returns the listed URLs normalised to url_key. Bounded (count + timeout)
|
|
7
|
-
* so a giant sitemap set can't stall a crawl.
|
|
8
|
-
*/
|
|
9
3
|
const LOC = /<loc>\s*([^<\s]+?)\s*<\/loc>/gi;
|
|
10
|
-
// XML sitemaps legally escape URL characters (?a=1&b=2 is stored as ?a=1&b=2). Decode
|
|
11
|
-
// numeric + the five predefined entities so stored URLs match crawl/GSC url_keys and the
|
|
12
|
-
// crawler seeds fetch the real URL, not the literal `&` form. `&` is decoded last
|
|
13
|
-
// so `&lt;` correctly yields `<` rather than `<`.
|
|
14
4
|
const decodeXmlEntities = (s) => s
|
|
15
5
|
.replace(/&#x([0-9a-f]+);/gi, (_, h) => String.fromCodePoint(parseInt(h, 16)))
|
|
16
6
|
.replace(/&#(\d+);/g, (_, d) => String.fromCodePoint(Number(d)))
|
|
@@ -40,7 +30,6 @@ async function fetchText(url, ua) {
|
|
|
40
30
|
export async function fetchSitemapUrls(origin, ua, keyOpts, opts = {}) {
|
|
41
31
|
const maxSitemaps = opts.maxSitemaps ?? 60;
|
|
42
32
|
const maxUrls = opts.maxUrls ?? 100000;
|
|
43
|
-
// Discover sitemap locations from robots.txt; fall back to /sitemap.xml.
|
|
44
33
|
const sources = [];
|
|
45
34
|
const robots = await fetchText(new URL('/robots.txt', origin).toString(), ua);
|
|
46
35
|
if (robots)
|
|
@@ -48,7 +37,7 @@ export async function fetchSitemapUrls(origin, ua, keyOpts, opts = {}) {
|
|
|
48
37
|
sources.push(m[1].trim());
|
|
49
38
|
if (!sources.length)
|
|
50
39
|
sources.push(new URL('/sitemap.xml', origin).toString());
|
|
51
|
-
const out = new Map();
|
|
40
|
+
const out = new Map();
|
|
52
41
|
const queue = [...new Set(sources)];
|
|
53
42
|
let fetched = 0;
|
|
54
43
|
const URL_BLOCK = /<url>([\s\S]*?)<\/url>/gi;
|
|
@@ -60,7 +49,7 @@ export async function fetchSitemapUrls(origin, ua, keyOpts, opts = {}) {
|
|
|
60
49
|
if (!out.has(k))
|
|
61
50
|
out.set(k, { url: loc, lastmod });
|
|
62
51
|
}
|
|
63
|
-
catch {
|
|
52
|
+
catch { }
|
|
64
53
|
};
|
|
65
54
|
while (queue.length && fetched < maxSitemaps && out.size < maxUrls) {
|
|
66
55
|
const sm = queue.shift();
|
|
@@ -71,11 +60,10 @@ export async function fetchSitemapUrls(origin, ua, keyOpts, opts = {}) {
|
|
|
71
60
|
if (/<sitemapindex[\s>]/i.test(txt)) {
|
|
72
61
|
for (const m of txt.matchAll(LOC)) {
|
|
73
62
|
if (queue.length + fetched < maxSitemaps)
|
|
74
|
-
queue.push(decodeXmlEntities(m[1]));
|
|
63
|
+
queue.push(decodeXmlEntities(m[1]));
|
|
75
64
|
}
|
|
76
65
|
continue;
|
|
77
66
|
}
|
|
78
|
-
// Parse per-<url> block so each <lastmod> claim stays paired with its <loc>.
|
|
79
67
|
let sawBlock = false;
|
|
80
68
|
for (const b of txt.matchAll(URL_BLOCK)) {
|
|
81
69
|
sawBlock = true;
|
|
@@ -86,7 +74,6 @@ export async function fetchSitemapUrls(origin, ua, keyOpts, opts = {}) {
|
|
|
86
74
|
if (out.size >= maxUrls)
|
|
87
75
|
break;
|
|
88
76
|
}
|
|
89
|
-
// Defensive fallback for malformed sitemaps that list bare <loc>s without <url> wrappers.
|
|
90
77
|
if (!sawBlock) {
|
|
91
78
|
for (const m of txt.matchAll(LOC)) {
|
|
92
79
|
add(decodeXmlEntities(m[1]), null);
|
package/dist/core/sitemap.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sitemap.js","sourceRoot":"","sources":["../../src/core/sitemap.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,MAAM,EAAsB,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"sitemap.js","sourceRoot":"","sources":["../../src/core/sitemap.ts"],"names":[],"mappings":"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"}
|
package/dist/core/sql.d.ts
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared SQL fragments. There is exactly ONE definition of "is this page HTML" in SQL —
|
|
3
|
-
* keep it aligned with the runtime helper `isHtmlContentType` in Crawler.ts.
|
|
4
|
-
*/
|
|
5
1
|
export declare const HTML_CT = "(LOWER(content_type) LIKE 'text/html%' OR LOWER(content_type) LIKE 'application/xhtml+xml%')";
|
|
6
2
|
//# sourceMappingURL=sql.d.ts.map
|
package/dist/core/sql.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../src/core/sql.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../src/core/sql.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,OAAO,iGAAiG,CAAC"}
|
package/dist/core/sql.js
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared SQL fragments. There is exactly ONE definition of "is this page HTML" in SQL —
|
|
3
|
-
* keep it aligned with the runtime helper `isHtmlContentType` in Crawler.ts.
|
|
4
|
-
*/
|
|
5
1
|
export const HTML_CT = `(LOWER(content_type) LIKE 'text/html%' OR LOWER(content_type) LIKE 'application/xhtml+xml%')`;
|
|
6
2
|
//# sourceMappingURL=sql.js.map
|
package/dist/core/sql.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql.js","sourceRoot":"","sources":["../../src/core/sql.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sql.js","sourceRoot":"","sources":["../../src/core/sql.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,OAAO,GAAG,8FAA8F,CAAC"}
|
package/dist/core/url-key.d.ts
CHANGED
|
@@ -1,39 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* url-key — the single source of truth for the join between GSC data and crawl data.
|
|
3
|
-
*
|
|
4
|
-
* GSC stores Google-canonicalised URLs; the crawler stores raw discovered URLs.
|
|
5
|
-
* Neither normalises, and they normalise differently — so a naive `page = url`
|
|
6
|
-
* join silently misses trailing-slash / www / protocol / tracking-param variants.
|
|
7
|
-
* Both write paths run their URL through `urlKey()` and store the result in a
|
|
8
|
-
* `*_key` column; all joins use the key. The raw URL is kept for evidence, and
|
|
9
|
-
* raw-vs-key divergence (esp. canonical mismatch) is itself a finding.
|
|
10
|
-
*
|
|
11
|
-
* See research/05 (normalisation pitfalls) and plan/architecture §2.
|
|
12
|
-
*/
|
|
13
1
|
export interface UrlKeyOptions {
|
|
14
|
-
/**
|
|
15
|
-
* Host form to unify to, derived from the GSC property at sync time:
|
|
16
|
-
* - 'apex' → strip a leading `www.`
|
|
17
|
-
* - 'www' → ensure a leading `www.`
|
|
18
|
-
* - 'asis' → leave host as delivered (default; safest when property type unknown)
|
|
19
|
-
*/
|
|
20
2
|
hostForm?: 'apex' | 'www' | 'asis';
|
|
21
|
-
/** Force https (Google almost always canonicalises to https). Default true. */
|
|
22
3
|
forceHttps?: boolean;
|
|
23
4
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Normalise a URL into a stable join key.
|
|
26
|
-
* Returns the original trimmed string if it cannot be parsed (so a bad URL still
|
|
27
|
-
* joins to itself rather than throwing).
|
|
28
|
-
*/
|
|
29
5
|
export declare function urlKey(rawUrl: string, options?: UrlKeyOptions): string;
|
|
30
|
-
/**
|
|
31
|
-
* The registrable brand label of a property — the first domain label, lower-cased, alphanumerics
|
|
32
|
-
* only (so "sc-domain:ehi.com.au" → "ehi", "https://www.sim-racing.gg/" → "simracing"). Returns null
|
|
33
|
-
* for labels under 3 chars (too short to match safely). Used for whole-token brand matching:
|
|
34
|
-
* `(' '||LOWER(query)||' ') LIKE '% '||brand||' %'` — same scheme as the dashboard's branded split.
|
|
35
|
-
*/
|
|
36
6
|
export declare function brandToken(siteUrl: string): string | null;
|
|
37
|
-
/** Derive the hostForm to use from a GSC property identifier. */
|
|
38
7
|
export declare function hostFormForProperty(siteUrl: string): UrlKeyOptions['hostForm'];
|
|
39
8
|
//# sourceMappingURL=url-key.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url-key.d.ts","sourceRoot":"","sources":["../../src/core/url-key.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"url-key.d.ts","sourceRoot":"","sources":["../../src/core/url-key.ts"],"names":[],"mappings":"AAqBA,MAAM,WAAW,aAAa;IAO5B,QAAQ,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;IAEnC,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAaD,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CAgD1E;AAQD,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIzD;AAGD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC,CAS9E"}
|
package/dist/core/url-key.js
CHANGED
|
@@ -1,16 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* url-key — the single source of truth for the join between GSC data and crawl data.
|
|
3
|
-
*
|
|
4
|
-
* GSC stores Google-canonicalised URLs; the crawler stores raw discovered URLs.
|
|
5
|
-
* Neither normalises, and they normalise differently — so a naive `page = url`
|
|
6
|
-
* join silently misses trailing-slash / www / protocol / tracking-param variants.
|
|
7
|
-
* Both write paths run their URL through `urlKey()` and store the result in a
|
|
8
|
-
* `*_key` column; all joins use the key. The raw URL is kept for evidence, and
|
|
9
|
-
* raw-vs-key divergence (esp. canonical mismatch) is itself a finding.
|
|
10
|
-
*
|
|
11
|
-
* See research/05 (normalisation pitfalls) and plan/architecture §2.
|
|
12
|
-
*/
|
|
13
|
-
/** Tracking / session params stripped before keying (prefix match for families). */
|
|
14
1
|
const TRACKING_PARAM_PREFIXES = ['utm_', 'mc_', 'hsa_', '_hs', 'pk_', 'piwik_', 'matomo_'];
|
|
15
2
|
const TRACKING_PARAM_EXACT = new Set([
|
|
16
3
|
'gclid', 'gbraid', 'wbraid', 'dclid', 'fbclid', 'msclkid', 'twclid', 'ttclid',
|
|
@@ -23,11 +10,6 @@ function isTrackingParam(name) {
|
|
|
23
10
|
return true;
|
|
24
11
|
return TRACKING_PARAM_PREFIXES.some(p => lower.startsWith(p));
|
|
25
12
|
}
|
|
26
|
-
/**
|
|
27
|
-
* Normalise a URL into a stable join key.
|
|
28
|
-
* Returns the original trimmed string if it cannot be parsed (so a bad URL still
|
|
29
|
-
* joins to itself rather than throwing).
|
|
30
|
-
*/
|
|
31
13
|
export function urlKey(rawUrl, options = {}) {
|
|
32
14
|
const { hostForm = 'asis', forceHttps = true } = options;
|
|
33
15
|
const raw = (rawUrl ?? '').trim();
|
|
@@ -38,28 +20,21 @@ export function urlKey(rawUrl, options = {}) {
|
|
|
38
20
|
u = new URL(raw);
|
|
39
21
|
}
|
|
40
22
|
catch {
|
|
41
|
-
return raw;
|
|
23
|
+
return raw;
|
|
42
24
|
}
|
|
43
|
-
// Only normalise http(s); leave other schemes (mailto:, tel:) untouched.
|
|
44
25
|
if (u.protocol !== 'http:' && u.protocol !== 'https:')
|
|
45
26
|
return raw;
|
|
46
|
-
// Scheme
|
|
47
27
|
if (forceHttps)
|
|
48
28
|
u.protocol = 'https:';
|
|
49
|
-
// Host: lowercase (hosts are case-insensitive), strip default ports, unify www.
|
|
50
29
|
let host = u.hostname.toLowerCase();
|
|
51
30
|
if (hostForm === 'apex' && host.startsWith('www.'))
|
|
52
31
|
host = host.slice(4);
|
|
53
32
|
else if (hostForm === 'www' && !host.startsWith('www.'))
|
|
54
33
|
host = `www.${host}`;
|
|
55
34
|
u.hostname = host;
|
|
56
|
-
// Strip default web ports unconditionally — after the https rewrite, a leftover
|
|
57
|
-
// :80 would otherwise survive on an https key and break the join.
|
|
58
35
|
if (u.port === '80' || u.port === '443')
|
|
59
36
|
u.port = '';
|
|
60
|
-
// Fragment never affects indexing identity.
|
|
61
37
|
u.hash = '';
|
|
62
|
-
// Query: drop tracking params, sort the rest for stable ordering. Preserve key case.
|
|
63
38
|
const kept = [];
|
|
64
39
|
for (const [k, v] of u.searchParams.entries()) {
|
|
65
40
|
if (!isTrackingParam(k))
|
|
@@ -69,33 +44,21 @@ export function urlKey(rawUrl, options = {}) {
|
|
|
69
44
|
u.search = '';
|
|
70
45
|
for (const [k, v] of kept)
|
|
71
46
|
u.searchParams.append(k, v);
|
|
72
|
-
// Path: preserve case (paths are case-sensitive); strip a single trailing slash
|
|
73
|
-
// except the root. Decode nothing — leave percent-encoding as delivered.
|
|
74
47
|
let path = u.pathname;
|
|
75
48
|
if (path.length > 1 && path.endsWith('/'))
|
|
76
49
|
path = path.slice(0, -1);
|
|
77
50
|
u.pathname = path;
|
|
78
|
-
// Rebuild without a trailing '?' when there are no params.
|
|
79
51
|
const query = u.searchParams.toString();
|
|
80
52
|
return `${u.protocol}//${u.host}${u.pathname}${query ? `?${query}` : ''}`;
|
|
81
53
|
}
|
|
82
|
-
/**
|
|
83
|
-
* The registrable brand label of a property — the first domain label, lower-cased, alphanumerics
|
|
84
|
-
* only (so "sc-domain:ehi.com.au" → "ehi", "https://www.sim-racing.gg/" → "simracing"). Returns null
|
|
85
|
-
* for labels under 3 chars (too short to match safely). Used for whole-token brand matching:
|
|
86
|
-
* `(' '||LOWER(query)||' ') LIKE '% '||brand||' %'` — same scheme as the dashboard's branded split.
|
|
87
|
-
*/
|
|
88
54
|
export function brandToken(siteUrl) {
|
|
89
55
|
const host = (siteUrl ?? '').replace(/^sc-domain:/, '').replace(/^https?:\/\//, '').replace(/^www\./, '').replace(/\/.*$/, '');
|
|
90
56
|
const b = (host.split('.')[0] ?? '').toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
91
57
|
return b.length >= 3 ? b : null;
|
|
92
58
|
}
|
|
93
|
-
/** Derive the hostForm to use from a GSC property identifier. */
|
|
94
59
|
export function hostFormForProperty(siteUrl) {
|
|
95
|
-
// Domain properties ("sc-domain:example.com") cover both — default to apex.
|
|
96
60
|
if (siteUrl.startsWith('sc-domain:'))
|
|
97
61
|
return 'apex';
|
|
98
|
-
// URL-prefix properties carry their own host form; honour it.
|
|
99
62
|
try {
|
|
100
63
|
return new URL(siteUrl).hostname.toLowerCase().startsWith('www.') ? 'www' : 'apex';
|
|
101
64
|
}
|
package/dist/core/url-key.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"url-key.js","sourceRoot":"","sources":["../../src/core/url-key.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"url-key.js","sourceRoot":"","sources":["../../src/core/url-key.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import type { WebCallHandlers } from './webServer.js';
|
|
2
2
|
import type { DataForSeoClient } from './DataForSeoClient.js';
|
|
3
|
-
/**
|
|
4
|
-
* The web UI's server-side call handlers (POST /api/call allowlist), factored out so BOTH
|
|
5
|
-
* surfaces share one definition: the in-MCP `serve_dashboard` / auto-serve (src/server.ts) and
|
|
6
|
-
* the standalone dashboard sidecar (src/dashboard.ts) used in the Docker-aware mode, where the
|
|
7
|
-
* MCP runs stdio-only behind the gateway and a separate published container serves the reports.
|
|
8
|
-
*/
|
|
9
3
|
export interface WebHandlerDeps {
|
|
10
4
|
dataDir: () => string;
|
|
11
5
|
dfs: DataForSeoClient | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webHandlers.d.ts","sourceRoot":"","sources":["../../src/core/webHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAItD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"webHandlers.d.ts","sourceRoot":"","sources":["../../src/core/webHandlers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAItD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAQ9D,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,MAAM,CAAC;IACtB,GAAG,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC7B,OAAO,EAAE,MAAM;QAAE,UAAU,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;CAClG;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,cAAc,GAAG,eAAe,CA4C1E"}
|
package/dist/core/webHandlers.js
CHANGED
|
@@ -11,8 +11,6 @@ export function buildWebCallHandlers(deps) {
|
|
|
11
11
|
return {
|
|
12
12
|
get_dashboard_data: async (a) => {
|
|
13
13
|
const want = String(a.siteUrl ?? '');
|
|
14
|
-
// Only serve properties that actually exist locally — getDashboardData would otherwise
|
|
15
|
-
// CREATE an empty DB file for any bogus siteUrl posted at the API.
|
|
16
14
|
if (!listLocalProperties(dataDir()).some(p => p.siteUrl === want))
|
|
17
15
|
throw new Error(`unknown property ${want}`);
|
|
18
16
|
return { ...getDashboardData(dataDir(), want), apiKeys: deps.apiKeys() };
|
|
@@ -21,7 +19,6 @@ export function buildWebCallHandlers(deps) {
|
|
|
21
19
|
const r = await requireDfs().relatedTerms(String(a.keyword ?? ''), a.location, a.languageCode);
|
|
22
20
|
return r;
|
|
23
21
|
},
|
|
24
|
-
// Content research (on-demand) — News (free Google News + paid DFS) / Videos / Trends.
|
|
25
22
|
news_discovery: async (a) => {
|
|
26
23
|
const kw = String(a.keyword ?? '');
|
|
27
24
|
const seen = new Set();
|
|
@@ -35,14 +32,14 @@ export function buildWebCallHandlers(deps) {
|
|
|
35
32
|
for (const x of g.articles)
|
|
36
33
|
add({ ...x, via: 'google-news' });
|
|
37
34
|
}
|
|
38
|
-
catch {
|
|
35
|
+
catch { }
|
|
39
36
|
if (deps.dfs) {
|
|
40
37
|
try {
|
|
41
38
|
const r = await deps.dfs.serpNews(kw, a.location, a.languageCode);
|
|
42
39
|
for (const x of r.articles)
|
|
43
40
|
add({ ...x, via: 'dataforseo' });
|
|
44
41
|
}
|
|
45
|
-
catch {
|
|
42
|
+
catch { }
|
|
46
43
|
}
|
|
47
44
|
return { articles };
|
|
48
45
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webHandlers.js","sourceRoot":"","sources":["../../src/core/webHandlers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAelD,MAAM,UAAU,oBAAoB,CAAC,IAAoB;IACvD,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACzB,MAAM,UAAU,GAAG,GAAqB,EAAE;QACxC,IAAI,CAAC,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;QACxG,OAAO,IAAI,CAAC,GAAG,CAAC;IAClB,CAAC,CAAC;IACF,OAAO;QACL,kBAAkB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;YAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"webHandlers.js","sourceRoot":"","sources":["../../src/core/webHandlers.ts"],"names":[],"mappings":"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"}
|