seo 0.17.2 → 0.17.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +84 -84
- package/dist/cli.js.map +1 -1
- package/dist/{dist-Ck71nZiP.js → dist-BNTdDj1i.js} +1 -1
- package/dist/{dist-CW8OlPkK.js → dist-CSPI6SOD.js} +37 -37
- package/dist/dist-CSPI6SOD.js.map +1 -0
- package/dist/{esm-BR8_7rhM.js → esm-HKeFfXOD.js} +2 -2
- package/dist/{esm-BR8_7rhM.js.map → esm-HKeFfXOD.js.map} +1 -1
- package/dist/index.d.ts +96 -42
- package/dist/index.js +191 -15
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +191 -14
- package/dist/mcp.js.map +1 -1
- package/package.json +1 -1
- package/dist/dist-CW8OlPkK.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createRequire as __seoCreateRequire } from 'node:module'; const require = __seoCreateRequire(import.meta.url);
|
|
2
|
-
import { n as version, t as load } from "./esm-
|
|
2
|
+
import { n as version, t as load } from "./esm-HKeFfXOD.js";
|
|
3
3
|
import { SEO_PROVIDER_API_VERSION } from "./provider-sdk.js";
|
|
4
4
|
import crypto$1, { createHash, randomUUID, sign } from "node:crypto";
|
|
5
5
|
import { z } from "zod";
|
|
@@ -38202,6 +38202,46 @@ async function saveResearch(store, key, saved) {
|
|
|
38202
38202
|
if (!store) return;
|
|
38203
38203
|
await store.put(key, JSON.stringify(saved), RESEARCH_TTL_SECONDS).catch(() => void 0);
|
|
38204
38204
|
}
|
|
38205
|
+
// packages/core/src/commands/research-installed.ts
|
|
38206
|
+
async function installedSerpResearch(provider, input, serp) {
|
|
38207
|
+
if (!serp) throw new CommandError("INVALID_INPUT", `${provider} is not a built-in provider. Here the providers are dataforseo and ahrefs; installed provider packages run only in the seo CLI and the local MCP server (seo mcp serve).`);
|
|
38208
|
+
if (input.keywords.length === 0) throw new CommandError("INVALID_INPUT", "serp needs keywords.");
|
|
38209
|
+
const keywords = input.keywords.slice(0, serpKeywords(input));
|
|
38210
|
+
const language = dataForSeoMarket(input.country, null).language_code;
|
|
38211
|
+
const missed = [];
|
|
38212
|
+
const warnings = [];
|
|
38213
|
+
let costMicros = 0;
|
|
38214
|
+
let partial = false;
|
|
38215
|
+
let depth = serpDepth(input);
|
|
38216
|
+
const rows = await eachKeyword(keywords, missed, async (keyword) => {
|
|
38217
|
+
const got = await serp({
|
|
38218
|
+
provider,
|
|
38219
|
+
keyword,
|
|
38220
|
+
country: input.country,
|
|
38221
|
+
language,
|
|
38222
|
+
device: input.device ?? "desktop",
|
|
38223
|
+
depth: serpDepth(input)
|
|
38224
|
+
});
|
|
38225
|
+
depth = Math.min(depth, got.depth);
|
|
38226
|
+
costMicros = costMicros === null || got.costMicros === null ? null : costMicros + got.costMicros;
|
|
38227
|
+
partial ||= got.partial;
|
|
38228
|
+
warnings.push(...got.warnings.map((warning) => `${keyword}: ${warning}`));
|
|
38229
|
+
return got.rows.map((row) => ({
|
|
38230
|
+
keyword,
|
|
38231
|
+
...row
|
|
38232
|
+
}));
|
|
38233
|
+
});
|
|
38234
|
+
const answered = new Set(rows.map((row) => row.keyword));
|
|
38235
|
+
if (depth < serpDepth(input)) warnings.unshift(`The package reads at most ${depth} results a keyword, so this read ${depth} of the ${serpDepth(input)} asked for.`);
|
|
38236
|
+
return {
|
|
38237
|
+
rows,
|
|
38238
|
+
costUsd: costMicros === null ? null : Number((costMicros / 1e6).toFixed(6)),
|
|
38239
|
+
partial,
|
|
38240
|
+
missed,
|
|
38241
|
+
noData: keywords.filter((keyword) => !missed.includes(keyword) && !answered.has(keyword)),
|
|
38242
|
+
warnings
|
|
38243
|
+
};
|
|
38244
|
+
}
|
|
38205
38245
|
// packages/core/src/commands/research.ts
|
|
38206
38246
|
const RESEARCH_ACTIONS = [
|
|
38207
38247
|
"keyword_metrics",
|
|
@@ -38218,7 +38258,7 @@ const RESEARCH_ACTIONS = [
|
|
|
38218
38258
|
"index_check"
|
|
38219
38259
|
];
|
|
38220
38260
|
const RESEARCH_PROVIDERS = ["dataforseo", "ahrefs"];
|
|
38221
|
-
const RESEARCH_HELP = `provider is optional: without it the call uses the saved key, DataForSEO when both are saved. The target is a domain (the whole site), a path ending in / such as example.com/blog/ (every URL under it), or one page; scope overrides that. keyword_metrics (keywords: volume, difficulty, CPC), keyword_ideas (up to 5 seed keywords: searches that contain each seed, by volume), ranked_keywords (target: keywords a site, subfolder or page ranks for, with the provider's traffic total for the whole target), top_pages (target: the pages with the most estimated organic traffic), serp (keywords, up to 5: the ranking pages with their organic position beside DataForSEO's rank_absolute, which also counts AI Overviews and other blocks, plus the AI Overview's sources; device desktop or mobile, DataForSEO only; each with its domain's authority: DataForSEO domain_rank 0 to 100, Ahrefs domain_rating; depth sets results per keyword, default 20; rows run position by position across the keywords), index_check (DataForSEO only; target: one page URL; keywords: up to 2 exact phrases from the page, default its H1 or title. Searches Google for site:<url> and each "<phrase>" on desktop and mobile, retries failed searches, treats Google's fallback to unrelated sites as no match, and says indexed, not found or unknown with each search's evidence; about $0.01 a page), serp_overlap (2 to 10 keywords: for each pair, how many of their top 10 pages and sites are the same, to decide one page or several; results without a real page are counted, not compared), competitors (target: domains that share keywords), backlinks (target: referring domains), pages_by_backlinks (target: the pages with the most referring domains), link_gap (target and 2 to 5 competitors: referring domains that link to two or more competitors and not the target, highest authority first, from each site's top 1,000 referring domains; costs one backlinks call per site), ai_answers (DataForSEO only; target: the site. Without keywords it takes the site’s top 10 chat-style and long questions from Search Console’s AI-shaped queries itself. With up to 10 questions in keywords it asks those instead, and the target can be any domain, such as a competitor's. Each answer row also lists the other sites it cites, and the notes rank them. Answers come from DataForSEO's queue: answers not ready after about 40 seconds are returned as tasks, already paid for; call again with the same target and those tasks to read them at no cost. It asks ChatGPT search, Google AI Mode and Google AI Overviews each one and says whether the answer cites or mentions the site. DataForSEO’s queue prices are about $0.0072 a question across the three engines, so about $0.07 a run: tell the person before running it). Rows with a domain, and the target, get a free Ahrefs domain_rating column. Numbers are provider estimates, not Search Console data.`;
|
|
38261
|
+
const RESEARCH_HELP = `provider is optional: without it the call uses the saved key, DataForSEO when both are saved. In the CLI and the local MCP server, serp can also use a provider package installed on this machine that supplies live search results: pass its id as provider. The target is a domain (the whole site), a path ending in / such as example.com/blog/ (every URL under it), or one page; scope overrides that. keyword_metrics (keywords: volume, difficulty, CPC), keyword_ideas (up to 5 seed keywords: searches that contain each seed, by volume), ranked_keywords (target: keywords a site, subfolder or page ranks for, with the provider's traffic total for the whole target), top_pages (target: the pages with the most estimated organic traffic), serp (keywords, up to 5: the ranking pages with their organic position beside DataForSEO's rank_absolute, which also counts AI Overviews and other blocks, plus the AI Overview's sources; device desktop or mobile, DataForSEO only; each with its domain's authority: DataForSEO domain_rank 0 to 100, Ahrefs domain_rating; depth sets results per keyword, default 20; rows run position by position across the keywords), index_check (DataForSEO only; target: one page URL; keywords: up to 2 exact phrases from the page, default its H1 or title. Searches Google for site:<url> and each "<phrase>" on desktop and mobile, retries failed searches, treats Google's fallback to unrelated sites as no match, and says indexed, not found or unknown with each search's evidence; about $0.01 a page), serp_overlap (2 to 10 keywords: for each pair, how many of their top 10 pages and sites are the same, to decide one page or several; results without a real page are counted, not compared), competitors (target: domains that share keywords), backlinks (target: referring domains), pages_by_backlinks (target: the pages with the most referring domains), link_gap (target and 2 to 5 competitors: referring domains that link to two or more competitors and not the target, highest authority first, from each site's top 1,000 referring domains; costs one backlinks call per site), ai_answers (DataForSEO only; target: the site. Without keywords it takes the site’s top 10 chat-style and long questions from Search Console’s AI-shaped queries itself. With up to 10 questions in keywords it asks those instead, and the target can be any domain, such as a competitor's. Each answer row also lists the other sites it cites, and the notes rank them. Answers come from DataForSEO's queue: answers not ready after about 40 seconds are returned as tasks, already paid for; call again with the same target and those tasks to read them at no cost. It asks ChatGPT search, Google AI Mode and Google AI Overviews each one and says whether the answer cites or mentions the site. DataForSEO’s queue prices are about $0.0072 a question across the three engines, so about $0.07 a run: tell the person before running it). Rows with a domain, and the target, get a free Ahrefs domain_rating column. Numbers are provider estimates, not Search Console data.`;
|
|
38222
38262
|
const GENERIC_PLATFORMS = [
|
|
38223
38263
|
"youtube.com",
|
|
38224
38264
|
"facebook.com",
|
|
@@ -38280,6 +38320,8 @@ async function runResearch(input, keys, options) {
|
|
|
38280
38320
|
const offset = input.offset ?? 0;
|
|
38281
38321
|
if (input.action === "ai_answers") throw new CommandError("INVALID_INPUT", "ai_answers runs on its own.");
|
|
38282
38322
|
const provider = chooseProvider(input.provider, keys);
|
|
38323
|
+
const builtIn = RESEARCH_PROVIDERS.includes(provider) ? provider : null;
|
|
38324
|
+
if (!builtIn && input.action !== "serp") throw new CommandError("INVALID_INPUT", `An installed provider answers serp only; ${input.action} needs a built-in provider.`);
|
|
38283
38325
|
if (input.action === "index_check") {
|
|
38284
38326
|
if (provider === "ahrefs") throw new CommandError("INVALID_INPUT", "index_check uses DataForSEO: it runs live Google searches, which Ahrefs does not offer.");
|
|
38285
38327
|
return runIndexCheck({
|
|
@@ -38312,20 +38354,23 @@ async function runResearch(input, keys, options) {
|
|
|
38312
38354
|
const store = options.store ?? workersResearchStore();
|
|
38313
38355
|
const key = await researchKey([
|
|
38314
38356
|
provider,
|
|
38315
|
-
|
|
38357
|
+
builtIn ? keys.get(KEY_HEADER[builtIn]) : null,
|
|
38316
38358
|
request
|
|
38317
38359
|
]);
|
|
38318
38360
|
const saved = await readResearch(store, key, limit);
|
|
38319
|
-
const result = saved?.result ?? await research(
|
|
38361
|
+
const result = saved?.result ?? (builtIn ? await research(builtIn, keys, {
|
|
38320
38362
|
...request,
|
|
38321
38363
|
limit
|
|
38322
|
-
})
|
|
38364
|
+
}) : await installedSerpResearch(provider, {
|
|
38365
|
+
...request,
|
|
38366
|
+
limit
|
|
38367
|
+
}, options.installedSerp));
|
|
38323
38368
|
if (!saved) await saveResearch(store, key, {
|
|
38324
38369
|
limit,
|
|
38325
38370
|
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
38326
38371
|
result
|
|
38327
38372
|
});
|
|
38328
|
-
const { rows: fetched, costUsd: paid, partial, missed, noData, floor, leftOut, available, siteTotal, rankFailed, compared, aiOverviews } = result;
|
|
38373
|
+
const { rows: fetched, costUsd: paid, partial, missed, noData, floor, leftOut, available, siteTotal, rankFailed, compared, aiOverviews, warnings } = result;
|
|
38329
38374
|
const costUsd = saved ? 0 : paid;
|
|
38330
38375
|
const order = new Map(request.keywords.map((word, index) => [word, index]));
|
|
38331
38376
|
const found = input.action === "serp" && request.keywords.length > 1 ? [...fetched].sort((a, b) => Number(a.position ?? 0) - Number(b.position ?? 0) || (order.get(String(a.keyword)) ?? 0) - (order.get(String(b.keyword)) ?? 0)) : fetched;
|
|
@@ -38354,18 +38399,19 @@ async function runResearch(input, keys, options) {
|
|
|
38354
38399
|
notes: [
|
|
38355
38400
|
`${provider} estimates, in the provider’s own units.`,
|
|
38356
38401
|
...compared ? [`Compared: ${compared.withPage} of ${compared.results} top results had a real page, so shared_pages counts only those; ${compared.results - compared.withPage} came back as Google redirect links and could not be compared by page. ${compared.withSite} had a known site for shared_sites. Unique pages and sites are counted per keyword.${compared.withPage < compared.results / 2 && provider === "dataforseo" ? " With this few pages, shared_pages cannot settle one page or several; provider ahrefs returns real pages." : ""}`] : [],
|
|
38357
|
-
...VOLUME_ACTIONS.includes(input.action) ? [`Volume model: ${VOLUME_MODEL[
|
|
38402
|
+
...VOLUME_ACTIONS.includes(input.action) && builtIn ? [`Volume model: ${VOLUME_MODEL[builtIn]} ${VOLUMES_DIFFER}`] : [],
|
|
38358
38403
|
...input.action === "serp" || input.action === "ranked_keywords" ? [positionNote(provider)] : [],
|
|
38359
38404
|
...aiOverviews?.length ? [aiOverviewNote(aiOverviews, request.keywords.length)] : input.action === "serp" && provider === "dataforseo" && rows.length ? ["No AI Overview on these results pages."] : [],
|
|
38360
38405
|
...perKeyword ? [`Results per keyword: ${Object.entries(perKeyword).map(([word, count]) => `${word} ${count}`).join(", ")}. Rows run position by position across the keywords.`] : [],
|
|
38361
|
-
...siteTotal ? [siteTotalNote(
|
|
38406
|
+
...siteTotal && builtIn ? [siteTotalNote(builtIn, siteTotal, rows.length)] : [],
|
|
38362
38407
|
...available !== void 0 && available > found.length ? [`Capped: ${provider} has ${available.toLocaleString("en-US")} rows for this; this read the first ${found.length.toLocaleString("en-US")} in its order.`] : [],
|
|
38363
38408
|
...!found.length && scope ? [emptyNote(provider, input.action)] : [],
|
|
38364
38409
|
...input.action === "serp" && provider === "dataforseo" ? [rankFailed ? "domain_rank is missing: the DataForSEO rank call failed, so it is unknown, not zero." : "domain_rank is DataForSEO's own authority score for the domain, 0 to 100. It is not Ahrefs' Domain Rating."] : [],
|
|
38365
38410
|
...input.action === "serp" && !drKey && provider === "dataforseo" ? ["No domain_rating column: Domain Rating by Ahrefs needs an Ahrefs key (or the hosted MCP at https://seoskill.dev/mcp, which adds it)."] : [],
|
|
38366
38411
|
...store && rated.rows.length > 50 ? ["The result is kept for a day, so the next pages, and the same rows in full, cost nothing more."] : [],
|
|
38367
|
-
...saved ? [`Read from the result saved at ${saved.savedAt}, at no new cost${paid ? ` (it cost $${paid} then)` : ""}. Results are kept for a day.`] : costUsd !== null ? [`DataForSEO cost: $${costUsd}.`] : [],
|
|
38368
|
-
...partial ? [
|
|
38412
|
+
...saved ? [`Read from the result saved at ${saved.savedAt}, at no new cost${paid ? ` (it cost $${paid} then)` : ""}. Results are kept for a day.`] : costUsd !== null ? [builtIn ? `DataForSEO cost: $${costUsd}.` : `Cost the ${provider} package reports: $${costUsd}.`] : [],
|
|
38413
|
+
...partial ? [`Partial: ${builtIn ? "DataForSEO" : provider} could not fetch some pages of results, so rows may be missing.`] : [],
|
|
38414
|
+
...warnings?.length ? [`${provider} warnings: ${warnings.join(" ")}`] : [],
|
|
38369
38415
|
...missed.length ? [`Partial: ${provider} failed for ${missed.join(", ")}, so those keywords have no rows. Ask for them again.`] : [],
|
|
38370
38416
|
...noData.length ? [noDataNote(provider, input.action, noData)] : [],
|
|
38371
38417
|
...byDr ? [rows.length > GAP_RATED ? `Sorted by Domain Rating for the top ${GAP_RATED} rows by DataForSEO rank; the ${rows.length - GAP_RATED} rows after them follow by rank, with no Domain Rating.` : "Sorted by Domain Rating, then DataForSEO rank."] : [],
|
|
@@ -38383,9 +38429,9 @@ async function runResearch(input, keys, options) {
|
|
|
38383
38429
|
action: input.action,
|
|
38384
38430
|
target: target || null,
|
|
38385
38431
|
scope,
|
|
38386
|
-
siteTotal: siteTotal ? {
|
|
38432
|
+
siteTotal: siteTotal && builtIn ? {
|
|
38387
38433
|
...siteTotal,
|
|
38388
|
-
model: TRAFFIC_MODEL[
|
|
38434
|
+
model: TRAFFIC_MODEL[builtIn]
|
|
38389
38435
|
} : null,
|
|
38390
38436
|
available: available ?? null,
|
|
38391
38437
|
country,
|
|
@@ -38400,6 +38446,7 @@ async function runResearch(input, keys, options) {
|
|
|
38400
38446
|
partial,
|
|
38401
38447
|
missedKeywords: missed,
|
|
38402
38448
|
noDataKeywords: noData,
|
|
38449
|
+
...warnings?.length ? { warnings } : {},
|
|
38403
38450
|
...input.action === "link_gap" ? {
|
|
38404
38451
|
competitors: input.competitors ?? [],
|
|
38405
38452
|
cutAt: floor ?? null,
|
|
@@ -38416,6 +38463,7 @@ async function runResearch(input, keys, options) {
|
|
|
38416
38463
|
};
|
|
38417
38464
|
}
|
|
38418
38465
|
function positionNote(provider) {
|
|
38466
|
+
if (provider !== "dataforseo" && provider !== "ahrefs") return `position is the organic position the ${provider} package reports (its rankGroup); rank_absolute is its rank among every block on the page, and type is featured_snippet for a featured snippet, which has no organic position.`;
|
|
38419
38467
|
return provider === "dataforseo" ? "position is the organic position: the nth organic link (DataForSEO rank_group). rank_absolute counts every block on the page from the top, AI Overviews, People Also Ask, videos and images included, so it is higher. A featured snippet has type featured_snippet and no organic position." : "position is the organic position: the nth row Ahrefs marks organic. ahrefs_position is Ahrefs' own position field, and type lists what each row is.";
|
|
38420
38468
|
}
|
|
38421
38469
|
function aiOverviewNote(overviews, keywords) {
|
|
@@ -39403,7 +39451,7 @@ const SHARED_TOOLS = [
|
|
|
39403
39451
|
title: "Keyword, competitor, backlink and AI answer data",
|
|
39404
39452
|
description: `Data from the person’s own DataForSEO or Ahrefs account, which costs them credits. It uses the key the person saved on their seoskill.dev account (or on this machine for the CLI). Actions: ${RESEARCH_HELP}`,
|
|
39405
39453
|
input: z.object({
|
|
39406
|
-
provider: z.
|
|
39454
|
+
provider: z.string().max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).optional().describe(`${RESEARCH_PROVIDERS.join(" or ")}. Optional: without it, the saved key; DataForSEO when both are saved. For serp in the CLI and the local MCP server it can also be the id of an installed provider package with live search results.`),
|
|
39407
39455
|
action: z.enum(RESEARCH_ACTIONS),
|
|
39408
39456
|
keywords: z.array(z.string().min(1)).max(100).default([]),
|
|
39409
39457
|
target: z.string().default("").describe("Domain (the whole site), a path ending in / for every URL under it, such as example.com/blog/, or one page."),
|
|
@@ -39420,7 +39468,7 @@ const SHARED_TOOLS = [
|
|
|
39420
39468
|
run: async (surface, input) => {
|
|
39421
39469
|
const more = (offset) => `seo_research with the same input, detail "rows", offset ${offset}`;
|
|
39422
39470
|
if (input.action === "ai_answers") {
|
|
39423
|
-
if (input.provider
|
|
39471
|
+
if (input.provider && input.provider !== "dataforseo") throw new CommandError("INVALID_INPUT", "ai_answers uses dataforseo.");
|
|
39424
39472
|
return runAiAnswers({
|
|
39425
39473
|
site: input.keywords.length || input.tasks.length ? input.target : await surface.resolveSite(input.target),
|
|
39426
39474
|
country: input.country,
|
|
@@ -39435,6 +39483,7 @@ const SHARED_TOOLS = [
|
|
|
39435
39483
|
return runResearch(input, await surface.keys(), {
|
|
39436
39484
|
drKey: surface.drKey,
|
|
39437
39485
|
store: surface.researchStore,
|
|
39486
|
+
installedSerp: surface.installedSerp,
|
|
39438
39487
|
call: more
|
|
39439
39488
|
});
|
|
39440
39489
|
}
|
|
@@ -41314,6 +41363,133 @@ async function uninstallProviderExtension(id, options = {}) {
|
|
|
41314
41363
|
], { cwd: packagesDir });
|
|
41315
41364
|
return removeInstalledProviderPackage(id);
|
|
41316
41365
|
}
|
|
41366
|
+
// packages/core/src/provider-extensions/serp.ts
|
|
41367
|
+
const nullableText = z.string().max(5e4).nullable();
|
|
41368
|
+
const serpSnapshotResultSchema = z.object({
|
|
41369
|
+
observedAt: z.string().max(100),
|
|
41370
|
+
effectiveKeyword: z.string().trim().min(1).max(1e3),
|
|
41371
|
+
searchEngineDomain: z.string().max(253).nullable(),
|
|
41372
|
+
checkUrl: z.url().max(8192).nullable(),
|
|
41373
|
+
resultCount: z.number().int().nonnegative().safe().nullable(),
|
|
41374
|
+
pagesCount: z.number().int().nonnegative().max(100).safe().nullable(),
|
|
41375
|
+
features: z.array(z.string().trim().min(1).max(100)).max(100),
|
|
41376
|
+
organicResults: z.array(z.object({
|
|
41377
|
+
rankGroup: z.number().int().positive().safe(),
|
|
41378
|
+
rankAbsolute: z.number().int().positive().safe(),
|
|
41379
|
+
page: z.number().int().positive().max(100).safe(),
|
|
41380
|
+
domain: z.string().trim().min(1).max(253),
|
|
41381
|
+
url: z.url().max(8192),
|
|
41382
|
+
title: z.string().max(1e4).nullable(),
|
|
41383
|
+
description: nullableText,
|
|
41384
|
+
isFeaturedSnippet: z.boolean().nullable()
|
|
41385
|
+
}).strict()).max(100),
|
|
41386
|
+
localPack: z.object({
|
|
41387
|
+
present: z.boolean(),
|
|
41388
|
+
returnedRows: z.number().int().nonnegative().max(100).safe(),
|
|
41389
|
+
retainedRows: z.number().int().nonnegative().max(100).safe(),
|
|
41390
|
+
invalidRows: z.number().int().nonnegative().max(100).safe(),
|
|
41391
|
+
results: z.array(z.unknown()).max(100)
|
|
41392
|
+
}).strict(),
|
|
41393
|
+
coverage: z.object({
|
|
41394
|
+
returnedRows: z.number().int().nonnegative().max(1e4).safe(),
|
|
41395
|
+
retainedRows: z.number().int().nonnegative().max(100).safe(),
|
|
41396
|
+
invalidRows: z.number().int().nonnegative().max(1e4).safe(),
|
|
41397
|
+
providerTotalRows: z.number().int().nonnegative().safe().nullable(),
|
|
41398
|
+
completeness: z.enum([
|
|
41399
|
+
"complete",
|
|
41400
|
+
"partial",
|
|
41401
|
+
"capped"
|
|
41402
|
+
]),
|
|
41403
|
+
nextCursor: z.string().max(500).nullable()
|
|
41404
|
+
}).strict(),
|
|
41405
|
+
request: z.object({
|
|
41406
|
+
endpoint: z.string().trim().min(1).max(500),
|
|
41407
|
+
filters: z.record(z.string().min(1).max(100), z.union([
|
|
41408
|
+
z.string().max(1e3),
|
|
41409
|
+
z.number().finite(),
|
|
41410
|
+
z.boolean()
|
|
41411
|
+
])),
|
|
41412
|
+
sort: z.array(z.string().min(1).max(200)).max(20)
|
|
41413
|
+
}).strict(),
|
|
41414
|
+
cost: z.object({
|
|
41415
|
+
estimatedMicros: z.number().int().nonnegative().safe().nullable(),
|
|
41416
|
+
actualMicros: z.number().int().nonnegative().safe().nullable(),
|
|
41417
|
+
taskIds: z.array(z.string().min(1).max(500)).max(20),
|
|
41418
|
+
native: z.object({
|
|
41419
|
+
unit: z.string().trim().min(1).max(100),
|
|
41420
|
+
estimatedUnits: z.number().finite().nonnegative().nullable(),
|
|
41421
|
+
actualUnits: z.number().finite().nonnegative().nullable(),
|
|
41422
|
+
remainingBefore: z.number().finite().nonnegative().nullable()
|
|
41423
|
+
}).strict().optional()
|
|
41424
|
+
}).strict(),
|
|
41425
|
+
qualityWarnings: z.array(z.object({
|
|
41426
|
+
code: z.string().trim().min(1).max(100),
|
|
41427
|
+
message: z.string().trim().min(1).max(500),
|
|
41428
|
+
field: z.string().max(200).optional(),
|
|
41429
|
+
row: z.number().int().positive().safe().optional()
|
|
41430
|
+
}).strict()).max(50)
|
|
41431
|
+
}).strict();
|
|
41432
|
+
const same = (list, value) => !list || list.some((item) => item.toLowerCase() === value.toLowerCase());
|
|
41433
|
+
function supports(capability, market) {
|
|
41434
|
+
return capability.markets.some((entry) => same(entry.searchEngines, market.searchEngine) && same(entry.countryCodes, market.countryCode) && same(entry.languageCodes, market.languageCode) && same(entry.devices, market.device ?? "desktop"));
|
|
41435
|
+
}
|
|
41436
|
+
const installedProviderSerp = async (input) => {
|
|
41437
|
+
const loaded = await loadProviderExtensions();
|
|
41438
|
+
const provider = loaded.registry.get(input.provider);
|
|
41439
|
+
if (!provider) throw new CommandError("INVALID_INPUT", `No provider ${input.provider} is installed. The built-in providers are dataforseo and ahrefs; \`seo providers list\` shows installed packages.`);
|
|
41440
|
+
const capability = loaded.registry.capability(provider.id, "serp-snapshot");
|
|
41441
|
+
if (!capability) throw new CommandError("INVALID_INPUT", `${provider.displayName} has no live search results (serp-snapshot), so it cannot answer serp. \`seo providers describe ${provider.id}\` lists its own actions.`);
|
|
41442
|
+
const market = {
|
|
41443
|
+
searchEngine: "google",
|
|
41444
|
+
countryCode: input.country.toUpperCase(),
|
|
41445
|
+
languageCode: input.language,
|
|
41446
|
+
device: input.device
|
|
41447
|
+
};
|
|
41448
|
+
if (!supports(capability, market)) throw new CommandError("INVALID_INPUT", `${provider.displayName} has no ${input.device} Google results for country ${input.country} in language ${input.language}.`);
|
|
41449
|
+
let account;
|
|
41450
|
+
let credentials;
|
|
41451
|
+
try {
|
|
41452
|
+
account = normalizeProviderExtensionAccount(provider, readProviderExtensionAccount(provider.id));
|
|
41453
|
+
credentials = await readProviderExtensionCredentials({
|
|
41454
|
+
providerId: provider.id,
|
|
41455
|
+
account,
|
|
41456
|
+
fields: provider.connection.fields
|
|
41457
|
+
});
|
|
41458
|
+
} catch (error) {
|
|
41459
|
+
throw new CommandError("NO_KEY", `${error instanceof Error ? error.message : String(error)} Connect it with \`seo providers connect ${provider.id}\`.`);
|
|
41460
|
+
}
|
|
41461
|
+
const depth = Math.min(input.depth, capability.maxDepth);
|
|
41462
|
+
let raw;
|
|
41463
|
+
try {
|
|
41464
|
+
raw = await capability.run({
|
|
41465
|
+
account,
|
|
41466
|
+
credentials,
|
|
41467
|
+
keyword: input.keyword,
|
|
41468
|
+
market,
|
|
41469
|
+
depth
|
|
41470
|
+
}, runtimeForProvider(provider.id, { maxRequests: capability.maxRequests }));
|
|
41471
|
+
} catch (error) {
|
|
41472
|
+
throw new CommandError("PROVIDER_ERROR", safeProviderAdapterError(provider.id, error, credentials).message);
|
|
41473
|
+
}
|
|
41474
|
+
const parsed = serpSnapshotResultSchema.safeParse(raw);
|
|
41475
|
+
if (!parsed.success) throw new CommandError("PROVIDER_ERROR", `${provider.displayName} returned a results page that does not match the serp-snapshot shape.`);
|
|
41476
|
+
const result = parsed.data;
|
|
41477
|
+
const warnings = result.qualityWarnings.map((warning) => warning.message);
|
|
41478
|
+
return {
|
|
41479
|
+
rows: [...result.organicResults].sort((a, b) => a.rankAbsolute - b.rankAbsolute || (a.url < b.url ? -1 : 1)).map((item) => ({
|
|
41480
|
+
position: item.isFeaturedSnippet ? null : item.rankGroup,
|
|
41481
|
+
rank_absolute: item.rankAbsolute,
|
|
41482
|
+
type: item.isFeaturedSnippet ? "featured_snippet" : "organic",
|
|
41483
|
+
url: item.url,
|
|
41484
|
+
domain: item.domain,
|
|
41485
|
+
title: item.title
|
|
41486
|
+
})),
|
|
41487
|
+
costMicros: result.cost.actualMicros,
|
|
41488
|
+
partial: result.coverage.completeness === "partial",
|
|
41489
|
+
warnings,
|
|
41490
|
+
depth
|
|
41491
|
+
};
|
|
41492
|
+
};
|
|
41317
41493
|
// packages/core/src/providers/ahrefs/schema.ts
|
|
41318
41494
|
const ahrefsLimitsAndUsageResponseSchema = z.object({ limits_and_usage: z.object({
|
|
41319
41495
|
api_key_expiration_date: z.string().trim().min(1).max(100),
|
|
@@ -42363,6 +42539,6 @@ function isoDate(daysAgo = 0) {
|
|
|
42363
42539
|
date.setUTCDate(date.getUTCDate() - daysAgo);
|
|
42364
42540
|
return date.toISOString().slice(0, 10);
|
|
42365
42541
|
}
|
|
42366
|
-
export { AHREFS_API_KEY_ENV, AHREFS_API_KEY_SECRET, AI_REFERRAL_SOURCES, AI_REFERRAL_SOURCES_VERSION, ANALYTICS_PROVIDER_IDS, AUDIT_PAGE_RULE_IDS, AhrefsClient, BING_API_KEY_ENV, BING_API_KEY_SECRET, BROWSER_USER_AGENT, CANNIBAL_MAXIMUM_DOMINANT_SHARE, CANNIBAL_MINIMUM_PAGE_IMPRESSIONS, CANNIBAL_MINIMUM_PAGE_SHARE, CLICKY_SITEKEY_ENV, CLICKY_SITE_KEYS_SECRET, CLOUD_SIGN_IN, CLOUD_URL, CRAWL_SKIP_REASONS, CTR_DEFAULT_LIMIT, CTR_MAX_LIMIT, CTR_MAX_MIN_IMPRESSIONS, DATAFORSEO_CREDENTIAL_SECRET, DATAFORSEO_LOGIN_ENV, DATAFORSEO_PASSWORD_ENV, DEFAULT_MAX_PAGES, DEFAULT_SEARCH_CONSOLE_EXPORT_ROW_LIMIT, DEFAULT_UNREACHED_PAGE_LIMIT, DataForSeoClient, DecisionModelError, DecisionRunner, GOOGLE_TIMEOUT_MS, GSC_FINAL_DATA_LAG_DAYS, GSC_TIME_ZONE, GoogleApiError, INCIDENTS_URL, JsonFileStorageAdapter, LINK_ROLES, LINT_MAX_FILES, LOCAL_BING_CONNECT, LOCAL_SIGN_IN, LOG_MAX_AGE_MS, LOG_MAX_FILE_BYTES, LOG_MAX_TOTAL_BYTES, LocalCredentialsProvider, MANAGED_PROVIDER_SECRET_NAMES, MAX_CRAWL_CONCURRENCY, MAX_CRAWL_DEPTH, MAX_CRAWL_PAGES, MAX_CRAWL_TIMEOUT_MS, MAX_MAX_PAGES, MAX_SEARCH_CONSOLE_EXPORT_FILES, MAX_SEARCH_CONSOLE_EXPORT_ROW_LIMIT, PAGE_TYPES, PROVIDER_ERROR_CODES, PROVIDER_SECRET_NAMES, ProviderError, ProviderExtensionRegistry, RESEARCH_IMPORT_COLUMN_KEYS, ResponseSizeLimitError, SEARCH_INTENTS, SEO_CRAWLER_IDENTITY, SEO_CRAWLER_TOKEN, SEO_CRAWLER_USER_AGENT, SEO_PROVIDER_API_VERSION, SEO_VERSION, SERP_TITLE_REFERENCE_WIDTH_PX, SERP_TITLE_WIDTH_PROFILE, SITEMAP_FILE_URL_LIMIT, SITE_CHECK_MAX_ISSUES, SITE_CHECK_MAX_PAGES, SITE_FACTS_DEFAULT_CONCURRENCY, SITE_FACTS_MAX_CONCURRENCY, SITE_FACTS_MAX_SITES, SITE_FACTS_TIMEOUT_MS, STEP_CHANGE_RULES, SeoError, ServiceAccountAccessTokenClient, SessionLedger, TELEMETRY_AGENTS, TELEMETRY_ENDPOINT, TELEMETRY_ERROR_CATEGORIES, TELEMETRY_EVENTS, TELEMETRY_FAILURE_CONTEXTS, TELEMETRY_FAILURE_REASONS, TELEMETRY_NOTICE, TELEMETRY_OPERATIONS, TELEMETRY_REPORTS, TELEMETRY_SCHEMA_VERSION, TELEMETRY_TIMEOUT_MS, TYPESAFE_API_KEY_ENV, URL_INSPECTION_TIMEOUT_MS, agentActionsView, aiReferralSourceForValue, aiReferralsReport, analyticsConnectionLabel, analyticsConnectionProviderId, analyticsConnectionSchema, analyticsProviderDetails, analyticsProviderSchema, analyzeAiReferralRows, analyzeCannibalImportRows, analyzeCannibalRows, analyzeCtrUnderperformersFromRows, analyzeDecay, analyzeIndexCoverageSignals, analyzePageOpportunitiesFromRows, analyzeQueryClustersFromRows, analyzeQuickWinsFromRows, analyzeSecondPageRows, analyzeSegmentRows, analyzeStrikingDistanceRows, analyzeTrafficAnomalyRows, assertCrawlConfigLimits, assertUrlMatchesGscProperty, auditCrawlPages, auditCrawlRequests, auditPage, authStatus, bearerFetch, boundedSitemapInventory, buildAgentFindings, buildQueryClusterReportFromRows, buildTelemetryPayload, builtPagePath, cacheDb, cannibalDataStatus, cannibalImportReport, cannibalReport, cannibalReportWith, changeWindow, checkBuiltSite, checkDatabaseReadiness, checkSites, classifyTelemetryFailure, clearCache, cloudAccountFor, cloudBing, cloudCredentials, cloudGoogleEmails, cloudGoogleToken, cloudKeys, cloudLinked, cloudLogout, cloudWeek, clusterQueryRows, combineRobotsValues, compareSegmentRows, configSchema, contentCoverageRecommendation, contentCoverageType, contentOptimizationFromPageOpportunities, contentOptimizationReport, countLabel, crawlConfigHash, crawlConfigSchema, crawlCoverageCaveat, crawlDefinitionId, crawlFixToQueueItem, crawlImplementationQueueWorkflow, crawlIssueGroupSchema, crawlIssueSchema, crawlOne, crawlPageSnapshotSchema, crawlReportSchema, crawlReportSummarySchema, crawlRequestObservationSchema, crawlRunId, crawlSite, crawlSkipImpact, crawlSkipReasonCountsFromRecord, crawlStatusOnly, crawlTopFixSchema, crawlerJsonSchemas, crawlerRuleCategorySchema, crawlerRuleIdSchema, crawlerRuleInfoSchema, crawlerRuleRecommendationSchema, crawlerRuleSeveritySchema, crawlerSchemas, createAuthorizedClient, createCrawlReport, createCtrBenchmarkContext, createGoogleAccessTokenClient, createLogger, createPageRenderer, ctrUnderperformersReport, ctrUnderperformersReportWith, decayClusterDrafts, decayComparisonRange, decayingReport, decayingReportWith, deleteAhrefsApiKey, deleteBingApiKey, deleteClickySiteKey, deleteDataForSeoCredentials, deleteManagedProviderSecrets, deleteProviderExtensionAccount, deleteProviderExtensionCredentials, deleteProviderSecret, deleteTokens, deriveBrandTerms, describeInstalledProviderExtension, detectAgentName, detectBrandTerms, detectTelemetryAgent, diagnoseCsvFiles, diagnoseProperty, diagnosePropertyWorkflow, effectiveRobotsDirectives, effectiveSnippetControl, ensurePrivateDatabaseFiles, ensureSeoCliDirs, estimateSerpTitleWidth, expectedCtrForPosition, explainRule, fetchCruxFieldData, fetchFailureKind, fetchPage, fetchPageStatus, fetchSearchStatusIncidents, fetchSitemapUrls, fileSize, finalGscDateRange, findOverlappingSearchUpdates, finishCloudLogin, formatRelativeExpiry, ga4MatchReason, ga4PropertyIdFromName, ga4ReportQualityWarnings, ga4RequestCanUseCache, ga4RowsToObjects, getAuthModeStatus, getCacheStats, getClientConfig, getDb, getPrivacySnapshot, getSeoCliPaths, getServiceAccountConfig, getServiceAccountStatus, getTelemetryStatus, getTokenStorageStatus, googleJson, groupCrawlIssues, hasMetaRobotsDirective, hasRule, hasXRobotsDirective, hashKey, indexCoverageSignals, inferTemplateMovement, initializeTelemetry, inspectProviderPackage, inspectSearchConsoleUrl, inspectUrl, installProviderPackage, installedProviderPackageSchema, installedProviderPackagesSchema, internalLinksReport, internalLinksReportWith, interpretUpdateCorrelation, isBrandQuery, isNewerVersion, isSkippableReportError, isTelemetryCi, isTelemetryOperation, isTelemetryReport, isoDate, isoWeek, latestFinalGscDate, linkRecover, linkRecoverRecommendation, lintPaths, listAnalyticsAccounts, listAnalyticsDataStreams, listGa4AccountSummaries, listGa4DataStreams, listGoogleAccounts, listInstalledProviderExtensions, listRules, listSearchConsoleSites, listSearchUpdates, listSites, loadInstalledProviderExtensions, loadProviderExtensions, loadProviderPackage, loadSearchConsoleExport, localAccounts, localBing, localCredentialsProvider, localError, localGoogleFetch, localInternalLinksDependencies, localRefreshClicky, localResearchKeys, localResearchStore, loginWithLoopback, makeRunId, matchGa4WebStreams, measureCoverage, metaRobotsDirectives, migrateLegacyMacConfig, missingOAuthClientMessage, missingSharedClientLoginMessage, nodeCommandDeps, normalizeBrandText, normalizeClickySiteId, normalizeClickySiteKey, normalizeCrawlConfig, normalizeCrawlSkipReasonCounts, normalizeForCoverage, normalizeHttpUrl, normalizeJavaScriptRenderingMode, normalizeLoadedCrawlReport, normalizeProviderExtensionAccount, normalizedResearchColumnName, notSignedIn, noteCacheWrite, openCloudLink, pageEvidenceRecommendation, pageOpportunitiesReport, parseOlderThan, pendingCloudLogin, performanceAudit, performanceReportIsCacheable, plural, providerCapabilitySchema, providerConnectionFieldSchema, providerExactVersionSchema, providerExtensionIdSchema, providerIdSchema, providerIntegritySchema, providerKindSchema, providerPackageManifestSchema, providerPackageNameSchema, providerPreferenceSchema, providerRegistrationSchema, providerRequestJson, providerRequestText, pruneLogs, publicHttpFetch, queryClusterReport, queryClusterTokens, queryContentCoverageFromPage, queryContentFieldsFromPage, queryFieldCoverage, queryOpportunityRecommendation, queryPageMetrics, queryPageTopQuery, queryPagesMetrics, queryPagesMetricsBatch, queryPagesTopQueries, queryPagesTopQueriesBatch, querySearchAnalytics, quickWinsCsvRows, quickWinsReport, quickWinsReportWith, readAhrefsApiKey, readAllTokens, readBingApiKey, readBoundedResponseText, readClickySiteKey, readClickySiteKeys, readConfig, readDataForSeoCredentials, readInstalledProviderPackages, readJson, readJsonOrUndefined, readLintFiles, readOauthClient, readProviderExtensionAccount, readProviderExtensionCredentials, readProviderSecret, readTokens, recommendationForRule, reconcileExportPagesWithCrawl, redirectTrace, refreshAuthToken, refreshPrioritiesCsvFiles, refreshPrioritiesWorkflow, registrableDomain, removeInstalledProviderPackage, renderCrawlCsv, renderCrawlHtml, renderCrawlJunit, renderCrawlMarkdownTickets, renderCrawlPagesCsv, renderCrawlPretty, renderCsv, renderPresentationTablesMarkdown, renderWorkflowMarkdown, reportNarrative, requestHeaders, requirePageVerification, researchImportColumns, resetSeoData, resolveLocalSite, resolveSegmentRanges, resolveSeoCliPaths, reviewObservations, roundedPosition, runAnalyticsProviderLandingPages, runAnalyticsReport, runDoctor, runGa4Report, runProviderExtensionAction, runtimeForProvider, safeProviderAdapterError, saveInstalledProviderPackage, searchAnalyticsRows, searchUpdatesFromIncidents, secondPage, secondPageWith, segmentComparisonRange, segmentImpact, segmentRangeDays, seoErrorEnvelope, sessionSourceInListFilter, setActiveGoogleAccount, setTelemetryEnabled, setTokenStorageMode, shiftIsoDate, shouldExcludeBrandQuery, siteStartUrl, snapshotFetchedPage, startCloudLogin, strikingDistance, strikingDistanceWith, summarizeCrawlReport, pageTechnicalSignals as technicalPageSignals, telemetryErrorCategory, toSeoError, tokenSchema, tokenStoreSchema, topFixes, trackTelemetryCommandFailed, trackTelemetryReportComplete, trackTelemetryReportFailed, trackTelemetryReportStart, trackTelemetrySetupComplete, trafficAnomaly, trafficAnomalyWith, typesafeDecisionModel, unavailableSegmentImpactReport, unicodeTokens, uninstallProviderExtension, updateCorrelation, updateNotice, updatePostmortemCsvFiles, updatePostmortemWorkflow, urlInspectionQuota, validateResearchImportColumnSources, verifyAnalyticsProvider, verifyProviderExtension, verifyQueryContent, verifyQueryContentWith, withAgentReportContract, withRankingHistory, withinGoogleTimeout, workflowPresentation, writeAhrefsApiKey, writeBingApiKey, writeClickySiteKey, writeConfig, writeDataForSeoCredentials, writeInstalledProviderPackages, writeOauthClient, writeProviderExtensionAccount, writeProviderExtensionCredentials, writeProviderSecret, writeToCache, writeTokens, xRobotsDirectives };
|
|
42542
|
+
export { AHREFS_API_KEY_ENV, AHREFS_API_KEY_SECRET, AI_REFERRAL_SOURCES, AI_REFERRAL_SOURCES_VERSION, ANALYTICS_PROVIDER_IDS, AUDIT_PAGE_RULE_IDS, AhrefsClient, BING_API_KEY_ENV, BING_API_KEY_SECRET, BROWSER_USER_AGENT, CANNIBAL_MAXIMUM_DOMINANT_SHARE, CANNIBAL_MINIMUM_PAGE_IMPRESSIONS, CANNIBAL_MINIMUM_PAGE_SHARE, CLICKY_SITEKEY_ENV, CLICKY_SITE_KEYS_SECRET, CLOUD_SIGN_IN, CLOUD_URL, CRAWL_SKIP_REASONS, CTR_DEFAULT_LIMIT, CTR_MAX_LIMIT, CTR_MAX_MIN_IMPRESSIONS, DATAFORSEO_CREDENTIAL_SECRET, DATAFORSEO_LOGIN_ENV, DATAFORSEO_PASSWORD_ENV, DEFAULT_MAX_PAGES, DEFAULT_SEARCH_CONSOLE_EXPORT_ROW_LIMIT, DEFAULT_UNREACHED_PAGE_LIMIT, DataForSeoClient, DecisionModelError, DecisionRunner, GOOGLE_TIMEOUT_MS, GSC_FINAL_DATA_LAG_DAYS, GSC_TIME_ZONE, GoogleApiError, INCIDENTS_URL, JsonFileStorageAdapter, LINK_ROLES, LINT_MAX_FILES, LOCAL_BING_CONNECT, LOCAL_SIGN_IN, LOG_MAX_AGE_MS, LOG_MAX_FILE_BYTES, LOG_MAX_TOTAL_BYTES, LocalCredentialsProvider, MANAGED_PROVIDER_SECRET_NAMES, MAX_CRAWL_CONCURRENCY, MAX_CRAWL_DEPTH, MAX_CRAWL_PAGES, MAX_CRAWL_TIMEOUT_MS, MAX_MAX_PAGES, MAX_SEARCH_CONSOLE_EXPORT_FILES, MAX_SEARCH_CONSOLE_EXPORT_ROW_LIMIT, PAGE_TYPES, PROVIDER_ERROR_CODES, PROVIDER_SECRET_NAMES, ProviderError, ProviderExtensionRegistry, RESEARCH_IMPORT_COLUMN_KEYS, ResponseSizeLimitError, SEARCH_INTENTS, SEO_CRAWLER_IDENTITY, SEO_CRAWLER_TOKEN, SEO_CRAWLER_USER_AGENT, SEO_PROVIDER_API_VERSION, SEO_VERSION, SERP_TITLE_REFERENCE_WIDTH_PX, SERP_TITLE_WIDTH_PROFILE, SITEMAP_FILE_URL_LIMIT, SITE_CHECK_MAX_ISSUES, SITE_CHECK_MAX_PAGES, SITE_FACTS_DEFAULT_CONCURRENCY, SITE_FACTS_MAX_CONCURRENCY, SITE_FACTS_MAX_SITES, SITE_FACTS_TIMEOUT_MS, STEP_CHANGE_RULES, SeoError, ServiceAccountAccessTokenClient, SessionLedger, TELEMETRY_AGENTS, TELEMETRY_ENDPOINT, TELEMETRY_ERROR_CATEGORIES, TELEMETRY_EVENTS, TELEMETRY_FAILURE_CONTEXTS, TELEMETRY_FAILURE_REASONS, TELEMETRY_NOTICE, TELEMETRY_OPERATIONS, TELEMETRY_REPORTS, TELEMETRY_SCHEMA_VERSION, TELEMETRY_TIMEOUT_MS, TYPESAFE_API_KEY_ENV, URL_INSPECTION_TIMEOUT_MS, agentActionsView, aiReferralSourceForValue, aiReferralsReport, analyticsConnectionLabel, analyticsConnectionProviderId, analyticsConnectionSchema, analyticsProviderDetails, analyticsProviderSchema, analyzeAiReferralRows, analyzeCannibalImportRows, analyzeCannibalRows, analyzeCtrUnderperformersFromRows, analyzeDecay, analyzeIndexCoverageSignals, analyzePageOpportunitiesFromRows, analyzeQueryClustersFromRows, analyzeQuickWinsFromRows, analyzeSecondPageRows, analyzeSegmentRows, analyzeStrikingDistanceRows, analyzeTrafficAnomalyRows, assertCrawlConfigLimits, assertUrlMatchesGscProperty, auditCrawlPages, auditCrawlRequests, auditPage, authStatus, bearerFetch, boundedSitemapInventory, buildAgentFindings, buildQueryClusterReportFromRows, buildTelemetryPayload, builtPagePath, cacheDb, cannibalDataStatus, cannibalImportReport, cannibalReport, cannibalReportWith, changeWindow, checkBuiltSite, checkDatabaseReadiness, checkSites, classifyTelemetryFailure, clearCache, cloudAccountFor, cloudBing, cloudCredentials, cloudGoogleEmails, cloudGoogleToken, cloudKeys, cloudLinked, cloudLogout, cloudWeek, clusterQueryRows, combineRobotsValues, compareSegmentRows, configSchema, contentCoverageRecommendation, contentCoverageType, contentOptimizationFromPageOpportunities, contentOptimizationReport, countLabel, crawlConfigHash, crawlConfigSchema, crawlCoverageCaveat, crawlDefinitionId, crawlFixToQueueItem, crawlImplementationQueueWorkflow, crawlIssueGroupSchema, crawlIssueSchema, crawlOne, crawlPageSnapshotSchema, crawlReportSchema, crawlReportSummarySchema, crawlRequestObservationSchema, crawlRunId, crawlSite, crawlSkipImpact, crawlSkipReasonCountsFromRecord, crawlStatusOnly, crawlTopFixSchema, crawlerJsonSchemas, crawlerRuleCategorySchema, crawlerRuleIdSchema, crawlerRuleInfoSchema, crawlerRuleRecommendationSchema, crawlerRuleSeveritySchema, crawlerSchemas, createAuthorizedClient, createCrawlReport, createCtrBenchmarkContext, createGoogleAccessTokenClient, createLogger, createPageRenderer, ctrUnderperformersReport, ctrUnderperformersReportWith, decayClusterDrafts, decayComparisonRange, decayingReport, decayingReportWith, deleteAhrefsApiKey, deleteBingApiKey, deleteClickySiteKey, deleteDataForSeoCredentials, deleteManagedProviderSecrets, deleteProviderExtensionAccount, deleteProviderExtensionCredentials, deleteProviderSecret, deleteTokens, deriveBrandTerms, describeInstalledProviderExtension, detectAgentName, detectBrandTerms, detectTelemetryAgent, diagnoseCsvFiles, diagnoseProperty, diagnosePropertyWorkflow, effectiveRobotsDirectives, effectiveSnippetControl, ensurePrivateDatabaseFiles, ensureSeoCliDirs, estimateSerpTitleWidth, expectedCtrForPosition, explainRule, fetchCruxFieldData, fetchFailureKind, fetchPage, fetchPageStatus, fetchSearchStatusIncidents, fetchSitemapUrls, fileSize, finalGscDateRange, findOverlappingSearchUpdates, finishCloudLogin, formatRelativeExpiry, ga4MatchReason, ga4PropertyIdFromName, ga4ReportQualityWarnings, ga4RequestCanUseCache, ga4RowsToObjects, getAuthModeStatus, getCacheStats, getClientConfig, getDb, getPrivacySnapshot, getSeoCliPaths, getServiceAccountConfig, getServiceAccountStatus, getTelemetryStatus, getTokenStorageStatus, googleJson, groupCrawlIssues, hasMetaRobotsDirective, hasRule, hasXRobotsDirective, hashKey, indexCoverageSignals, inferTemplateMovement, initializeTelemetry, inspectProviderPackage, inspectSearchConsoleUrl, inspectUrl, installProviderPackage, installedProviderPackageSchema, installedProviderPackagesSchema, installedProviderSerp, internalLinksReport, internalLinksReportWith, interpretUpdateCorrelation, isBrandQuery, isNewerVersion, isSkippableReportError, isTelemetryCi, isTelemetryOperation, isTelemetryReport, isoDate, isoWeek, latestFinalGscDate, linkRecover, linkRecoverRecommendation, lintPaths, listAnalyticsAccounts, listAnalyticsDataStreams, listGa4AccountSummaries, listGa4DataStreams, listGoogleAccounts, listInstalledProviderExtensions, listRules, listSearchConsoleSites, listSearchUpdates, listSites, loadInstalledProviderExtensions, loadProviderExtensions, loadProviderPackage, loadSearchConsoleExport, localAccounts, localBing, localCredentialsProvider, localError, localGoogleFetch, localInternalLinksDependencies, localRefreshClicky, localResearchKeys, localResearchStore, loginWithLoopback, makeRunId, matchGa4WebStreams, measureCoverage, metaRobotsDirectives, migrateLegacyMacConfig, missingOAuthClientMessage, missingSharedClientLoginMessage, nodeCommandDeps, normalizeBrandText, normalizeClickySiteId, normalizeClickySiteKey, normalizeCrawlConfig, normalizeCrawlSkipReasonCounts, normalizeForCoverage, normalizeHttpUrl, normalizeJavaScriptRenderingMode, normalizeLoadedCrawlReport, normalizeProviderExtensionAccount, normalizedResearchColumnName, notSignedIn, noteCacheWrite, openCloudLink, pageEvidenceRecommendation, pageOpportunitiesReport, parseOlderThan, pendingCloudLogin, performanceAudit, performanceReportIsCacheable, plural, providerCapabilitySchema, providerConnectionFieldSchema, providerExactVersionSchema, providerExtensionIdSchema, providerIdSchema, providerIntegritySchema, providerKindSchema, providerPackageManifestSchema, providerPackageNameSchema, providerPreferenceSchema, providerRegistrationSchema, providerRequestJson, providerRequestText, pruneLogs, publicHttpFetch, queryClusterReport, queryClusterTokens, queryContentCoverageFromPage, queryContentFieldsFromPage, queryFieldCoverage, queryOpportunityRecommendation, queryPageMetrics, queryPageTopQuery, queryPagesMetrics, queryPagesMetricsBatch, queryPagesTopQueries, queryPagesTopQueriesBatch, querySearchAnalytics, quickWinsCsvRows, quickWinsReport, quickWinsReportWith, readAhrefsApiKey, readAllTokens, readBingApiKey, readBoundedResponseText, readClickySiteKey, readClickySiteKeys, readConfig, readDataForSeoCredentials, readInstalledProviderPackages, readJson, readJsonOrUndefined, readLintFiles, readOauthClient, readProviderExtensionAccount, readProviderExtensionCredentials, readProviderSecret, readTokens, recommendationForRule, reconcileExportPagesWithCrawl, redirectTrace, refreshAuthToken, refreshPrioritiesCsvFiles, refreshPrioritiesWorkflow, registrableDomain, removeInstalledProviderPackage, renderCrawlCsv, renderCrawlHtml, renderCrawlJunit, renderCrawlMarkdownTickets, renderCrawlPagesCsv, renderCrawlPretty, renderCsv, renderPresentationTablesMarkdown, renderWorkflowMarkdown, reportNarrative, requestHeaders, requirePageVerification, researchImportColumns, resetSeoData, resolveLocalSite, resolveSegmentRanges, resolveSeoCliPaths, reviewObservations, roundedPosition, runAnalyticsProviderLandingPages, runAnalyticsReport, runDoctor, runGa4Report, runProviderExtensionAction, runtimeForProvider, safeProviderAdapterError, saveInstalledProviderPackage, searchAnalyticsRows, searchUpdatesFromIncidents, secondPage, secondPageWith, segmentComparisonRange, segmentImpact, segmentRangeDays, seoErrorEnvelope, sessionSourceInListFilter, setActiveGoogleAccount, setTelemetryEnabled, setTokenStorageMode, shiftIsoDate, shouldExcludeBrandQuery, siteStartUrl, snapshotFetchedPage, startCloudLogin, strikingDistance, strikingDistanceWith, summarizeCrawlReport, pageTechnicalSignals as technicalPageSignals, telemetryErrorCategory, toSeoError, tokenSchema, tokenStoreSchema, topFixes, trackTelemetryCommandFailed, trackTelemetryReportComplete, trackTelemetryReportFailed, trackTelemetryReportStart, trackTelemetrySetupComplete, trafficAnomaly, trafficAnomalyWith, typesafeDecisionModel, unavailableSegmentImpactReport, unicodeTokens, uninstallProviderExtension, updateCorrelation, updateNotice, updatePostmortemCsvFiles, updatePostmortemWorkflow, urlInspectionQuota, validateResearchImportColumnSources, verifyAnalyticsProvider, verifyProviderExtension, verifyQueryContent, verifyQueryContentWith, withAgentReportContract, withRankingHistory, withinGoogleTimeout, workflowPresentation, writeAhrefsApiKey, writeBingApiKey, writeClickySiteKey, writeConfig, writeDataForSeoCredentials, writeInstalledProviderPackages, writeOauthClient, writeProviderExtensionAccount, writeProviderExtensionCredentials, writeProviderSecret, writeToCache, writeTokens, xRobotsDirectives };
|
|
42367
42543
|
|
|
42368
42544
|
//# sourceMappingURL=index.js.map
|