@houtini/seo-audit-console 0.9.0 → 0.9.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/README.md +15 -13
- 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 +0 -74
- package/dist/core/DataForSeoClient.d.ts.map +1 -1
- package/dist/core/DataForSeoClient.js +1 -72
- 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.js +16 -166
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/server.json +2 -2
package/dist/audit/topicGaps.js
CHANGED
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Topic-gap engine — "what related topics should this site cover to be expert in its
|
|
3
|
-
* space?" Competitor keyword footprints (DataForSEO Labs ranked_keywords, fetched by
|
|
4
|
-
* the caller — this module makes NO paid calls) minus OUR footprint:
|
|
5
|
-
* A. every distinct query we already earn impressions for in search_analytics, and
|
|
6
|
-
* B. lexical near-matches against our page titles / H1s / slugs (≥70% token cover),
|
|
7
|
-
* then the survivors are clustered lexically (same tokenise + greedy-Jaccard approach
|
|
8
|
-
* as opportunities.ts) and scored by summed search volume × competitor coverage.
|
|
9
|
-
* If the entity layer is populated (page_entity + entity_edge), clusters whose terms
|
|
10
|
-
* sit beside entities we already cover are annotated — stored edges only, no live
|
|
11
|
-
* Wikidata calls.
|
|
12
|
-
*/
|
|
13
1
|
const STOP = new Set(['the', 'a', 'an', 'and', 'or', 'of', 'for', 'to', 'in', 'on', 'with', 'your', 'you', 'is', 'are', 'best', 'how', 'what', 'vs', 'why', 'can', 'my', 'i', 'it']);
|
|
14
2
|
const tokenize = (s) => (s || '').toLowerCase().replace(/[^a-z0-9 ]+/g, ' ').split(/\s+/).filter(t => t.length >= 2 && !STOP.has(t));
|
|
15
3
|
const jaccard = (a, b) => {
|
|
@@ -24,12 +12,9 @@ const jaccard = (a, b) => {
|
|
|
24
12
|
export function computeTopicGaps(db, rows, opts = {}) {
|
|
25
13
|
const limit = opts.limit ?? 15;
|
|
26
14
|
const clusterT = opts.clusterThreshold ?? 0.5;
|
|
27
|
-
// ── OUR footprint, part A: every distinct query we already get impressions for.
|
|
28
15
|
const ourQueries = new Set();
|
|
29
16
|
for (const r of db.prepare(`SELECT DISTINCT lower(query) q FROM search_analytics WHERE query IS NOT NULL AND impressions > 0`).iterate())
|
|
30
17
|
ourQueries.add(r.q);
|
|
31
|
-
// ── OUR footprint, part B: page vocabulary (title + H1 + slug) → inverted index,
|
|
32
|
-
// same 70%-coverage subtraction as opportunities.ts.
|
|
33
18
|
const pages = db.prepare(`SELECT url_key, url, title, h1 FROM pages WHERE status_code = 200`).all();
|
|
34
19
|
const pageTokens = pages.map(p => {
|
|
35
20
|
const slug = (() => { try {
|
|
@@ -73,18 +58,16 @@ export function computeTopicGaps(db, rows, opts = {}) {
|
|
|
73
58
|
if (!prev || (r.searchVolume ?? 0) >= prev.volume)
|
|
74
59
|
m.byCompetitor.set(r.competitor, { volume: r.searchVolume ?? 0, url: r.url ?? prev?.url ?? null });
|
|
75
60
|
}
|
|
76
|
-
// ── Subtraction: drop what we already have (GSC query, or a page that near-covers it).
|
|
77
61
|
const survivors = [];
|
|
78
62
|
for (const m of byKeyword.values()) {
|
|
79
63
|
if (!m.toks.length)
|
|
80
64
|
continue;
|
|
81
65
|
if (ourQueries.has(m.keyword))
|
|
82
|
-
continue;
|
|
66
|
+
continue;
|
|
83
67
|
if (bestPageCover(m.toks).cover >= 0.7)
|
|
84
|
-
continue;
|
|
68
|
+
continue;
|
|
85
69
|
survivors.push(m);
|
|
86
70
|
}
|
|
87
|
-
// ── Cluster survivors lexically (greedy Jaccard, volume-first so heads are the big terms).
|
|
88
71
|
survivors.sort((a, b) => b.volume - a.volume);
|
|
89
72
|
const clusters = [];
|
|
90
73
|
for (const s of survivors) {
|
|
@@ -98,8 +81,6 @@ export function computeTopicGaps(db, rows, opts = {}) {
|
|
|
98
81
|
else
|
|
99
82
|
clusters.push({ head: s, toks: new Set(s.toks), members: [s] });
|
|
100
83
|
}
|
|
101
|
-
// ── Entity adjacency (stored data only): our covered entities that share a parent —
|
|
102
|
-
// a cluster matching one of those labels slots into a topic family we already cover.
|
|
103
84
|
const entityLabels = [];
|
|
104
85
|
try {
|
|
105
86
|
const covered = db.prepare(`SELECT url_key, qid, label FROM page_entity WHERE label IS NOT NULL`).all();
|
|
@@ -117,7 +98,7 @@ export function computeTopicGaps(db, rows, opts = {}) {
|
|
|
117
98
|
}
|
|
118
99
|
}
|
|
119
100
|
}
|
|
120
|
-
catch {
|
|
101
|
+
catch { }
|
|
121
102
|
const entityNoteFor = (clusterToks) => {
|
|
122
103
|
let best = null;
|
|
123
104
|
for (const e of entityLabels) {
|
|
@@ -131,7 +112,6 @@ export function computeTopicGaps(db, rows, opts = {}) {
|
|
|
131
112
|
}
|
|
132
113
|
return best ? `sits beside "${best.label}" in your entity graph (shared parent topic already covered)` : null;
|
|
133
114
|
};
|
|
134
|
-
// ── Score + shape the output clusters.
|
|
135
115
|
const out = clusters.map(c => {
|
|
136
116
|
const volByCompetitor = new Map();
|
|
137
117
|
let totalVolume = 0;
|
|
@@ -142,7 +122,6 @@ export function computeTopicGaps(db, rows, opts = {}) {
|
|
|
142
122
|
}
|
|
143
123
|
const coverage = volByCompetitor.size;
|
|
144
124
|
const ownedBy = [...volByCompetitor.entries()].sort((a, b) => b[1] - a[1])[0]?.[0] ?? '';
|
|
145
|
-
// Example URL: the owner's URL for the head term, else the owner's highest-volume member.
|
|
146
125
|
const exampleUrl = c.head.byCompetitor.get(ownedBy)?.url ??
|
|
147
126
|
c.members.map(m => m.byCompetitor.get(ownedBy)?.url).find(u => u != null) ?? null;
|
|
148
127
|
const near = bestPageCover([...c.toks]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"topicGaps.js","sourceRoot":"","sources":["../../src/audit/topicGaps.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"topicGaps.js","sourceRoot":"","sources":["../../src/audit/topicGaps.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AuditDatabase — one SQLite database per GSC property, colocating:
|
|
3
|
-
* - GSC history (search_analytics) ← from better-search-console
|
|
4
|
-
* - crawl snapshot (crawl_metadata, pages, links, errors) ← from seo-crawler-mcp
|
|
5
|
-
* - audit results (audit_runs, findings) ← new
|
|
6
|
-
*
|
|
7
|
-
* The join spine is the normalised URL key (`page_key` / `url_key`), written by
|
|
8
|
-
* url-key.ts on both the GSC and crawl write paths. See plan/architecture §2.
|
|
9
|
-
*
|
|
10
|
-
* Never console.log — MCP speaks JSON-RPC over stdio; use console.error for debug.
|
|
11
|
-
*/
|
|
12
1
|
import Database from 'better-sqlite3';
|
|
13
2
|
export type FindingLabel = 'D' | 'N' | 'L' | 'G' | 'S';
|
|
14
3
|
export type Severity = 'crit' | 'high' | 'med' | 'low' | 'info';
|
|
@@ -16,7 +5,6 @@ export declare class AuditDatabase {
|
|
|
16
5
|
readonly db: Database.Database;
|
|
17
6
|
constructor(dbPath: string);
|
|
18
7
|
private initializeTables;
|
|
19
|
-
/** Idempotent column additions for DBs created before a column existed. */
|
|
20
8
|
private migrate;
|
|
21
9
|
upsertProperty(siteUrl: string, hostForm: string, permissionLevel?: string): void;
|
|
22
10
|
getProperty(siteUrl: string): {
|
|
@@ -24,9 +12,7 @@ export declare class AuditDatabase {
|
|
|
24
12
|
host_form: string;
|
|
25
13
|
last_synced_at: string | null;
|
|
26
14
|
} | undefined;
|
|
27
|
-
/** Persist the DataForSEO target location for a property (string name or numeric code). */
|
|
28
15
|
setDfsLocation(siteUrl: string, location: string | number): void;
|
|
29
|
-
/** Resolved DataForSEO location for a property: a code, a name, or undefined. */
|
|
30
16
|
getDfsLocation(siteUrl: string): string | number | undefined;
|
|
31
17
|
close(): void;
|
|
32
18
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuditDatabase.d.ts","sourceRoot":"","sources":["../../src/core/AuditDatabase.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AuditDatabase.d.ts","sourceRoot":"","sources":["../../src/core/AuditDatabase.ts"],"names":[],"mappings":"AAWA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAItC,MAAM,MAAM,YAAY,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AACvD,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;AAEhE,qBAAa,aAAa;IACxB,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,CAAC;gBAEnB,MAAM,EAAE,MAAM;IAgB1B,OAAO,CAAC,gBAAgB;IA0cxB,OAAO,CAAC,OAAO;IA+Df,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI;IAWjF,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,SAAS;IAOhH,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAOhE,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS;IAO5D,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -1,14 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AuditDatabase — one SQLite database per GSC property, colocating:
|
|
3
|
-
* - GSC history (search_analytics) ← from better-search-console
|
|
4
|
-
* - crawl snapshot (crawl_metadata, pages, links, errors) ← from seo-crawler-mcp
|
|
5
|
-
* - audit results (audit_runs, findings) ← new
|
|
6
|
-
*
|
|
7
|
-
* The join spine is the normalised URL key (`page_key` / `url_key`), written by
|
|
8
|
-
* url-key.ts on both the GSC and crawl write paths. See plan/architecture §2.
|
|
9
|
-
*
|
|
10
|
-
* Never console.log — MCP speaks JSON-RPC over stdio; use console.error for debug.
|
|
11
|
-
*/
|
|
12
1
|
import Database from 'better-sqlite3';
|
|
13
2
|
import { mkdirSync } from 'node:fs';
|
|
14
3
|
import { dirname } from 'node:path';
|
|
@@ -18,19 +7,15 @@ export class AuditDatabase {
|
|
|
18
7
|
mkdirSync(dirname(dbPath), { recursive: true });
|
|
19
8
|
this.db = new Database(dbPath);
|
|
20
9
|
this.db.pragma('journal_mode = WAL');
|
|
21
|
-
this.db.pragma('synchronous = NORMAL');
|
|
22
|
-
this.db.pragma('busy_timeout = 10000');
|
|
10
|
+
this.db.pragma('synchronous = NORMAL');
|
|
11
|
+
this.db.pragma('busy_timeout = 10000');
|
|
23
12
|
this.db.pragma('foreign_keys = ON');
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
this.db.pragma('cache_size = -262144'); // 256 MB page cache (negative = KiB)
|
|
28
|
-
this.db.pragma('mmap_size = 536870912'); // 512 MB memory-mapped I/O
|
|
29
|
-
this.db.pragma('temp_store = MEMORY'); // GROUP BY / ORDER BY scratch in RAM, not on disk
|
|
13
|
+
this.db.pragma('cache_size = -262144');
|
|
14
|
+
this.db.pragma('mmap_size = 536870912');
|
|
15
|
+
this.db.pragma('temp_store = MEMORY');
|
|
30
16
|
this.initializeTables();
|
|
31
17
|
}
|
|
32
18
|
initializeTables() {
|
|
33
|
-
// ── Property + sync/crawl bookkeeping ──────────────────────────────────
|
|
34
19
|
this.db.exec(`
|
|
35
20
|
CREATE TABLE IF NOT EXISTS property_meta (
|
|
36
21
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -44,7 +29,6 @@ export class AuditDatabase {
|
|
|
44
29
|
created_at TEXT DEFAULT (datetime('now'))
|
|
45
30
|
);
|
|
46
31
|
`);
|
|
47
|
-
// ── GSC history (from better-search-console) + page_key for the join ───
|
|
48
32
|
this.db.exec(`
|
|
49
33
|
CREATE TABLE IF NOT EXISTS search_analytics (
|
|
50
34
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -85,7 +69,6 @@ export class AuditDatabase {
|
|
|
85
69
|
created_at TEXT NOT NULL
|
|
86
70
|
);
|
|
87
71
|
`);
|
|
88
|
-
// ── Crawl snapshot (from seo-crawler-mcp), url_key added, redirects captured ─
|
|
89
72
|
this.db.exec(`
|
|
90
73
|
CREATE TABLE IF NOT EXISTS crawl_metadata (
|
|
91
74
|
crawl_id TEXT PRIMARY KEY,
|
|
@@ -182,9 +165,6 @@ export class AuditDatabase {
|
|
|
182
165
|
CREATE INDEX IF NOT EXISTS idx_pages_indexable ON pages(indexable);
|
|
183
166
|
CREATE INDEX IF NOT EXISTS idx_pages_ipr ON pages(ipr DESC);
|
|
184
167
|
`);
|
|
185
|
-
// ── Change-detection (drift): one persistent snapshot per (crawl, URL) of the SEO-salient
|
|
186
|
-
// fields. `pages` only ever holds the latest crawl (unique url_key), so cross-crawl diffing
|
|
187
|
-
// needs its own history table. Written once per crawl at audit time (INSERT OR IGNORE). ──
|
|
188
168
|
this.db.exec(`
|
|
189
169
|
CREATE TABLE IF NOT EXISTS page_snapshots (
|
|
190
170
|
crawl_id TEXT NOT NULL,
|
|
@@ -206,8 +186,6 @@ export class AuditDatabase {
|
|
|
206
186
|
CREATE INDEX IF NOT EXISTS idx_snap_urlkey ON page_snapshots(url_key);
|
|
207
187
|
CREATE INDEX IF NOT EXISTS idx_snap_captured ON page_snapshots(captured_at);
|
|
208
188
|
`);
|
|
209
|
-
// Agent-readiness result (one row per origin) — populated by check_agent_readiness, read by
|
|
210
|
-
// the dashboard. Live HTTP probe, not crawl-derived, so it persists separately.
|
|
211
189
|
this.db.exec(`
|
|
212
190
|
CREATE TABLE IF NOT EXISTS agent_readiness (
|
|
213
191
|
origin TEXT PRIMARY KEY,
|
|
@@ -249,7 +227,6 @@ export class AuditDatabase {
|
|
|
249
227
|
);
|
|
250
228
|
CREATE INDEX IF NOT EXISTS idx_errors_type ON errors(error_type);
|
|
251
229
|
`);
|
|
252
|
-
// ── GSC URL Inspection (authoritative per-URL index status) ─────────────
|
|
253
230
|
this.db.exec(`
|
|
254
231
|
CREATE TABLE IF NOT EXISTS url_inspection (
|
|
255
232
|
url_key TEXT PRIMARY KEY,
|
|
@@ -269,7 +246,6 @@ export class AuditDatabase {
|
|
|
269
246
|
);
|
|
270
247
|
CREATE INDEX IF NOT EXISTS idx_inspection_coverage ON url_inspection(coverage_state);
|
|
271
248
|
`);
|
|
272
|
-
// ── DataForSEO rank history (over-time sequence, monthly) ───────────────
|
|
273
249
|
this.db.exec(`
|
|
274
250
|
CREATE TABLE IF NOT EXISTS rank_history (
|
|
275
251
|
period TEXT PRIMARY KEY, -- YYYY-MM
|
|
@@ -283,7 +259,6 @@ export class AuditDatabase {
|
|
|
283
259
|
fetched_at TEXT DEFAULT (datetime('now'))
|
|
284
260
|
);
|
|
285
261
|
`);
|
|
286
|
-
// ── Audit results (new) ────────────────────────────────────────────────
|
|
287
262
|
this.db.exec(`
|
|
288
263
|
CREATE TABLE IF NOT EXISTS audit_runs (
|
|
289
264
|
run_id TEXT PRIMARY KEY,
|
|
@@ -318,7 +293,6 @@ export class AuditDatabase {
|
|
|
318
293
|
CREATE INDEX IF NOT EXISTS idx_findings_priority ON findings(priority DESC);
|
|
319
294
|
CREATE INDEX IF NOT EXISTS idx_findings_check ON findings(check_id);
|
|
320
295
|
`);
|
|
321
|
-
// ── Backlinks (DataForSEO, on-demand) — page-level counts + live HTTP status ──
|
|
322
296
|
this.db.exec(`
|
|
323
297
|
CREATE TABLE IF NOT EXISTS page_backlinks (
|
|
324
298
|
url_key TEXT PRIMARY KEY, -- normalised join key (urlKey of the page)
|
|
@@ -331,7 +305,6 @@ export class AuditDatabase {
|
|
|
331
305
|
);
|
|
332
306
|
CREATE INDEX IF NOT EXISTS idx_pbl_backlinks ON page_backlinks(backlinks DESC);
|
|
333
307
|
`);
|
|
334
|
-
// ── Sitemap URLs (for crawl↔sitemap reconciliation) ────────────────────
|
|
335
308
|
this.db.exec(`
|
|
336
309
|
CREATE TABLE IF NOT EXISTS sitemap_urls (
|
|
337
310
|
url_key TEXT PRIMARY KEY, -- normalised join key of a URL listed in the XML sitemap(s)
|
|
@@ -340,7 +313,6 @@ export class AuditDatabase {
|
|
|
340
313
|
fetched_at TEXT DEFAULT (datetime('now'))
|
|
341
314
|
);
|
|
342
315
|
`);
|
|
343
|
-
// ── Image weights (post-crawl sample: distinct <img> srcs + content-length) ─
|
|
344
316
|
this.db.exec(`
|
|
345
317
|
CREATE TABLE IF NOT EXISTS image_assets (
|
|
346
318
|
url TEXT PRIMARY KEY,
|
|
@@ -351,8 +323,6 @@ export class AuditDatabase {
|
|
|
351
323
|
fetched_at TEXT DEFAULT (datetime('now'))
|
|
352
324
|
);
|
|
353
325
|
`);
|
|
354
|
-
// ── DataForSEO on-demand enrichments persisted for the audit (6a) ────────
|
|
355
|
-
// Keyword intent (Labs search_intent) → powers intent-vs-pagetype-mismatch.
|
|
356
326
|
this.db.exec(`
|
|
357
327
|
CREATE TABLE IF NOT EXISTS keyword_intent (
|
|
358
328
|
keyword TEXT PRIMARY KEY,
|
|
@@ -361,7 +331,6 @@ export class AuditDatabase {
|
|
|
361
331
|
fetched_at TEXT DEFAULT (datetime('now'))
|
|
362
332
|
);
|
|
363
333
|
`);
|
|
364
|
-
// Per-URL lab Core Web Vitals (On-Page Lighthouse) → powers high-yield-cwv-fail.
|
|
365
334
|
this.db.exec(`
|
|
366
335
|
CREATE TABLE IF NOT EXISTS page_cwv (
|
|
367
336
|
url_key TEXT PRIMARY KEY, -- urlKey of the audited URL (join spine)
|
|
@@ -374,7 +343,6 @@ export class AuditDatabase {
|
|
|
374
343
|
fetched_at TEXT DEFAULT (datetime('now'))
|
|
375
344
|
);
|
|
376
345
|
`);
|
|
377
|
-
// ── Wikidata entity layer (6d) — heuristic H1→QID resolution + relationship edges ──
|
|
378
346
|
this.db.exec(`
|
|
379
347
|
CREATE TABLE IF NOT EXISTS page_entity (
|
|
380
348
|
url_key TEXT PRIMARY KEY, -- page resolved to a Wikidata entity
|
|
@@ -393,8 +361,6 @@ export class AuditDatabase {
|
|
|
393
361
|
);
|
|
394
362
|
CREATE INDEX IF NOT EXISTS idx_entity_edge_related ON entity_edge(related_qid);
|
|
395
363
|
`);
|
|
396
|
-
// ── Content recon (recon_targets) — per-page SERP/AIO classification + a trackable
|
|
397
|
-
// to-do ledger with baseline→outcome so a fix's effect on rank/citation is measurable.
|
|
398
364
|
this.db.exec(`
|
|
399
365
|
CREATE TABLE IF NOT EXISTS recon_page (
|
|
400
366
|
url_key TEXT PRIMARY KEY, -- OUR page under recon
|
|
@@ -432,11 +398,6 @@ export class AuditDatabase {
|
|
|
432
398
|
CREATE INDEX IF NOT EXISTS idx_recon_todo_url ON recon_todo(url_key);
|
|
433
399
|
CREATE INDEX IF NOT EXISTS idx_recon_todo_status ON recon_todo(status);
|
|
434
400
|
`);
|
|
435
|
-
// ── Link intersect (link_intersect) — domains that link to our competitors but not
|
|
436
|
-
// to us, the classic "what links do our rivals have that we don't" prospect list.
|
|
437
|
-
// DataForSEO backlinks/domain_intersection fills the core columns; MajesticClient
|
|
438
|
-
// fills trust_flow/topical_trust_flow when MAJESTIC_API_KEY is set (the directory-
|
|
439
|
-
// killer re-sort); the contact_* columns are the later owned-page capture tier.
|
|
440
401
|
this.db.exec(`
|
|
441
402
|
CREATE TABLE IF NOT EXISTS link_prospects (
|
|
442
403
|
domain TEXT PRIMARY KEY, -- the prospect (referring) domain we'd pursue a link from
|
|
@@ -466,7 +427,6 @@ export class AuditDatabase {
|
|
|
466
427
|
`);
|
|
467
428
|
this.migrate();
|
|
468
429
|
}
|
|
469
|
-
/** Idempotent column additions for DBs created before a column existed. */
|
|
470
430
|
migrate() {
|
|
471
431
|
const cols = (table) => new Set(this.db.prepare(`PRAGMA table_info(${table})`).all().map(c => c.name));
|
|
472
432
|
const ensure = (table, col, ddl) => {
|
|
@@ -490,7 +450,7 @@ export class AuditDatabase {
|
|
|
490
450
|
ensure('pages', 'body_chunks', 'body_chunks TEXT');
|
|
491
451
|
ensure('pages', 'has_favicon', 'has_favicon INTEGER');
|
|
492
452
|
ensure('pages', 'has_analytics', 'has_analytics INTEGER');
|
|
493
|
-
ensure('pages', 'conditional_304', 'conditional_304 INTEGER');
|
|
453
|
+
ensure('pages', 'conditional_304', 'conditional_304 INTEGER');
|
|
494
454
|
ensure('sitemap_urls', 'lastmod', 'lastmod TEXT');
|
|
495
455
|
ensure('pages', 'max_passage_score', 'max_passage_score REAL');
|
|
496
456
|
ensure('pages', 'max_passage_query', 'max_passage_query TEXT');
|
|
@@ -498,37 +458,26 @@ export class AuditDatabase {
|
|
|
498
458
|
ensure('pages', 'max_passage_at', 'max_passage_at TEXT');
|
|
499
459
|
ensure('pages', 'click_depth', 'click_depth INTEGER');
|
|
500
460
|
ensure('pages', 'indexable_reason', 'indexable_reason TEXT');
|
|
501
|
-
// Majestic per-URL authority on backlinked pages (trapped-authority v2) — filled by
|
|
502
|
-
// pull_backlinks when MAJESTIC_API_KEY is set. topical_trust_flow is JSON [{topic,value}].
|
|
503
461
|
ensure('page_backlinks', 'trust_flow', 'trust_flow INTEGER');
|
|
504
462
|
ensure('page_backlinks', 'citation_flow', 'citation_flow INTEGER');
|
|
505
463
|
ensure('page_backlinks', 'topical_trust_flow', 'topical_trust_flow TEXT');
|
|
506
464
|
ensure('page_backlinks', 'majestic_at', 'majestic_at TEXT');
|
|
507
|
-
// property-level backlink profile summary (from DataForSEO backlinks/summary)
|
|
508
465
|
ensure('property_meta', 'total_backlinks', 'total_backlinks INTEGER');
|
|
509
466
|
ensure('property_meta', 'referring_domains', 'referring_domains INTEGER');
|
|
510
467
|
ensure('property_meta', 'backlinks_spam_score', 'backlinks_spam_score REAL');
|
|
511
468
|
ensure('property_meta', 'backlinks_fetched_at', 'backlinks_fetched_at TEXT');
|
|
512
|
-
|
|
513
|
-
ensure('property_meta', 'backlinks_rank', 'backlinks_rank INTEGER'); // DataForSEO Domain Rank (0–1000)
|
|
469
|
+
ensure('property_meta', 'backlinks_rank', 'backlinks_rank INTEGER');
|
|
514
470
|
ensure('property_meta', 'broken_backlinks', 'broken_backlinks INTEGER');
|
|
515
471
|
ensure('property_meta', 'broken_pages', 'broken_pages INTEGER');
|
|
516
|
-
ensure('property_meta', 'backlinks_nofollow_pct', 'backlinks_nofollow_pct REAL');
|
|
517
|
-
// rank_history keyword-movement counts + paid-value — same historical_rank_overview response we already pay for
|
|
472
|
+
ensure('property_meta', 'backlinks_nofollow_pct', 'backlinks_nofollow_pct REAL');
|
|
518
473
|
ensure('rank_history', 'is_new', 'is_new INTEGER');
|
|
519
474
|
ensure('rank_history', 'is_up', 'is_up INTEGER');
|
|
520
475
|
ensure('rank_history', 'is_down', 'is_down INTEGER');
|
|
521
476
|
ensure('rank_history', 'is_lost', 'is_lost INTEGER');
|
|
522
477
|
ensure('rank_history', 'estimated_paid_traffic_cost', 'estimated_paid_traffic_cost REAL');
|
|
523
|
-
// url_inspection: sample of referring pages Google reports for the URL (JSON array of URLs)
|
|
524
478
|
ensure('url_inspection', 'referring_urls', 'referring_urls TEXT');
|
|
525
|
-
// GSC search type ('web' | 'discover' | 'googleNews' | 'image' | 'video'). NOTE: the unique
|
|
526
|
-
// index idx_sa_unique deliberately does NOT include this column (rebuilding it on existing
|
|
527
|
-
// rows would rewrite months of history) — the table therefore holds ONE search type at a
|
|
528
|
-
// time, enforced by the mode-guard in GscSync (a type switch wipes, riding the first batch).
|
|
529
479
|
ensure('search_analytics', 'search_type', "search_type TEXT DEFAULT 'web'");
|
|
530
480
|
}
|
|
531
|
-
// ── Minimal property accessors (full CRUD added as modules are wired) ─────
|
|
532
481
|
upsertProperty(siteUrl, hostForm, permissionLevel) {
|
|
533
482
|
this.db
|
|
534
483
|
.prepare(`INSERT INTO property_meta (site_url, host_form, permission_level)
|
|
@@ -540,13 +489,11 @@ export class AuditDatabase {
|
|
|
540
489
|
getProperty(siteUrl) {
|
|
541
490
|
return this.db.prepare('SELECT site_url, host_form, last_synced_at FROM property_meta WHERE site_url = ?').get(siteUrl);
|
|
542
491
|
}
|
|
543
|
-
/** Persist the DataForSEO target location for a property (string name or numeric code). */
|
|
544
492
|
setDfsLocation(siteUrl, location) {
|
|
545
493
|
this.db
|
|
546
494
|
.prepare('UPDATE property_meta SET dfs_location_code = ?, dfs_location_name = ? WHERE site_url = ?')
|
|
547
495
|
.run(typeof location === 'number' ? location : null, typeof location === 'string' ? location : null, siteUrl);
|
|
548
496
|
}
|
|
549
|
-
/** Resolved DataForSEO location for a property: a code, a name, or undefined. */
|
|
550
497
|
getDfsLocation(siteUrl) {
|
|
551
498
|
const r = this.db.prepare('SELECT dfs_location_code c, dfs_location_name n FROM property_meta WHERE site_url = ?').get(siteUrl);
|
|
552
499
|
return r?.c ?? r?.n ?? undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AuditDatabase.js","sourceRoot":"","sources":["../../src/core/AuditDatabase.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AuditDatabase.js","sourceRoot":"","sources":["../../src/core/AuditDatabase.ts"],"names":[],"mappings":"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"}
|
package/dist/core/Backlinks.d.ts
CHANGED
|
@@ -15,13 +15,6 @@ export interface BacklinksResult {
|
|
|
15
15
|
cached: boolean;
|
|
16
16
|
cost: number;
|
|
17
17
|
}
|
|
18
|
-
/**
|
|
19
|
-
* On-demand backlink profile via DataForSEO (cheap endpoints): summary/live (overall
|
|
20
|
-
* profile → property_meta) + domain_pages_summary/live (per-page backlink counts →
|
|
21
|
-
* page_backlinks). Then resolves each backlinked page's live HTTP status — from the
|
|
22
|
-
* crawl when present, else a bounded fetch — so backlinks-to-404 is precise.
|
|
23
|
-
* Never auto-run (the user's rule: backlinks are paid + on-demand); 20-day cached.
|
|
24
|
-
*/
|
|
25
18
|
export declare class Backlinks {
|
|
26
19
|
private readonly dfs;
|
|
27
20
|
private readonly dataDir;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Backlinks.d.ts","sourceRoot":"","sources":["../../src/core/Backlinks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAoBrD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IACtE,cAAc,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IACjD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAC7C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;CAC/B;
|
|
1
|
+
{"version":3,"file":"Backlinks.d.ts","sourceRoot":"","sources":["../../src/core/Backlinks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAoBrD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAC;IACtE,cAAc,EAAE,MAAM,CAAC;IAAC,gBAAgB,EAAE,MAAM,CAAC;IACjD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAC7C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;CAC/B;AASD,qBAAa,SAAS;IACR,OAAO,CAAC,QAAQ,CAAC,GAAG;IAAoB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAAU,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAlF,GAAG,EAAE,gBAAgB,EAAmB,OAAO,EAAE,MAAM,EAAmB,QAAQ,GAAE,cAAc,GAAG,IAAW;IAEvI,GAAG,CACP,OAAO,EAAE,MAAM,EACf,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,EAC1F,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,EAC5C,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,eAAe,CAAC;CAuH5B"}
|
package/dist/core/Backlinks.js
CHANGED
|
@@ -3,7 +3,6 @@ import { dbPathFor } from './paths.js';
|
|
|
3
3
|
import { urlKey, hostFormForProperty } from './url-key.js';
|
|
4
4
|
const n = (v) => Number(v) || 0;
|
|
5
5
|
const domainFromProperty = (siteUrl) => siteUrl.replace(/^sc-domain:/, '').replace(/^https?:\/\//, '').replace(/\/+$/, '');
|
|
6
|
-
/** Live HTTP status of a backlinked URL (follow redirects → final status; null on error). */
|
|
7
6
|
async function statusOf(url, ua) {
|
|
8
7
|
try {
|
|
9
8
|
const res = await fetch(url, {
|
|
@@ -17,13 +16,6 @@ async function statusOf(url, ua) {
|
|
|
17
16
|
return null;
|
|
18
17
|
}
|
|
19
18
|
}
|
|
20
|
-
/**
|
|
21
|
-
* On-demand backlink profile via DataForSEO (cheap endpoints): summary/live (overall
|
|
22
|
-
* profile → property_meta) + domain_pages_summary/live (per-page backlink counts →
|
|
23
|
-
* page_backlinks). Then resolves each backlinked page's live HTTP status — from the
|
|
24
|
-
* crawl when present, else a bounded fetch — so backlinks-to-404 is precise.
|
|
25
|
-
* Never auto-run (the user's rule: backlinks are paid + on-demand); 20-day cached.
|
|
26
|
-
*/
|
|
27
19
|
export class Backlinks {
|
|
28
20
|
dfs;
|
|
29
21
|
dataDir;
|
|
@@ -40,10 +32,7 @@ export class Backlinks {
|
|
|
40
32
|
const db = new AuditDatabase(dbPathFor(this.dataDir, siteUrl));
|
|
41
33
|
try {
|
|
42
34
|
db.upsertProperty(siteUrl, hostForm ?? 'asis');
|
|
43
|
-
// 1. Profile summary → property_meta
|
|
44
35
|
const sum = await this.dfs.backlinksSummary(target);
|
|
45
|
-
// Surface task-level failures (the Backlinks API is a SEPARATE DataForSEO subscription —
|
|
46
|
-
// a 40204 here means it isn't activated). Don't silently store 0 backlinks.
|
|
47
36
|
const task = sum.tasks[0];
|
|
48
37
|
if (!task || (task.status_code ?? 0) >= 40000) {
|
|
49
38
|
const msg = task?.status_message ?? 'no task returned';
|
|
@@ -51,14 +40,11 @@ export class Backlinks {
|
|
|
51
40
|
(task?.status_code === 40204 ? ' — the Backlinks API is a separate DataForSEO subscription; activate it at app.dataforseo.com/backlinks-subscription to use pull_backlinks.' : ''));
|
|
52
41
|
}
|
|
53
42
|
const s = task.result?.[0] ?? {};
|
|
54
|
-
// Summary extras previously dropped from the same paid response: Domain Rank (the authority
|
|
55
|
-
// number), broken backlinks/pages (equity leaks Google's link graph sees), nofollow share.
|
|
56
43
|
const nofollowPct = n(s.backlinks) > 0 ? n(s.referring_links_attributes?.nofollow) / n(s.backlinks) : null;
|
|
57
44
|
db.db.prepare(`UPDATE property_meta SET total_backlinks=?, referring_domains=?, backlinks_spam_score=?,
|
|
58
45
|
backlinks_rank=?, broken_backlinks=?, broken_pages=?, backlinks_nofollow_pct=?,
|
|
59
46
|
backlinks_fetched_at=datetime('now') WHERE site_url=?`).run(n(s.backlinks), n(s.referring_domains), s.backlinks_spam_score ?? null, s.rank != null ? n(s.rank) : null, n(s.broken_backlinks), n(s.broken_pages), nofollowPct, siteUrl);
|
|
60
47
|
update({ phase: 'summary', backlinks: n(s.backlinks), referringDomains: n(s.referring_domains), rank: s.rank ?? null });
|
|
61
|
-
// 2. Per-page backlink counts → page_backlinks
|
|
62
48
|
const res = await this.dfs.domainPagesSummary(target, opts.limit ?? 1000);
|
|
63
49
|
const items = res.tasks[0]?.result?.[0]?.items ?? [];
|
|
64
50
|
const rows = items
|
|
@@ -73,7 +59,6 @@ export class Backlinks {
|
|
|
73
59
|
};
|
|
74
60
|
})
|
|
75
61
|
.filter(r => r.url && r.url_key);
|
|
76
|
-
// 3. Live status — reuse crawl status where we have it; fetch the rest (bounded, by backlinks).
|
|
77
62
|
const crawlStatus = new Map(db.db.prepare('SELECT url_key, status_code FROM pages WHERE status_code IS NOT NULL').all()
|
|
78
63
|
.map(r => [r.url_key, r.status_code]));
|
|
79
64
|
const toFetch = rows.filter(r => !crawlStatus.has(r.url_key)).sort((a, b) => b.backlinks - a.backlinks).slice(0, opts.statusLimit ?? 150);
|
|
@@ -95,15 +80,8 @@ export class Backlinks {
|
|
|
95
80
|
for (const r of rows)
|
|
96
81
|
upsert.run({ ...r, status_code: crawlStatus.get(r.url_key) ?? fetched.get(r.url_key) ?? null });
|
|
97
82
|
})();
|
|
98
|
-
// Majestic per-URL Trust Flow (trapped-authority v2). GetIndexItemInfo batches ≤100 items
|
|
99
|
-
// per call and MajesticClient slices internally, so this is ceil(N/100) calls, not N. Bounded
|
|
100
|
-
// to the most-backlinked URLs, only when a Majestic key is set, and never fails the pull.
|
|
101
83
|
let majesticEnriched = 0;
|
|
102
84
|
if (this.majestic && rows.length && !signal.aborted) {
|
|
103
|
-
// Enrich a BROAD set, not just the most-linked: trapped-authority pages are deep pages
|
|
104
|
-
// with only a few referring domains, so a top-N-by-backlinks slice misses exactly the
|
|
105
|
-
// pages that matter. Cap high (batched ≤100/call, cached 30d); sort only decides which
|
|
106
|
-
// survive the cap on very large sites.
|
|
107
85
|
const cand = [...rows].sort((a, b) => b.backlinks - a.backlinks).slice(0, Math.min(rows.length, opts.majesticLimit ?? 500));
|
|
108
86
|
const byUrl = new Map(cand.map(r => [r.url, r.url_key]));
|
|
109
87
|
try {
|
|
@@ -120,7 +98,7 @@ export class Backlinks {
|
|
|
120
98
|
}
|
|
121
99
|
})();
|
|
122
100
|
}
|
|
123
|
-
catch {
|
|
101
|
+
catch { }
|
|
124
102
|
}
|
|
125
103
|
return {
|
|
126
104
|
siteUrl, target, pages: rows.length, statusChecked: fetched.size,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Backlinks.js","sourceRoot":"","sources":["../../src/core/Backlinks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAE3D,MAAM,CAAC,GAAG,CAAC,CAAU,EAAU,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACjD,MAAM,kBAAkB,GAAG,CAAC,OAAe,EAAU,EAAE,CACrD,OAAO,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"Backlinks.js","sourceRoot":"","sources":["../../src/core/Backlinks.ts"],"names":[],"mappings":"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"}
|
package/dist/core/Crawler.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Crawler.d.ts","sourceRoot":"","sources":["../../src/core/Crawler.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,iBAAiB,GAAI,IAAI,MAAM,GAAG,IAAI,GAAG,SAAS,KAAG,OACE,CAAC;AAqCrE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"Crawler.d.ts","sourceRoot":"","sources":["../../src/core/Crawler.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,iBAAiB,GAAI,IAAI,MAAM,GAAG,IAAI,GAAG,SAAS,KAAG,OACE,CAAC;AAqCrE,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB;AA6ID,qBAAa,OAAO;IACN,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,MAAM;IAEtC,GAAG,CACP,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,EAC5C,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,WAAW,CAAC;CAiXxB"}
|