@gscdump/sdk 0.38.2 → 0.40.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 +5 -6
- package/dist/_chunks/query.d.mts +1 -1
- package/dist/index.d.mts +64 -85
- package/dist/index.mjs +174 -325
- package/dist/query.mjs +1 -5
- package/dist/v1/index.d.mts +14 -0
- package/dist/v1/index.mjs +48 -16
- package/package.json +5 -5
- package/dist/_chunks/rolldown-runtime.mjs +0 -25
package/README.md
CHANGED
|
@@ -3,10 +3,9 @@
|
|
|
3
3
|
Consumer SDK for hosted gscdump.com integrations.
|
|
4
4
|
|
|
5
5
|
> The descriptor-driven HTTP client and ticketed realtime state machine are
|
|
6
|
-
> exported from `@gscdump/sdk/v1`.
|
|
7
|
-
>
|
|
8
|
-
>
|
|
9
|
-
> not be used for a v1 browser integration. See the
|
|
6
|
+
> exported from `@gscdump/sdk/v1`. The root HTTP client remains a temporary
|
|
7
|
+
> compatibility surface during the release and cutover overlap; the unsafe
|
|
8
|
+
> long-lived-key realtime client was removed before v1. See the
|
|
10
9
|
> [v1 contract](../../docs/hosted-api-v1.md).
|
|
11
10
|
|
|
12
11
|
This package is for partner applications that consume gscdump.com APIs,
|
|
@@ -14,9 +13,9 @@ webhooks, and realtime events. Callers inject the HTTP transport and auth they
|
|
|
14
13
|
want to use; route construction stays inside the hosted adapter.
|
|
15
14
|
|
|
16
15
|
```ts
|
|
17
|
-
import {
|
|
16
|
+
import { createPartnerClient } from '@gscdump/sdk'
|
|
18
17
|
|
|
19
|
-
const gscdump =
|
|
18
|
+
const gscdump = createPartnerClient({
|
|
20
19
|
apiBase: 'https://example.com/api',
|
|
21
20
|
apiKey: process.env.GSCDUMP_API_KEY,
|
|
22
21
|
fetch: $fetch,
|
package/dist/_chunks/query.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import * as import_gscdump_query from "gscdump/query";
|
|
2
|
-
export {
|
|
2
|
+
export { __exportAll, __reExport, query_d_exports };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { query_d_exports } from "./_chunks/query.mjs";
|
|
1
|
+
import { __exportAll, __reExport, query_d_exports } from "./_chunks/query.mjs";
|
|
2
2
|
import { Result } from "gscdump/result";
|
|
3
|
-
import {
|
|
3
|
+
import { arbitrarySql as arbitrarySql$1, auxCloudOnly as auxCloudOnly$1, entityDailySparkline as entityDailySparkline$1, entityDailyTimeseries as entityDailyTimeseries$1, multiSeriesStackedDaily as multiSeriesStackedDaily$1, singleRowLookup as singleRowLookup$1, siteDailyTimeseries as siteDailyTimeseries$1, topNBreakdown as topNBreakdown$1, twoDimensionDetail as twoDimensionDetail$1 } from "@gscdump/contracts/archetypes";
|
|
4
|
+
import { AddPartnerTeamMemberParams, AnalyticsClient, AnalyticsClient as AnalyticsClient$1, BackfillRange, BackfillResponse, BindPartnerSiteTeamParams, BuilderState, BulkRegisterPartnerSiteResult, BulkRegisterPartnerSitesParams, BulkRegisterPartnerSitesResponse, CANONICAL_WEBHOOK_EVENTS, CanonicalWebhookEventType, CreatePartnerTeamParams, CreateWebhookEnvelopeOptions, DataDetailOptions, DataQueryOptions, DeletePartnerUserResponse, GscComparisonFilter, GscdumpAnalysisParams, GscdumpAnalysisPreset, GscdumpAnalysisResponse, GscdumpAnalysisSourcesResponse, GscdumpAvailableSite, GscdumpCanonicalMismatchesResponse, GscdumpDataDetailResponse, GscdumpDataResponse, GscdumpDataRow, GscdumpDateRangeParams, GscdumpIndexPercentResponse, GscdumpIndexingDiagnosticsResponse, GscdumpIndexingResponse, GscdumpIndexingUrlStatus, GscdumpIndexingUrlsResponse, GscdumpKeywordSparklinesParams, GscdumpKeywordSparklinesResponse, GscdumpMeta, GscdumpPageTrendParams, GscdumpPageTrendResponse, GscdumpPermissionRecovery, GscdumpQueryTrendParams, GscdumpQueryTrendResponse, GscdumpSiteRegistration, GscdumpSitemap, GscdumpSitemapChangesResponse, GscdumpSitemapHistory, GscdumpSitemapsResponse, GscdumpSyncStatusResponse, GscdumpSyncStatusResponse as GscdumpSyncStatusResponse$1, GscdumpTeamMemberRow, GscdumpTeamRow, GscdumpTopAssociationParams, GscdumpTopAssociationResponse, GscdumpTotals, GscdumpUserRegistration, GscdumpUserSettings, GscdumpUserSite, GscdumpUserSite as GscdumpUserSite$1, GscdumpUserStatus, GscdumpUserTokenUpdate, IndexingDiagnosticsParams, IndexingUrlsParams, InspectionHistoryResponse, InspectionIndex, PartnerClient, PartnerClient as PartnerClient$1, PartnerLifecycleAccount, PartnerLifecycleResponse, PartnerLifecycleSite, PartnerLifecycleSite as PartnerLifecycleSite$1, PartnerWebhookData, PartnerWebhookHeaders, PartnerWebhookHeaders as PartnerWebhookHeaders$1, RegisterPartnerSiteParams, RegisterPartnerUserParams, RollupEnvelope, SourceInfoOptions, UpdatePartnerUserTokensParams, VALID_WEBHOOK_EVENTS, WEBHOOK_CONTRACT_VERSION, WEBHOOK_CONTRACT_VERSION_HEADER, WEBHOOK_DELIVERY_HEADER, WEBHOOK_EVENT_HEADER, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_TIMESTAMP_HEADER, WebhookEnvelope, WebhookEnvelope as WebhookEnvelope$1, WebhookEventType, WhoamiResponse } from "@gscdump/contracts";
|
|
4
5
|
import { ZodTypeAny } from "zod";
|
|
5
6
|
import { ActionSource } from "@gscdump/analysis";
|
|
6
7
|
import { AnalysisTool } from "@gscdump/engine/analysis-types";
|
|
@@ -136,7 +137,20 @@ interface DailyAnonInput {
|
|
|
136
137
|
anonymizedImpressionsPct: number;
|
|
137
138
|
}
|
|
138
139
|
declare function weightedAnonPct(days: readonly DailyAnonInput[] | null | undefined, window?: number): number | null;
|
|
140
|
+
declare namespace archetypes_d_exports {
|
|
141
|
+
export { ARCHETYPE_EXECUTION_CLASS, arbitrarySql, auxCloudOnly, entityDailySparkline, entityDailyTimeseries, multiSeriesStackedDaily, singleRowLookup, siteDailyTimeseries, topNBreakdown, twoDimensionDetail };
|
|
142
|
+
}
|
|
139
143
|
import * as import__gscdump_contracts_archetypes from "@gscdump/contracts/archetypes";
|
|
144
|
+
declare const ARCHETYPE_EXECUTION_CLASS: Record<import("@gscdump/contracts").QueryArchetype, import("@gscdump/contracts").ArchetypeExecutionClass>;
|
|
145
|
+
declare const arbitrarySql: typeof arbitrarySql$1;
|
|
146
|
+
declare const auxCloudOnly: typeof auxCloudOnly$1;
|
|
147
|
+
declare const entityDailySparkline: typeof entityDailySparkline$1;
|
|
148
|
+
declare const entityDailyTimeseries: typeof entityDailyTimeseries$1;
|
|
149
|
+
declare const multiSeriesStackedDaily: typeof multiSeriesStackedDaily$1;
|
|
150
|
+
declare const singleRowLookup: typeof singleRowLookup$1;
|
|
151
|
+
declare const siteDailyTimeseries: typeof siteDailyTimeseries$1;
|
|
152
|
+
declare const topNBreakdown: typeof topNBreakdown$1;
|
|
153
|
+
declare const twoDimensionDetail: typeof twoDimensionDetail$1;
|
|
140
154
|
type PartnerFetch = HostedFetch;
|
|
141
155
|
type PartnerHeaders = HostedHeaders;
|
|
142
156
|
type PartnerFetchOptions = HostedFetchOptions;
|
|
@@ -156,7 +170,6 @@ interface PartnerClientOptions extends HostedClientOptions {
|
|
|
156
170
|
validate?: boolean | 'request' | 'response';
|
|
157
171
|
}
|
|
158
172
|
declare function createPartnerClient(options?: PartnerClientOptions): PartnerClient$1;
|
|
159
|
-
declare const createGscdumpClient: typeof createPartnerClient;
|
|
160
173
|
declare const COUNTRY_NAMES: Record<string, string>;
|
|
161
174
|
declare const countryName: (code: string) => string;
|
|
162
175
|
declare const CWV_GOOD_LCP = 2500;
|
|
@@ -213,7 +226,7 @@ interface GscClassifiedError {
|
|
|
213
226
|
code?: number;
|
|
214
227
|
/** Best-effort human message: server-supplied `message`, then `data.message`, then the error's own message. */
|
|
215
228
|
message?: string;
|
|
216
|
-
/** Seconds the server suggested waiting (429
|
|
229
|
+
/** Seconds the server suggested waiting (429/503 retry payloads). */
|
|
217
230
|
retryAfter?: number;
|
|
218
231
|
}
|
|
219
232
|
declare function classifyGscError(e: unknown): GscClassifiedError;
|
|
@@ -246,6 +259,14 @@ interface DateRangeResult {
|
|
|
246
259
|
yearEnd: string;
|
|
247
260
|
days: number;
|
|
248
261
|
}
|
|
262
|
+
interface PeriodOptions {
|
|
263
|
+
/** Subtract GSC's stable-data latency from `end`. Default `true`. */
|
|
264
|
+
stableData?: boolean;
|
|
265
|
+
/** IANA timezone used to resolve today's calendar date. Default GSC/Pacific time. */
|
|
266
|
+
timezone?: string;
|
|
267
|
+
/** Clock used to resolve today's calendar date. Defaults to the current time. */
|
|
268
|
+
now?: Date;
|
|
269
|
+
}
|
|
249
270
|
declare function isCustomPeriod(p: Period | string): p is CustomPeriod;
|
|
250
271
|
declare function parseCustomPeriod(p: Period | string): {
|
|
251
272
|
start: string;
|
|
@@ -253,8 +274,8 @@ declare function parseCustomPeriod(p: Period | string): {
|
|
|
253
274
|
prevStart?: string;
|
|
254
275
|
prevEnd?: string;
|
|
255
276
|
} | null;
|
|
256
|
-
declare function periodToDateRange(period: Period | string,
|
|
257
|
-
declare function periodToDays(period: Period | string): number;
|
|
277
|
+
declare function periodToDateRange(period: Period | string, stableDataOrOptions?: boolean | PeriodOptions): DateRangeResult;
|
|
278
|
+
declare function periodToDays(period: Period | string, stableDataOrOptions?: boolean | PeriodOptions): number;
|
|
258
279
|
declare function compareRange(range: DateRangeResult, mode: CompareMode): {
|
|
259
280
|
start: string;
|
|
260
281
|
end: string;
|
|
@@ -349,6 +370,29 @@ declare function positionFor(r: {
|
|
|
349
370
|
impressions: number;
|
|
350
371
|
sum_position: number;
|
|
351
372
|
}): number;
|
|
373
|
+
type GscSearchType = 'web' | 'image' | 'video' | 'news' | 'discover' | 'googleNews';
|
|
374
|
+
interface SearchTypeOptions {
|
|
375
|
+
searchType?: GscSearchType;
|
|
376
|
+
}
|
|
377
|
+
interface SourceRangeOptions {
|
|
378
|
+
start?: string;
|
|
379
|
+
end?: string;
|
|
380
|
+
startDate?: string;
|
|
381
|
+
endDate?: string;
|
|
382
|
+
}
|
|
383
|
+
interface AnalysisSourcesOptions extends SearchTypeOptions, SourceRangeOptions {
|
|
384
|
+
tables?: string[] | string;
|
|
385
|
+
maxBytes?: number;
|
|
386
|
+
maxRows?: number;
|
|
387
|
+
maxFiles?: number;
|
|
388
|
+
}
|
|
389
|
+
declare const DEFAULT_SEARCH_TYPE: GscSearchType;
|
|
390
|
+
declare function withDefaultSearchType<T extends object>(value: T, searchType?: GscSearchType): T & SearchTypeOptions;
|
|
391
|
+
declare function withDefaultSearchType<T>(value: T, searchType?: GscSearchType): T;
|
|
392
|
+
declare function searchTypeQuery(searchType?: GscSearchType): Record<string, string>;
|
|
393
|
+
declare function dateRangeOptionsQuery(options: SourceRangeOptions | undefined): Record<string, string>;
|
|
394
|
+
declare function sourceInfoQuery(options: SourceInfoOptions | undefined): Record<string, string>;
|
|
395
|
+
declare function tablesQuery(tablesOrOptions: string[] | string | AnalysisSourcesOptions | undefined, options?: AnalysisSourcesOptions): Record<string, string>;
|
|
352
396
|
interface IndexingIssueDetail {
|
|
353
397
|
description: string;
|
|
354
398
|
fix: string;
|
|
@@ -403,83 +447,18 @@ declare const issueTypeToGroup: Record<string, string>;
|
|
|
403
447
|
declare function enrichIssueDetails(modules?: {
|
|
404
448
|
name: string;
|
|
405
449
|
}[]): Record<string, IndexingIssueDetail>;
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
type
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
}) => void) | null;
|
|
419
|
-
onerror: ((event: unknown) => void) | null;
|
|
420
|
-
onclose: ((event: unknown) => void) | null;
|
|
421
|
-
send: (data: string) => void;
|
|
422
|
-
close: (code?: number, reason?: string) => void;
|
|
423
|
-
}
|
|
424
|
-
interface PartnerWebSocketConstructor {
|
|
425
|
-
new (url: string, protocols?: string | string[]): PartnerWebSocketLike;
|
|
426
|
-
}
|
|
427
|
-
interface PartnerRealtimeReconnectOptions {
|
|
428
|
-
/** Default `true`. Set `false` to disable automatic reconnection entirely. */
|
|
429
|
-
enabled?: boolean;
|
|
430
|
-
/** First-retry delay in ms; doubles each attempt. Default `1000`. */
|
|
431
|
-
baseDelayMs?: number;
|
|
432
|
-
/** Upper bound on the backoff delay in ms. Default `30000`. */
|
|
433
|
-
maxDelayMs?: number;
|
|
434
|
-
/** Stop after this many consecutive failed attempts. Default `Infinity`. */
|
|
435
|
-
maxRetries?: number;
|
|
436
|
-
/** Apply equal-jitter to each delay so many clients don't reconnect in lockstep. Default `true`. */
|
|
437
|
-
jitter?: boolean;
|
|
438
|
-
}
|
|
439
|
-
interface PartnerRealtimeOptions {
|
|
440
|
-
/**
|
|
441
|
-
* HTTP API base used only to derive a same-origin websocket base when `wsBase`
|
|
442
|
-
* is omitted. Prefer passing `wsBase` when the websocket origin differs.
|
|
443
|
-
*/
|
|
444
|
-
apiBase?: string;
|
|
445
|
-
/** WebSocket origin base, for example `wss://origin.example`. */
|
|
446
|
-
wsBase?: string;
|
|
447
|
-
/** Partner or user API key sent in the first auth message. */
|
|
448
|
-
apiKey: string;
|
|
449
|
-
/** `/ws/partner` or `/ws/user`. User scope supports partner key + user id. */
|
|
450
|
-
scope?: PartnerRealtimeScope;
|
|
451
|
-
/** Required by the hosted `/ws/user` route when authenticating with a partner API key. */
|
|
452
|
-
userId?: number | string;
|
|
453
|
-
/** Optional initial site filter sent after authentication succeeds. */
|
|
454
|
-
siteIds?: string[];
|
|
455
|
-
protocols?: string | string[];
|
|
456
|
-
WebSocket?: PartnerWebSocketConstructor;
|
|
457
|
-
/**
|
|
458
|
-
* Automatic reconnection on unexpected close (network drop, server restart).
|
|
459
|
-
* A raw WebSocket `error` Event carries no actionable detail, so rather than
|
|
460
|
-
* surfacing it the client transparently reconnects with exponential backoff.
|
|
461
|
-
* `true` (default) uses defaults; pass an object to tune; `false` disables.
|
|
462
|
-
* The backoff counter resets once a reconnection reaches `authenticated`.
|
|
463
|
-
*/
|
|
464
|
-
reconnect?: boolean | PartnerRealtimeReconnectOptions;
|
|
465
|
-
/** Injected timer hooks (for tests). Defaults to global `setTimeout`/`clearTimeout`. */
|
|
466
|
-
setTimeout?: (handler: () => void, ms: number) => unknown;
|
|
467
|
-
clearTimeout?: (handle: unknown) => void;
|
|
468
|
-
}
|
|
469
|
-
interface PartnerRealtimeClient {
|
|
470
|
-
readonly status: PartnerRealtimeStatus;
|
|
471
|
-
readonly socket: PartnerWebSocketLike | null;
|
|
472
|
-
connect: () => PartnerWebSocketLike;
|
|
473
|
-
close: (code?: number, reason?: string) => void;
|
|
474
|
-
ping: () => void;
|
|
475
|
-
subscribe: (siteIds: string[]) => void;
|
|
476
|
-
onStatus: (handler: PartnerRealtimeHandler<PartnerRealtimeStatus>) => () => void;
|
|
477
|
-
onMessage: (handler: PartnerRealtimeHandler<PartnerRealtimeMessage$1>) => () => void;
|
|
478
|
-
onEvent: (handler: PartnerRealtimeHandler<PartnerRealtimeEvent$1>) => () => void;
|
|
479
|
-
onError: (handler: PartnerRealtimeHandler<unknown>) => () => void;
|
|
480
|
-
}
|
|
481
|
-
declare function createPartnerRealtimeClient(options: PartnerRealtimeOptions): PartnerRealtimeClient;
|
|
482
|
-
declare const createGscdumpRealtimeClient: typeof createPartnerRealtimeClient;
|
|
450
|
+
/**
|
|
451
|
+
* Stable lifecycle fields shared by the legacy partner response and public v1.
|
|
452
|
+
* Keeping the adapters structural lets consumers migrate to v1 without
|
|
453
|
+
* re-introducing legacy-only fields such as `intId` or `lifecycleRevision`.
|
|
454
|
+
*/
|
|
455
|
+
type LifecycleSiteLike = Pick<PartnerLifecycleSite$1, 'siteId' | 'externalSiteId' | 'requestedUrl' | 'gscPropertyUrl' | 'permissionLevel' | 'analytics' | 'indexing' | 'latestError' | 'updatedAt'>;
|
|
456
|
+
declare function analyticsStatusToSyncStatus(status: LifecycleSiteLike['analytics']['status']): GscdumpUserSite$1['syncStatus'];
|
|
457
|
+
declare function lifecycleSiteToUserSite(site: LifecycleSiteLike): GscdumpUserSite$1;
|
|
458
|
+
declare function lifecycleSiteToSyncStatus(site: LifecycleSiteLike): GscdumpSyncStatusResponse$1;
|
|
459
|
+
declare function findLifecycleSite<TSite extends LifecycleSiteLike>(lifecycle: {
|
|
460
|
+
sites: readonly TSite[];
|
|
461
|
+
}, siteIdOrPropertyUrl: string): TSite | null;
|
|
483
462
|
type SearchConsoleStageKey = 'not_connected' | 'waiting_for_data' | 'weak_discovery' | 'discovery_backlog' | 'crawl_blocked' | 'indexability_blocked' | 'index_rejection' | 'partially_indexed' | 'indexed_invisible' | 'visible_not_clicked' | 'ranking_stalled' | 'declining_visibility' | 'healthy_growth_ready';
|
|
484
463
|
type SearchConsoleStageSeverity = 'success' | 'error' | 'warning' | 'info' | 'neutral';
|
|
485
464
|
interface SearchConsoleStageEvidence {
|
|
@@ -754,7 +733,6 @@ declare function parseWebhookPayload<TData extends Record<string, unknown> = Rec
|
|
|
754
733
|
validateSignature?: boolean;
|
|
755
734
|
}): Promise<WebhookEnvelope$1<TData>>;
|
|
756
735
|
declare function readWebhookHeaders(headers: Headers | PartnerWebhookHeaders$1 | null | undefined): Required<PartnerWebhookHeaders$1>;
|
|
757
|
-
type ARCHETYPE_EXECUTION_CLASS = import__gscdump_contracts_archetypes.ARCHETYPE_EXECUTION_CLASS;
|
|
758
736
|
type ArbitrarySqlQuery = import__gscdump_contracts_archetypes.ArbitrarySqlQuery;
|
|
759
737
|
type ArchetypeExecutionClass = import__gscdump_contracts_archetypes.ArchetypeExecutionClass;
|
|
760
738
|
type ArchetypeFacet = import__gscdump_contracts_archetypes.ArchetypeFacet;
|
|
@@ -774,4 +752,5 @@ type SingleRowLookupQuery = import__gscdump_contracts_archetypes.SingleRowLookup
|
|
|
774
752
|
type SiteDailyTimeseriesQuery = import__gscdump_contracts_archetypes.SiteDailyTimeseriesQuery;
|
|
775
753
|
type TopNBreakdownQuery = import__gscdump_contracts_archetypes.TopNBreakdownQuery;
|
|
776
754
|
type TwoDimensionDetailQuery = import__gscdump_contracts_archetypes.TwoDimensionDetailQuery;
|
|
777
|
-
|
|
755
|
+
type WireDateRange = import__gscdump_contracts_archetypes.WireDateRange;
|
|
756
|
+
export { ARCHETYPE_EXECUTION_CLASS, type AddPartnerTeamMemberParams, type AnalysisSourcesOptions, type AnalyticsClient, type AnalyticsClientOptions, type AnalyticsFetch, type AnalyticsFetchOptions, type AnalyticsHeaders, type ArbitrarySqlQuery, type ArchetypeExecutionClass, type ArchetypeFacet, type ArchetypeQuery, type ArchetypeQueryBase, type ArchetypeResult, type ArchetypeResultRow, type ArchetypeResultSource, type AuxCloudOnlyQuery, type BackfillRange, type BackfillResponse, type BindPartnerSiteTeamParams, type BuilderState, type BulkRegisterPartnerSiteResult, type BulkRegisterPartnerSitesParams, type BulkRegisterPartnerSitesResponse, CANONICAL_WEBHOOK_EVENTS, COMPARE_OPTIONS, COUNTRY_NAMES, CWV_GOOD_CLS, CWV_GOOD_INP, CWV_GOOD_LCP, CWV_POOR_CLS, CWV_POOR_INP, CWV_POOR_LCP, type CalendarPeriod, type CanonicalDailyRow, type CanonicalWebhookEventType, type ClassifySearchConsoleStageInput, type CompareMode, type CreatePartnerTeamParams, type CreateWebhookEnvelopeOptions, type CustomPeriod, type CwvBucket, DEFAULT_SEARCH_TYPE, type DailyAnonInput, type DataDetailOptions, type DataQueryOptions, type DateRange, type DateRangeResult, type DeletePartnerUserResponse, type EntityDailySparklineQuery, type EntityDailyTimeseriesQuery, GSC_COLUMN_OPTIONS, GSC_PERIOD_OPTIONS, GSC_PERIOD_OPTIONS_LONG, GSC_STABLE_LATENCY_DAYS, type GscAnalyzerAccent, type GscAnalyzerCapabilities, type GscAnalyzerCapability, type GscAnalyzerDefinition, type GscAnalyzerDefinitionWithCapability, type GscAnalyzerInsightCard, type GscAnalyzerKind, type GscAnalyzerPanelResult, type GscAnalyzerPanelSpec, type GscAnalyzerStatTile, type GscClassifiedError, type GscColumn, type GscColumnOption, type GscComparisonFilter, type GscConsoleUrlOpts, type GscDailySummary, type GscErrorStatus, type GscRowTotals, type GscdumpAnalysisParams, type GscdumpAnalysisPreset, type GscdumpAnalysisResponse, type GscdumpAnalysisSourcesResponse, type GscdumpAvailableSite, type GscdumpCanonicalMismatchesResponse, type GscdumpDataDetailResponse, type GscdumpDataResponse, type GscdumpDataRow, type GscdumpDateRangeParams, type GscdumpIndexPercentResponse, type GscdumpIndexingDiagnosticsResponse, type GscdumpIndexingResponse, type GscdumpIndexingUrlStatus, type GscdumpIndexingUrlsResponse, type GscdumpKeywordSparklinesParams, type GscdumpKeywordSparklinesResponse, type GscdumpMeta, type GscdumpPageTrendParams, type GscdumpPageTrendResponse, type GscdumpPermissionRecovery, type GscdumpQueryTrendParams, type GscdumpQueryTrendResponse, type GscdumpSiteRegistration, type GscdumpSitemap, type GscdumpSitemapChangesResponse, type GscdumpSitemapHistory, type GscdumpSitemapsResponse, type GscdumpSyncStatusResponse, type GscdumpTeamMemberRow, type GscdumpTeamRow, type GscdumpTopAssociationParams, type GscdumpTopAssociationResponse, type GscdumpTotals, type GscdumpUserRegistration, type GscdumpUserSettings, type GscdumpUserSite, type GscdumpUserStatus, type GscdumpUserTokenUpdate, type HealthStage, type HealthVerdict, type IndexingDiagnosticsParams, type IndexingIssue, type IndexingIssueDetail, type IndexingUrlsParams, type InspectionHistoryResponse, type InspectionIndex, type IssueGroup, type IssueSeverity, type LifecycleSiteLike, type MultiSeriesStackedDailyQuery, PERIOD_PRESETS, PartnerApiError, type PartnerClient, type PartnerClientOptions, type PartnerErrorInfo, type PartnerErrorKind, type PartnerFetch, type PartnerFetchOptions, type PartnerHeaders, type PartnerLifecycleAccount, type PartnerLifecycleResponse, type PartnerLifecycleSite, type PartnerWebhookData, type PartnerWebhookHeaders, type PeerBaselineInput, type PeerConfidence, type PeerStanding, type Period, type PeriodOptions, type PeriodPreset, type QueryArchetype, type RawDailyRow, type ReachStage, type ReachVerdict, type RegisterPartnerSiteParams, type RegisterPartnerUserParams, type ResolvedArchetypeQuery, type RollingPeriod, type RollupEnvelope, SITE_TYPE_BASELINE, type SearchConsoleStage, type SearchConsoleStageEvidence, type SearchConsoleStageIssue, type SearchConsoleStageKey, type SearchConsoleStagePage, type SearchConsoleStageSeverity, type SearchConsoleStageSitemap, type SearchConsoleStageSummary, type SearchConsoleStageTrajectory, type SearchTypeOptions, type SingleRowLookupQuery, type SiteBaseline, type SiteDailyTimeseriesQuery, type SiteTriage, type SiteTriageInput, type SiteType, type SiteTypeBaseline, type SourceRangeOptions, type TopNBreakdownQuery, type TriageEvidence, type TwoDimensionDetailQuery, type UpdatePartnerUserTokensParams, VALID_WEBHOOK_EVENTS, WEBHOOK_CONTRACT_VERSION, WEBHOOK_CONTRACT_VERSION_HEADER, WEBHOOK_DELIVERY_HEADER, WEBHOOK_EVENT_HEADER, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_TIMESTAMP_HEADER, type WebhookEnvelope, type WebhookEventType, type WhoamiResponse, type WireDateRange, analyticsStatusToSyncStatus, andFilter, arbitrarySql, auxCloudOnly, classifyGscError, classifyHealthStage, classifyReachStage, classifySearchConsoleStage, classifySiteTriage, coerceRowMetrics, compareRange, countryName, coverageLabel, coverageLabels, createAnalyticsClient, createPartnerClient, cwvBucket, dateFilter, dateRangeOptionsQuery, defineGscAnalyzer, derivePeerStanding, deriveSiteBaseline, enrichIssueDetails, entityDailySparkline, entityDailyTimeseries, findLifecycleSite, formatPartnerError, getGscUnstableCutoffDate, gscConsoleUrl, investigationStatusConfig, isCustomPeriod, isPartnerError, issueDetails, issueGroups, issueTypeToGroup, lifecycleSiteToSyncStatus, lifecycleSiteToUserSite, multiSeriesStackedDaily, normalizeSiteType, nuxtSeoTips, parseCustomPeriod, parseWebhookPayload, parseWebhookPayloadResult, partnerErrorToException, periodToDateRange, periodToDays, positionFor, reachLivenessRatio, readWebhookHeaders, searchTypeQuery, serializeWebhookPayload, severityOrder, singleRowLookup, siteDailyTimeseries, siteTypeBaseline, siteUrlToHostname, sourceInfoQuery, splitOpportunityTitle, summarizeDailyRows, tablesQuery, toPartnerError, topNBreakdown, truncateQuery, twoDimensionDetail, verifyWebhookSignature, weightedAnonPct, withDefaultSearchType };
|
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { __exportAll, __reExport } from "./_chunks/rolldown-runtime.mjs";
|
|
2
|
-
import { query_exports } from "./query.mjs";
|
|
3
1
|
import { analyticsEndpoints } from "@gscdump/contracts/analytics";
|
|
4
2
|
import { err, ok, unwrapResult } from "gscdump/result";
|
|
5
3
|
import { ofetch } from "ofetch";
|
|
6
|
-
import {
|
|
4
|
+
import { ARCHETYPE_EXECUTION_CLASS as ARCHETYPE_EXECUTION_CLASS$1, arbitrarySql as arbitrarySql$1, auxCloudOnly as auxCloudOnly$1, entityDailySparkline as entityDailySparkline$1, entityDailyTimeseries as entityDailyTimeseries$1, multiSeriesStackedDaily as multiSeriesStackedDaily$1, singleRowLookup as singleRowLookup$1, siteDailyTimeseries as siteDailyTimeseries$1, topNBreakdown as topNBreakdown$1, twoDimensionDetail as twoDimensionDetail$1 } from "@gscdump/contracts/archetypes";
|
|
5
|
+
import { partnerEndpoints } from "@gscdump/contracts/partner";
|
|
7
6
|
import { resolveWindow } from "@gscdump/engine/period";
|
|
8
7
|
import { endOfMonth, format, startOfMonth, startOfQuarter, startOfWeek, subDays, subMonths } from "date-fns";
|
|
9
8
|
import { CANONICAL_WEBHOOK_EVENTS, VALID_WEBHOOK_EVENTS, WEBHOOK_CONTRACT_VERSION, WEBHOOK_CONTRACT_VERSION_HEADER, WEBHOOK_CONTRACT_VERSION_HEADER as WEBHOOK_CONTRACT_VERSION_HEADER$1, WEBHOOK_DELIVERY_HEADER, WEBHOOK_DELIVERY_HEADER as WEBHOOK_DELIVERY_HEADER$1, WEBHOOK_EVENT_HEADER, WEBHOOK_EVENT_HEADER as WEBHOOK_EVENT_HEADER$1, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_SIGNATURE_HEADER as WEBHOOK_SIGNATURE_HEADER$1, WEBHOOK_TIMESTAMP_HEADER, WEBHOOK_TIMESTAMP_HEADER as WEBHOOK_TIMESTAMP_HEADER$1, partnerWebhookEnvelopeSchema } from "@gscdump/contracts";
|
|
10
9
|
export * from "@gscdump/contracts";
|
|
10
|
+
const DEFAULT_SEARCH_TYPE = "web";
|
|
11
11
|
function isAnalysisSourcesOptions(value) {
|
|
12
12
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
13
13
|
}
|
|
@@ -49,6 +49,9 @@ function tablesQuery(tablesOrOptions, options) {
|
|
|
49
49
|
...dateRangeOptionsQuery(source)
|
|
50
50
|
};
|
|
51
51
|
if (tables) query.tables = Array.isArray(tables) ? [...new Set(tables.filter(Boolean))].sort().join(",") : [...new Set(tables.split(",").map((t) => t.trim()).filter(Boolean))].sort().join(",");
|
|
52
|
+
if (source?.maxBytes != null) query.maxBytes = String(Math.max(1, Math.floor(source.maxBytes)));
|
|
53
|
+
if (source?.maxRows != null) query.maxRows = String(Math.max(1, Math.floor(source.maxRows)));
|
|
54
|
+
if (source?.maxFiles != null) query.maxFiles = String(Math.max(1, Math.floor(source.maxFiles)));
|
|
52
55
|
return query;
|
|
53
56
|
}
|
|
54
57
|
function dataQuery(state, options) {
|
|
@@ -186,10 +189,10 @@ function formatPartnerError(error) {
|
|
|
186
189
|
function partnerErrorToException(error) {
|
|
187
190
|
return error;
|
|
188
191
|
}
|
|
189
|
-
const TRAILING_SLASH_RE
|
|
192
|
+
const TRAILING_SLASH_RE = /\/+$/;
|
|
190
193
|
const LEADING_SLASH_RE = /^\/+/;
|
|
191
194
|
function trimApiBase(apiBase, fallback) {
|
|
192
|
-
return (apiBase ?? fallback).replace(TRAILING_SLASH_RE
|
|
195
|
+
return (apiBase ?? fallback).replace(TRAILING_SLASH_RE, "");
|
|
193
196
|
}
|
|
194
197
|
function buildPath(apiBase, path) {
|
|
195
198
|
if (!apiBase) return path.startsWith("/") ? path : `/${path}`;
|
|
@@ -398,9 +401,16 @@ function weightedAnonPct(days, window = 28) {
|
|
|
398
401
|
}
|
|
399
402
|
return totalImpressions > 0 ? weighted / totalImpressions : null;
|
|
400
403
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
+
const ARCHETYPE_EXECUTION_CLASS = ARCHETYPE_EXECUTION_CLASS$1;
|
|
405
|
+
const arbitrarySql = arbitrarySql$1;
|
|
406
|
+
const auxCloudOnly = auxCloudOnly$1;
|
|
407
|
+
const entityDailySparkline = entityDailySparkline$1;
|
|
408
|
+
const entityDailyTimeseries = entityDailyTimeseries$1;
|
|
409
|
+
const multiSeriesStackedDaily = multiSeriesStackedDaily$1;
|
|
410
|
+
const singleRowLookup = singleRowLookup$1;
|
|
411
|
+
const siteDailyTimeseries = siteDailyTimeseries$1;
|
|
412
|
+
const topNBreakdown = topNBreakdown$1;
|
|
413
|
+
const twoDimensionDetail = twoDimensionDetail$1;
|
|
404
414
|
function normalizeLifecycleUrl(url) {
|
|
405
415
|
return (url || "").replace(/^sc-domain:/, "").replace(/^https?:\/\//, "").replace(/^www\./, "").replace(/\/$/, "").toLowerCase();
|
|
406
416
|
}
|
|
@@ -858,7 +868,6 @@ function createPartnerClient(options = {}) {
|
|
|
858
868
|
}
|
|
859
869
|
};
|
|
860
870
|
}
|
|
861
|
-
const createGscdumpClient = createPartnerClient;
|
|
862
871
|
const COUNTRY_NAMES = {
|
|
863
872
|
US: "United States",
|
|
864
873
|
GB: "United Kingdom",
|
|
@@ -965,10 +974,11 @@ function classifyGscError(e) {
|
|
|
965
974
|
code,
|
|
966
975
|
message
|
|
967
976
|
};
|
|
968
|
-
if (code === 429) {
|
|
969
|
-
const
|
|
977
|
+
if (code === 429 || code === 503) {
|
|
978
|
+
const data = e?.data;
|
|
979
|
+
const retry = data?.retryAfter ?? data?.retryAfterSeconds;
|
|
970
980
|
return {
|
|
971
|
-
status: "rate-limited",
|
|
981
|
+
status: code === 429 ? "rate-limited" : "network",
|
|
972
982
|
code,
|
|
973
983
|
message,
|
|
974
984
|
retryAfter: typeof retry === "number" ? retry : void 0
|
|
@@ -1133,19 +1143,26 @@ function coerceRowMetrics(row) {
|
|
|
1133
1143
|
};
|
|
1134
1144
|
}
|
|
1135
1145
|
function summarizeDailyRows(raw) {
|
|
1136
|
-
const daily =
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
sum_position:
|
|
1141
|
-
|
|
1146
|
+
const daily = [];
|
|
1147
|
+
for (let index = 0; index < raw.length; index++) {
|
|
1148
|
+
const row = raw[index];
|
|
1149
|
+
const position = row.position ?? 0;
|
|
1150
|
+
const sumPosition = row.sum_position ?? (position > 0 ? (position - 1) * row.impressions : 0);
|
|
1151
|
+
daily.push({
|
|
1152
|
+
date: row.date,
|
|
1153
|
+
clicks: row.clicks,
|
|
1154
|
+
impressions: row.impressions,
|
|
1155
|
+
sum_position: sumPosition
|
|
1156
|
+
});
|
|
1157
|
+
}
|
|
1158
|
+
daily.sort((a, b) => a.date.localeCompare(b.date));
|
|
1142
1159
|
let clicks = 0;
|
|
1143
1160
|
let impressions = 0;
|
|
1144
1161
|
let weightedPosition = 0;
|
|
1145
|
-
for (const
|
|
1146
|
-
clicks +=
|
|
1147
|
-
impressions +=
|
|
1148
|
-
weightedPosition +=
|
|
1162
|
+
for (const row of daily) {
|
|
1163
|
+
clicks += row.clicks;
|
|
1164
|
+
impressions += row.impressions;
|
|
1165
|
+
weightedPosition += row.sum_position;
|
|
1149
1166
|
}
|
|
1150
1167
|
return {
|
|
1151
1168
|
daily,
|
|
@@ -1481,8 +1498,14 @@ function parseCustomPeriod(p) {
|
|
|
1481
1498
|
end
|
|
1482
1499
|
};
|
|
1483
1500
|
}
|
|
1484
|
-
function
|
|
1485
|
-
|
|
1501
|
+
function todayInTimezone(timezone = "America/Los_Angeles", now = /* @__PURE__ */ new Date()) {
|
|
1502
|
+
const date = new Intl.DateTimeFormat("en-CA", {
|
|
1503
|
+
timeZone: timezone,
|
|
1504
|
+
year: "numeric",
|
|
1505
|
+
month: "2-digit",
|
|
1506
|
+
day: "2-digit"
|
|
1507
|
+
}).format(now);
|
|
1508
|
+
return /* @__PURE__ */ new Date(`${date}T00:00:00`);
|
|
1486
1509
|
}
|
|
1487
1510
|
const ROLLING_TO_UPSTREAM = {
|
|
1488
1511
|
"7d": "last-7d",
|
|
@@ -1524,7 +1547,9 @@ function buildResultFromIso(start, end) {
|
|
|
1524
1547
|
days
|
|
1525
1548
|
};
|
|
1526
1549
|
}
|
|
1527
|
-
function periodToDateRange(period,
|
|
1550
|
+
function periodToDateRange(period, stableDataOrOptions = true) {
|
|
1551
|
+
const options = typeof stableDataOrOptions === "boolean" ? { stableData: stableDataOrOptions } : stableDataOrOptions;
|
|
1552
|
+
const stableData = options.stableData ?? true;
|
|
1528
1553
|
const custom = parseCustomPeriod(period);
|
|
1529
1554
|
if (custom) {
|
|
1530
1555
|
const result = buildResultFromIso(custom.start, custom.end);
|
|
@@ -1537,7 +1562,7 @@ function periodToDateRange(period, stableData = true) {
|
|
|
1537
1562
|
};
|
|
1538
1563
|
return result;
|
|
1539
1564
|
}
|
|
1540
|
-
const today =
|
|
1565
|
+
const today = todayInTimezone(options.timezone, options.now);
|
|
1541
1566
|
const end = stableData ? subDays(today, 3) : subDays(today, 1);
|
|
1542
1567
|
const endIso = fmt(end);
|
|
1543
1568
|
const upstreamPreset = ROLLING_TO_UPSTREAM[period] ?? CALENDAR_TO_UPSTREAM[period];
|
|
@@ -1564,8 +1589,8 @@ function periodToDateRange(period, stableData = true) {
|
|
|
1564
1589
|
}
|
|
1565
1590
|
return buildResultFromIso(fmt(start), endIso);
|
|
1566
1591
|
}
|
|
1567
|
-
function periodToDays(period) {
|
|
1568
|
-
return periodToDateRange(period).days;
|
|
1592
|
+
function periodToDays(period, stableDataOrOptions = true) {
|
|
1593
|
+
return periodToDateRange(period, stableDataOrOptions).days;
|
|
1569
1594
|
}
|
|
1570
1595
|
function compareRange(range, mode) {
|
|
1571
1596
|
if (mode === "none") return null;
|
|
@@ -1583,189 +1608,6 @@ function getGscUnstableCutoffDate() {
|
|
|
1583
1608
|
const cutoff = new Date(y, m - 1, d - 3);
|
|
1584
1609
|
return `${cutoff.getFullYear()}-${String(cutoff.getMonth() + 1).padStart(2, "0")}-${String(cutoff.getDate()).padStart(2, "0")}`;
|
|
1585
1610
|
}
|
|
1586
|
-
function resolveReconnect(reconnect) {
|
|
1587
|
-
const opts = reconnect === false ? { enabled: false } : reconnect === true || reconnect == null ? {} : reconnect;
|
|
1588
|
-
return {
|
|
1589
|
-
enabled: opts.enabled ?? true,
|
|
1590
|
-
baseDelayMs: opts.baseDelayMs ?? 1e3,
|
|
1591
|
-
maxDelayMs: opts.maxDelayMs ?? 3e4,
|
|
1592
|
-
maxRetries: opts.maxRetries ?? Number.POSITIVE_INFINITY,
|
|
1593
|
-
jitter: opts.jitter ?? true
|
|
1594
|
-
};
|
|
1595
|
-
}
|
|
1596
|
-
const HTTP_PROTOCOL_RE = /^http/i;
|
|
1597
|
-
const API_SUFFIX_RE = /\/api\/?$/;
|
|
1598
|
-
const TRAILING_SLASH_RE = /\/+$/;
|
|
1599
|
-
function inferWsBase(options) {
|
|
1600
|
-
if (options.wsBase) return options.wsBase.replace(TRAILING_SLASH_RE, "");
|
|
1601
|
-
if (!options.apiBase) return "";
|
|
1602
|
-
return options.apiBase.replace(API_SUFFIX_RE, "").replace(TRAILING_SLASH_RE, "").replace(HTTP_PROTOCOL_RE, (m) => m.toLowerCase() === "https" ? "wss" : "ws");
|
|
1603
|
-
}
|
|
1604
|
-
function wsPath(scope) {
|
|
1605
|
-
return scope === "partner" ? partnerRoutes.realtime.partner : partnerRoutes.realtime.user;
|
|
1606
|
-
}
|
|
1607
|
-
function buildWsUrl(options) {
|
|
1608
|
-
const scope = options.scope ?? "partner";
|
|
1609
|
-
const base = inferWsBase(options);
|
|
1610
|
-
if (!base) return wsPath(scope);
|
|
1611
|
-
return `${base}${wsPath(scope)}`;
|
|
1612
|
-
}
|
|
1613
|
-
function parseMessage(raw) {
|
|
1614
|
-
if (typeof raw !== "string") return null;
|
|
1615
|
-
try {
|
|
1616
|
-
return JSON.parse(raw);
|
|
1617
|
-
} catch {
|
|
1618
|
-
return null;
|
|
1619
|
-
}
|
|
1620
|
-
}
|
|
1621
|
-
function isRealtimeEvent(message) {
|
|
1622
|
-
return "event" in message && message.event !== "auth.required" && message.event !== "connected";
|
|
1623
|
-
}
|
|
1624
|
-
function getWebSocketCtor(options) {
|
|
1625
|
-
const ctor = options.WebSocket ?? globalThis.WebSocket;
|
|
1626
|
-
if (!ctor) throw new Error("WebSocket is not available; pass options.WebSocket");
|
|
1627
|
-
return ctor;
|
|
1628
|
-
}
|
|
1629
|
-
function createPartnerRealtimeClient(options) {
|
|
1630
|
-
let socket = null;
|
|
1631
|
-
let status = "idle";
|
|
1632
|
-
const reconnect = resolveReconnect(options.reconnect);
|
|
1633
|
-
const setTimer = options.setTimeout ?? ((handler, ms) => setTimeout(handler, ms));
|
|
1634
|
-
const clearTimer = options.clearTimeout ?? ((handle) => clearTimeout(handle));
|
|
1635
|
-
let manualClose = false;
|
|
1636
|
-
let reconnectAttempts = 0;
|
|
1637
|
-
let reconnectTimer = null;
|
|
1638
|
-
const statusHandlers = /* @__PURE__ */ new Set();
|
|
1639
|
-
const messageHandlers = /* @__PURE__ */ new Set();
|
|
1640
|
-
const eventHandlers = /* @__PURE__ */ new Set();
|
|
1641
|
-
const errorHandlers = /* @__PURE__ */ new Set();
|
|
1642
|
-
function setStatus(next) {
|
|
1643
|
-
status = next;
|
|
1644
|
-
for (const handler of statusHandlers) handler(next);
|
|
1645
|
-
}
|
|
1646
|
-
function sendJson(payload) {
|
|
1647
|
-
if (!socket) throw new Error("Partner realtime client is not connected");
|
|
1648
|
-
socket.send(JSON.stringify(payload));
|
|
1649
|
-
}
|
|
1650
|
-
function authPayload() {
|
|
1651
|
-
const payload = {
|
|
1652
|
-
type: "auth",
|
|
1653
|
-
apiKey: options.apiKey
|
|
1654
|
-
};
|
|
1655
|
-
if (options.userId != null) payload.userId = options.userId;
|
|
1656
|
-
return payload;
|
|
1657
|
-
}
|
|
1658
|
-
function subscribe(siteIds) {
|
|
1659
|
-
sendJson({
|
|
1660
|
-
type: "subscribe",
|
|
1661
|
-
siteIds
|
|
1662
|
-
});
|
|
1663
|
-
}
|
|
1664
|
-
function clearReconnectTimer() {
|
|
1665
|
-
if (reconnectTimer != null) {
|
|
1666
|
-
clearTimer(reconnectTimer);
|
|
1667
|
-
reconnectTimer = null;
|
|
1668
|
-
}
|
|
1669
|
-
}
|
|
1670
|
-
function backoffDelay(attempt) {
|
|
1671
|
-
const exp = Math.min(reconnect.maxDelayMs, reconnect.baseDelayMs * 2 ** attempt);
|
|
1672
|
-
if (!reconnect.jitter) return exp;
|
|
1673
|
-
return Math.round(exp / 2 + Math.random() * (exp / 2));
|
|
1674
|
-
}
|
|
1675
|
-
function openSocket() {
|
|
1676
|
-
if (socket) return socket;
|
|
1677
|
-
clearReconnectTimer();
|
|
1678
|
-
manualClose = false;
|
|
1679
|
-
socket = new (getWebSocketCtor(options))(buildWsUrl(options), options.protocols);
|
|
1680
|
-
setStatus("connecting");
|
|
1681
|
-
socket.onopen = () => {
|
|
1682
|
-
setStatus("open");
|
|
1683
|
-
sendJson(authPayload());
|
|
1684
|
-
};
|
|
1685
|
-
socket.onmessage = (event) => {
|
|
1686
|
-
const message = parseMessage(event.data);
|
|
1687
|
-
if (!message) return;
|
|
1688
|
-
if ("event" in message && message.event === "connected") {
|
|
1689
|
-
reconnectAttempts = 0;
|
|
1690
|
-
setStatus("authenticated");
|
|
1691
|
-
if (options.siteIds?.length) subscribe(options.siteIds);
|
|
1692
|
-
}
|
|
1693
|
-
for (const handler of messageHandlers) handler(message);
|
|
1694
|
-
if (isRealtimeEvent(message)) for (const handler of eventHandlers) handler(message);
|
|
1695
|
-
};
|
|
1696
|
-
socket.onerror = (event) => {
|
|
1697
|
-
setStatus("error");
|
|
1698
|
-
for (const handler of errorHandlers) handler(event);
|
|
1699
|
-
};
|
|
1700
|
-
socket.onclose = (event) => {
|
|
1701
|
-
socket = null;
|
|
1702
|
-
setStatus("closed");
|
|
1703
|
-
for (const handler of messageHandlers) handler({
|
|
1704
|
-
type: "error",
|
|
1705
|
-
message: `WebSocket closed: ${JSON.stringify(event)}`
|
|
1706
|
-
});
|
|
1707
|
-
scheduleReconnect();
|
|
1708
|
-
};
|
|
1709
|
-
return socket;
|
|
1710
|
-
}
|
|
1711
|
-
function scheduleReconnect() {
|
|
1712
|
-
if (!reconnect.enabled || manualClose || reconnectTimer != null) return;
|
|
1713
|
-
if (reconnectAttempts >= reconnect.maxRetries) {
|
|
1714
|
-
const err = /* @__PURE__ */ new Error(`Partner realtime reconnect exhausted after ${reconnectAttempts} attempts`);
|
|
1715
|
-
for (const handler of errorHandlers) handler(err);
|
|
1716
|
-
return;
|
|
1717
|
-
}
|
|
1718
|
-
const delay = backoffDelay(reconnectAttempts);
|
|
1719
|
-
reconnectAttempts += 1;
|
|
1720
|
-
setStatus("connecting");
|
|
1721
|
-
reconnectTimer = setTimer(() => {
|
|
1722
|
-
reconnectTimer = null;
|
|
1723
|
-
openSocket();
|
|
1724
|
-
}, delay);
|
|
1725
|
-
}
|
|
1726
|
-
return {
|
|
1727
|
-
get status() {
|
|
1728
|
-
return status;
|
|
1729
|
-
},
|
|
1730
|
-
get socket() {
|
|
1731
|
-
return socket;
|
|
1732
|
-
},
|
|
1733
|
-
connect() {
|
|
1734
|
-
return openSocket();
|
|
1735
|
-
},
|
|
1736
|
-
close(code, reason) {
|
|
1737
|
-
manualClose = true;
|
|
1738
|
-
clearReconnectTimer();
|
|
1739
|
-
const ws = socket;
|
|
1740
|
-
socket = null;
|
|
1741
|
-
setStatus("closed");
|
|
1742
|
-
if (!ws) return;
|
|
1743
|
-
if (ws.readyState === 0) ws.onopen = () => ws.close(code, reason);
|
|
1744
|
-
else ws.close(code, reason);
|
|
1745
|
-
},
|
|
1746
|
-
ping() {
|
|
1747
|
-
sendJson({ type: "ping" });
|
|
1748
|
-
},
|
|
1749
|
-
subscribe,
|
|
1750
|
-
onStatus(handler) {
|
|
1751
|
-
statusHandlers.add(handler);
|
|
1752
|
-
return () => statusHandlers.delete(handler);
|
|
1753
|
-
},
|
|
1754
|
-
onMessage(handler) {
|
|
1755
|
-
messageHandlers.add(handler);
|
|
1756
|
-
return () => messageHandlers.delete(handler);
|
|
1757
|
-
},
|
|
1758
|
-
onEvent(handler) {
|
|
1759
|
-
eventHandlers.add(handler);
|
|
1760
|
-
return () => eventHandlers.delete(handler);
|
|
1761
|
-
},
|
|
1762
|
-
onError(handler) {
|
|
1763
|
-
errorHandlers.add(handler);
|
|
1764
|
-
return () => errorHandlers.delete(handler);
|
|
1765
|
-
}
|
|
1766
|
-
};
|
|
1767
|
-
}
|
|
1768
|
-
const createGscdumpRealtimeClient = createPartnerRealtimeClient;
|
|
1769
1611
|
function formatSearchConsoleCount(value) {
|
|
1770
1612
|
return new Intl.NumberFormat("en").format(Math.max(0, Math.round(value)));
|
|
1771
1613
|
}
|
|
@@ -1893,120 +1735,123 @@ function totalSitemapErrors(sitemaps) {
|
|
|
1893
1735
|
function signedPct1(value) {
|
|
1894
1736
|
return `${value >= 0 ? "+" : ""}${value.toFixed(1)}%`;
|
|
1895
1737
|
}
|
|
1738
|
+
const SEARCH_CONSOLE_STAGES = {
|
|
1739
|
+
not_connected: {
|
|
1740
|
+
label: "Not connected",
|
|
1741
|
+
severity: "neutral",
|
|
1742
|
+
summary: "Search Console is not connected for this site yet.",
|
|
1743
|
+
primaryAction: "Connect Google Search Console so we can read discovery, indexing, and performance data.",
|
|
1744
|
+
nextStage: "waiting_for_data",
|
|
1745
|
+
sprintFindingTypes: []
|
|
1746
|
+
},
|
|
1747
|
+
waiting_for_data: {
|
|
1748
|
+
label: "Waiting for data",
|
|
1749
|
+
severity: "info",
|
|
1750
|
+
summary: "Search Console is connected, but there is not enough indexing data to diagnose the site yet.",
|
|
1751
|
+
primaryAction: "Let the first sync finish, then make sure a sitemap is submitted.",
|
|
1752
|
+
nextStage: "weak_discovery",
|
|
1753
|
+
sprintFindingTypes: []
|
|
1754
|
+
},
|
|
1755
|
+
weak_discovery: {
|
|
1756
|
+
label: "Weak discovery",
|
|
1757
|
+
severity: "warning",
|
|
1758
|
+
summary: "Google does not have a clean map of the pages you want indexed.",
|
|
1759
|
+
primaryAction: "Submit a clean sitemap that contains only canonical, indexable 200 URLs.",
|
|
1760
|
+
nextStage: "discovery_backlog",
|
|
1761
|
+
sprintFindingTypes: ["search-console-stage", "sitemap-missing"]
|
|
1762
|
+
},
|
|
1763
|
+
discovery_backlog: {
|
|
1764
|
+
label: "Discovery backlog",
|
|
1765
|
+
severity: "warning",
|
|
1766
|
+
summary: "Google knows these pages exist, but is not crawling them fast enough.",
|
|
1767
|
+
primaryAction: "Add internal links from indexed pages and remove low-value URLs from the sitemap.",
|
|
1768
|
+
nextStage: "crawl_blocked",
|
|
1769
|
+
sprintFindingTypes: ["search-console-stage"]
|
|
1770
|
+
},
|
|
1771
|
+
crawl_blocked: {
|
|
1772
|
+
label: "Crawl blocked",
|
|
1773
|
+
severity: "error",
|
|
1774
|
+
summary: "Google is trying to access pages, but technical access problems are blocking progress.",
|
|
1775
|
+
primaryAction: "Fix robots.txt blocks, server errors, broken URLs, and access failures before content work.",
|
|
1776
|
+
nextStage: "indexability_blocked",
|
|
1777
|
+
sprintFindingTypes: ["search-console-stage", "noindex-block"]
|
|
1778
|
+
},
|
|
1779
|
+
indexability_blocked: {
|
|
1780
|
+
label: "Indexability blocked",
|
|
1781
|
+
severity: "error",
|
|
1782
|
+
summary: "Google can reach pages, but index directives or canonical signals are preventing clean indexing.",
|
|
1783
|
+
primaryAction: "Remove accidental noindex directives and make canonical signals agree.",
|
|
1784
|
+
nextStage: "index_rejection",
|
|
1785
|
+
sprintFindingTypes: [
|
|
1786
|
+
"search-console-stage",
|
|
1787
|
+
"noindex-block",
|
|
1788
|
+
"canonicalisation"
|
|
1789
|
+
]
|
|
1790
|
+
},
|
|
1791
|
+
index_rejection: {
|
|
1792
|
+
label: "Index rejection",
|
|
1793
|
+
severity: "warning",
|
|
1794
|
+
summary: "Google is crawling pages but skipping too many of them from the index.",
|
|
1795
|
+
primaryAction: "Improve or consolidate crawled-but-not-indexed pages before publishing more.",
|
|
1796
|
+
nextStage: "partially_indexed",
|
|
1797
|
+
sprintFindingTypes: ["search-console-stage", "pages-not-indexed"]
|
|
1798
|
+
},
|
|
1799
|
+
partially_indexed: {
|
|
1800
|
+
label: "Partially indexed",
|
|
1801
|
+
severity: "warning",
|
|
1802
|
+
summary: "A meaningful share of the site is indexed, but coverage is still below a healthy level.",
|
|
1803
|
+
primaryAction: "Work through the largest remaining indexing blocker first.",
|
|
1804
|
+
nextStage: "indexed_invisible",
|
|
1805
|
+
sprintFindingTypes: ["search-console-stage", "pages-not-indexed"]
|
|
1806
|
+
},
|
|
1807
|
+
indexed_invisible: {
|
|
1808
|
+
label: "Indexed but invisible",
|
|
1809
|
+
severity: "warning",
|
|
1810
|
+
summary: "Pages are indexed, but too many are not earning impressions in Search.",
|
|
1811
|
+
primaryAction: "Improve query targeting, titles, headings, internal links, and page depth.",
|
|
1812
|
+
nextStage: "visible_not_clicked",
|
|
1813
|
+
sprintFindingTypes: ["search-console-stage"]
|
|
1814
|
+
},
|
|
1815
|
+
visible_not_clicked: {
|
|
1816
|
+
label: "Visible but not clicked",
|
|
1817
|
+
severity: "warning",
|
|
1818
|
+
summary: "Google is showing your pages, but searchers are not clicking often enough.",
|
|
1819
|
+
primaryAction: "Rewrite titles and descriptions for the queries already producing impressions.",
|
|
1820
|
+
nextStage: "ranking_stalled",
|
|
1821
|
+
sprintFindingTypes: ["search-console-stage", "ctr-outliers"]
|
|
1822
|
+
},
|
|
1823
|
+
ranking_stalled: {
|
|
1824
|
+
label: "Ranking but stalled",
|
|
1825
|
+
severity: "info",
|
|
1826
|
+
summary: "The site has search visibility, but many pages are not yet ranking in useful positions.",
|
|
1827
|
+
primaryAction: "Prioritise striking-distance pages, refresh content, and add internal links.",
|
|
1828
|
+
nextStage: "healthy_growth_ready",
|
|
1829
|
+
sprintFindingTypes: ["striking-distance", "internal-linking"]
|
|
1830
|
+
},
|
|
1831
|
+
declining_visibility: {
|
|
1832
|
+
label: "Declining visibility",
|
|
1833
|
+
severity: "error",
|
|
1834
|
+
summary: "Search visibility is dropping compared with the previous period.",
|
|
1835
|
+
primaryAction: "Review affected pages, recent releases, competitors, and SERP changes before expanding.",
|
|
1836
|
+
nextStage: "healthy_growth_ready",
|
|
1837
|
+
sprintFindingTypes: ["search-console-stage", "negative-movers"]
|
|
1838
|
+
},
|
|
1839
|
+
healthy_growth_ready: {
|
|
1840
|
+
label: "Healthy",
|
|
1841
|
+
severity: "success",
|
|
1842
|
+
summary: "Google can discover, index, and show your pages.",
|
|
1843
|
+
primaryAction: "Push striking-distance pages (positions 11 to 20) and close content gaps to grow impressions.",
|
|
1844
|
+
nextStage: null,
|
|
1845
|
+
sprintFindingTypes: ["striking-distance", "competitor-content-gap"]
|
|
1846
|
+
}
|
|
1847
|
+
};
|
|
1896
1848
|
function stage(key, evidence) {
|
|
1849
|
+
const definition = SEARCH_CONSOLE_STAGES[key];
|
|
1897
1850
|
return {
|
|
1898
1851
|
key,
|
|
1899
1852
|
evidence,
|
|
1900
|
-
...
|
|
1901
|
-
|
|
1902
|
-
label: "Not connected",
|
|
1903
|
-
severity: "neutral",
|
|
1904
|
-
summary: "Search Console is not connected for this site yet.",
|
|
1905
|
-
primaryAction: "Connect Google Search Console so we can read discovery, indexing, and performance data.",
|
|
1906
|
-
nextStage: "waiting_for_data",
|
|
1907
|
-
sprintFindingTypes: []
|
|
1908
|
-
},
|
|
1909
|
-
waiting_for_data: {
|
|
1910
|
-
label: "Waiting for data",
|
|
1911
|
-
severity: "info",
|
|
1912
|
-
summary: "Search Console is connected, but there is not enough indexing data to diagnose the site yet.",
|
|
1913
|
-
primaryAction: "Let the first sync finish, then make sure a sitemap is submitted.",
|
|
1914
|
-
nextStage: "weak_discovery",
|
|
1915
|
-
sprintFindingTypes: []
|
|
1916
|
-
},
|
|
1917
|
-
weak_discovery: {
|
|
1918
|
-
label: "Weak discovery",
|
|
1919
|
-
severity: "warning",
|
|
1920
|
-
summary: "Google does not have a clean map of the pages you want indexed.",
|
|
1921
|
-
primaryAction: "Submit a clean sitemap that contains only canonical, indexable 200 URLs.",
|
|
1922
|
-
nextStage: "discovery_backlog",
|
|
1923
|
-
sprintFindingTypes: ["search-console-stage", "sitemap-missing"]
|
|
1924
|
-
},
|
|
1925
|
-
discovery_backlog: {
|
|
1926
|
-
label: "Discovery backlog",
|
|
1927
|
-
severity: "warning",
|
|
1928
|
-
summary: "Google knows these pages exist, but is not crawling them fast enough.",
|
|
1929
|
-
primaryAction: "Add internal links from indexed pages and remove low-value URLs from the sitemap.",
|
|
1930
|
-
nextStage: "crawl_blocked",
|
|
1931
|
-
sprintFindingTypes: ["search-console-stage"]
|
|
1932
|
-
},
|
|
1933
|
-
crawl_blocked: {
|
|
1934
|
-
label: "Crawl blocked",
|
|
1935
|
-
severity: "error",
|
|
1936
|
-
summary: "Google is trying to access pages, but technical access problems are blocking progress.",
|
|
1937
|
-
primaryAction: "Fix robots.txt blocks, server errors, broken URLs, and access failures before content work.",
|
|
1938
|
-
nextStage: "indexability_blocked",
|
|
1939
|
-
sprintFindingTypes: ["search-console-stage", "noindex-block"]
|
|
1940
|
-
},
|
|
1941
|
-
indexability_blocked: {
|
|
1942
|
-
label: "Indexability blocked",
|
|
1943
|
-
severity: "error",
|
|
1944
|
-
summary: "Google can reach pages, but index directives or canonical signals are preventing clean indexing.",
|
|
1945
|
-
primaryAction: "Remove accidental noindex directives and make canonical signals agree.",
|
|
1946
|
-
nextStage: "index_rejection",
|
|
1947
|
-
sprintFindingTypes: [
|
|
1948
|
-
"search-console-stage",
|
|
1949
|
-
"noindex-block",
|
|
1950
|
-
"canonicalisation"
|
|
1951
|
-
]
|
|
1952
|
-
},
|
|
1953
|
-
index_rejection: {
|
|
1954
|
-
label: "Index rejection",
|
|
1955
|
-
severity: "warning",
|
|
1956
|
-
summary: "Google is crawling pages but skipping too many of them from the index.",
|
|
1957
|
-
primaryAction: "Improve or consolidate crawled-but-not-indexed pages before publishing more.",
|
|
1958
|
-
nextStage: "partially_indexed",
|
|
1959
|
-
sprintFindingTypes: ["search-console-stage", "pages-not-indexed"]
|
|
1960
|
-
},
|
|
1961
|
-
partially_indexed: {
|
|
1962
|
-
label: "Partially indexed",
|
|
1963
|
-
severity: "warning",
|
|
1964
|
-
summary: "A meaningful share of the site is indexed, but coverage is still below a healthy level.",
|
|
1965
|
-
primaryAction: "Work through the largest remaining indexing blocker first.",
|
|
1966
|
-
nextStage: "indexed_invisible",
|
|
1967
|
-
sprintFindingTypes: ["search-console-stage", "pages-not-indexed"]
|
|
1968
|
-
},
|
|
1969
|
-
indexed_invisible: {
|
|
1970
|
-
label: "Indexed but invisible",
|
|
1971
|
-
severity: "warning",
|
|
1972
|
-
summary: "Pages are indexed, but too many are not earning impressions in Search.",
|
|
1973
|
-
primaryAction: "Improve query targeting, titles, headings, internal links, and page depth.",
|
|
1974
|
-
nextStage: "visible_not_clicked",
|
|
1975
|
-
sprintFindingTypes: ["search-console-stage"]
|
|
1976
|
-
},
|
|
1977
|
-
visible_not_clicked: {
|
|
1978
|
-
label: "Visible but not clicked",
|
|
1979
|
-
severity: "warning",
|
|
1980
|
-
summary: "Google is showing your pages, but searchers are not clicking often enough.",
|
|
1981
|
-
primaryAction: "Rewrite titles and descriptions for the queries already producing impressions.",
|
|
1982
|
-
nextStage: "ranking_stalled",
|
|
1983
|
-
sprintFindingTypes: ["search-console-stage", "ctr-outliers"]
|
|
1984
|
-
},
|
|
1985
|
-
ranking_stalled: {
|
|
1986
|
-
label: "Ranking but stalled",
|
|
1987
|
-
severity: "info",
|
|
1988
|
-
summary: "The site has search visibility, but many pages are not yet ranking in useful positions.",
|
|
1989
|
-
primaryAction: "Prioritise striking-distance pages, refresh content, and add internal links.",
|
|
1990
|
-
nextStage: "healthy_growth_ready",
|
|
1991
|
-
sprintFindingTypes: ["striking-distance", "internal-linking"]
|
|
1992
|
-
},
|
|
1993
|
-
declining_visibility: {
|
|
1994
|
-
label: "Declining visibility",
|
|
1995
|
-
severity: "error",
|
|
1996
|
-
summary: "Search visibility is dropping compared with the previous period.",
|
|
1997
|
-
primaryAction: "Review affected pages, recent releases, competitors, and SERP changes before expanding.",
|
|
1998
|
-
nextStage: "healthy_growth_ready",
|
|
1999
|
-
sprintFindingTypes: ["search-console-stage", "negative-movers"]
|
|
2000
|
-
},
|
|
2001
|
-
healthy_growth_ready: {
|
|
2002
|
-
label: "Healthy",
|
|
2003
|
-
severity: "success",
|
|
2004
|
-
summary: "Google can discover, index, and show your pages.",
|
|
2005
|
-
primaryAction: "Push striking-distance pages (positions 11 to 20) and close content gaps to grow impressions.",
|
|
2006
|
-
nextStage: null,
|
|
2007
|
-
sprintFindingTypes: ["striking-distance", "competitor-content-gap"]
|
|
2008
|
-
}
|
|
2009
|
-
}[key]
|
|
1853
|
+
...definition,
|
|
1854
|
+
sprintFindingTypes: [...definition.sprintFindingTypes]
|
|
2010
1855
|
};
|
|
2011
1856
|
}
|
|
2012
1857
|
const ESTABLISHED_IMPRESSIONS_28D$1 = 2e4;
|
|
@@ -2039,8 +1884,13 @@ function classifySearchConsoleStage(input) {
|
|
|
2039
1884
|
const crawled = countSearchConsoleIssues(issues, "crawled_not_indexed");
|
|
2040
1885
|
const hardBlocks = countSearchConsoleIssues(issues, "blocked_robots", "server_error", "access_denied", "forbidden") + (input.crawlAuditBlockerCount ?? 0);
|
|
2041
1886
|
const canonicalMismatches = Math.min(notIndexed, input.canonicalMismatchCount ?? countSearchConsoleIssues(issues, "canonical_mismatch"));
|
|
2042
|
-
|
|
2043
|
-
|
|
1887
|
+
let visibleNoClickPages = 0;
|
|
1888
|
+
let poorPositionPages = 0;
|
|
1889
|
+
for (const page of input.pageInventory ?? []) {
|
|
1890
|
+
if (page.impressions < 50) continue;
|
|
1891
|
+
if (page.clicks === 0) visibleNoClickPages++;
|
|
1892
|
+
if ((page.position ?? 0) > 20) poorPositionPages++;
|
|
1893
|
+
}
|
|
2044
1894
|
const ctrOutlierCount = input.ctrOutlierCount ?? 0;
|
|
2045
1895
|
const traj = input.trajectory ?? null;
|
|
2046
1896
|
const impressions28d = input.impressions28d ?? null;
|
|
@@ -2508,5 +2358,4 @@ function readWebhookHeaders(headers) {
|
|
|
2508
2358
|
signature: headers.signature ?? null
|
|
2509
2359
|
};
|
|
2510
2360
|
}
|
|
2511
|
-
|
|
2512
|
-
export { ARCHETYPE_EXECUTION_CLASS, CANONICAL_WEBHOOK_EVENTS, COMPARE_OPTIONS, COUNTRY_NAMES, CWV_GOOD_CLS, CWV_GOOD_INP, CWV_GOOD_LCP, CWV_POOR_CLS, CWV_POOR_INP, CWV_POOR_LCP, GSC_COLUMN_OPTIONS, GSC_PERIOD_OPTIONS, GSC_PERIOD_OPTIONS_LONG, GSC_STABLE_LATENCY_DAYS, PERIOD_PRESETS, PartnerApiError, SITE_TYPE_BASELINE, VALID_WEBHOOK_EVENTS, WEBHOOK_CONTRACT_VERSION, WEBHOOK_CONTRACT_VERSION_HEADER, WEBHOOK_DELIVERY_HEADER, WEBHOOK_EVENT_HEADER, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_TIMESTAMP_HEADER, analyticsStatusToSyncStatus, andFilter, classifyGscError, classifyHealthStage, classifyReachStage, classifySearchConsoleStage, classifySiteTriage, coerceRowMetrics, compareRange, countryName, coverageLabel, coverageLabels, createAnalyticsClient, createGscdumpClient, createGscdumpRealtimeClient, createPartnerClient, createPartnerRealtimeClient, cwvBucket, dateFilter, defineGscAnalyzer, derivePeerStanding, deriveSiteBaseline, enrichIssueDetails, findLifecycleSite, formatPartnerError, getGscUnstableCutoffDate, gscConsoleUrl, investigationStatusConfig, isCustomPeriod, isPartnerError, issueDetails, issueGroups, issueTypeToGroup, lifecycleSiteToSyncStatus, lifecycleSiteToUserSite, normalizeSiteType, nuxtSeoTips, parseCustomPeriod, parseWebhookPayload, parseWebhookPayloadResult, partnerErrorToException, periodToDateRange, periodToDays, positionFor, reachLivenessRatio, readWebhookHeaders, serializeWebhookPayload, severityOrder, siteTypeBaseline, siteUrlToHostname, splitOpportunityTitle, summarizeDailyRows, toPartnerError, truncateQuery, verifyWebhookSignature, weightedAnonPct };
|
|
2361
|
+
export { ARCHETYPE_EXECUTION_CLASS, CANONICAL_WEBHOOK_EVENTS, COMPARE_OPTIONS, COUNTRY_NAMES, CWV_GOOD_CLS, CWV_GOOD_INP, CWV_GOOD_LCP, CWV_POOR_CLS, CWV_POOR_INP, CWV_POOR_LCP, DEFAULT_SEARCH_TYPE, GSC_COLUMN_OPTIONS, GSC_PERIOD_OPTIONS, GSC_PERIOD_OPTIONS_LONG, GSC_STABLE_LATENCY_DAYS, PERIOD_PRESETS, PartnerApiError, SITE_TYPE_BASELINE, VALID_WEBHOOK_EVENTS, WEBHOOK_CONTRACT_VERSION, WEBHOOK_CONTRACT_VERSION_HEADER, WEBHOOK_DELIVERY_HEADER, WEBHOOK_EVENT_HEADER, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_TIMESTAMP_HEADER, analyticsStatusToSyncStatus, andFilter, arbitrarySql, auxCloudOnly, classifyGscError, classifyHealthStage, classifyReachStage, classifySearchConsoleStage, classifySiteTriage, coerceRowMetrics, compareRange, countryName, coverageLabel, coverageLabels, createAnalyticsClient, createPartnerClient, cwvBucket, dateFilter, dateRangeOptionsQuery, defineGscAnalyzer, derivePeerStanding, deriveSiteBaseline, enrichIssueDetails, entityDailySparkline, entityDailyTimeseries, findLifecycleSite, formatPartnerError, getGscUnstableCutoffDate, gscConsoleUrl, investigationStatusConfig, isCustomPeriod, isPartnerError, issueDetails, issueGroups, issueTypeToGroup, lifecycleSiteToSyncStatus, lifecycleSiteToUserSite, multiSeriesStackedDaily, normalizeSiteType, nuxtSeoTips, parseCustomPeriod, parseWebhookPayload, parseWebhookPayloadResult, partnerErrorToException, periodToDateRange, periodToDays, positionFor, reachLivenessRatio, readWebhookHeaders, searchTypeQuery, serializeWebhookPayload, severityOrder, singleRowLookup, siteDailyTimeseries, siteTypeBaseline, siteUrlToHostname, sourceInfoQuery, splitOpportunityTitle, summarizeDailyRows, tablesQuery, toPartnerError, topNBreakdown, truncateQuery, twoDimensionDetail, verifyWebhookSignature, weightedAnonPct, withDefaultSearchType };
|
package/dist/query.mjs
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
import { __exportAll, __reExport } from "./_chunks/rolldown-runtime.mjs";
|
|
2
1
|
export * from "gscdump/query";
|
|
3
|
-
|
|
4
|
-
import * as import_gscdump_query from "gscdump/query";
|
|
5
|
-
__reExport(query_exports, import_gscdump_query);
|
|
6
|
-
export { query_exports };
|
|
2
|
+
export {};
|
package/dist/v1/index.d.mts
CHANGED
|
@@ -71,7 +71,21 @@ declare function isGscdumpV1Error(error: unknown): error is GscdumpV1Error;
|
|
|
71
71
|
interface GscdumpV1Client {
|
|
72
72
|
execute: <TId extends GscdumpV1OperationId>(operation: TId, input: GscdumpV1OperationInput<TId>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<TId>>;
|
|
73
73
|
getUserLifecycle: (input: GscdumpV1OperationInput<'partner.users.lifecycle.get'>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<'partner.users.lifecycle.get'>>;
|
|
74
|
+
listAvailableSites: (input: GscdumpV1OperationInput<'partner.users.sites.available.list'>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<'partner.users.sites.available.list'>>;
|
|
75
|
+
createSite: (input: GscdumpV1OperationInput<'partner.users.sites.create'>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<'partner.users.sites.create'>>;
|
|
76
|
+
createUser: (input: GscdumpV1OperationInput<'partner.users.create'>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<'partner.users.create'>>;
|
|
77
|
+
updateUserTokens: (input: GscdumpV1OperationInput<'partner.users.tokens.update'>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<'partner.users.tokens.update'>>;
|
|
78
|
+
getSiteIndexing: (input: GscdumpV1OperationInput<'partner.sites.indexing.get'>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<'partner.sites.indexing.get'>>;
|
|
79
|
+
listSiteIndexingUrls: (input: GscdumpV1OperationInput<'partner.sites.indexing.urls.list'>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<'partner.sites.indexing.urls.list'>>;
|
|
80
|
+
getSiteIndexingDiagnostics: (input: GscdumpV1OperationInput<'partner.sites.indexing.diagnostics.get'>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<'partner.sites.indexing.diagnostics.get'>>;
|
|
81
|
+
getSiteSitemaps: (input: GscdumpV1OperationInput<'partner.sites.sitemaps.get'>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<'partner.sites.sitemaps.get'>>;
|
|
82
|
+
getSiteSitemapChanges: (input: GscdumpV1OperationInput<'partner.sites.sitemaps.changes.get'>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<'partner.sites.sitemaps.changes.get'>>;
|
|
83
|
+
getSiteAnalysis: (input: GscdumpV1OperationInput<'partner.sites.analysis.get'>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<'partner.sites.analysis.get'>>;
|
|
84
|
+
getSiteAnalysisBundle: (input: GscdumpV1OperationInput<'partner.sites.analysis.bundle.get'>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<'partner.sites.analysis.bundle.get'>>;
|
|
85
|
+
deleteSite: (input: GscdumpV1OperationInput<'partner.sites.delete'>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<'partner.sites.delete'>>;
|
|
74
86
|
queryAnalyticsRows: (input: GscdumpV1OperationInput<'analytics.rows.query'>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<'analytics.rows.query'>>;
|
|
87
|
+
queryAnalyticsReport: (input: GscdumpV1OperationInput<'analytics.reports.query'>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<'analytics.reports.query'>>;
|
|
88
|
+
queryAnalyticsReportDetail: (input: GscdumpV1OperationInput<'analytics.reports.detail.query'>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<'analytics.reports.detail.query'>>;
|
|
75
89
|
getRealtimeStreamHead: (input?: GscdumpV1OperationInput<'realtime.stream.head.get'>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<'realtime.stream.head.get'>>;
|
|
76
90
|
createRealtimeTicket: (input: GscdumpV1OperationInput<'realtime.tickets.create'>, options?: GscdumpV1ExecuteOptions) => Promise<GscdumpV1OperationResponse<'realtime.tickets.create'>>;
|
|
77
91
|
}
|
package/dist/v1/index.mjs
CHANGED
|
@@ -155,11 +155,12 @@ async function resolveBaseHeaders(resolver) {
|
|
|
155
155
|
}
|
|
156
156
|
async function buildRequestHeaders(options, operation, prepared, executeOptions) {
|
|
157
157
|
try {
|
|
158
|
-
const
|
|
158
|
+
const [baseHeaders, credential] = await Promise.all([resolveBaseHeaders(options.headers), resolveCredential(options.credential)]);
|
|
159
|
+
const headers = new Headers(baseHeaders);
|
|
159
160
|
for (const [key, value] of Object.entries(prepared.headers)) if (value !== void 0) headers.set(key, String(value));
|
|
160
161
|
headers.delete("x-api-key");
|
|
161
162
|
headers.set("accept", "application/json");
|
|
162
|
-
headers.set("authorization", `Bearer ${
|
|
163
|
+
headers.set("authorization", `Bearer ${credential}`);
|
|
163
164
|
if (executeOptions.idempotencyKey) headers.set("idempotency-key", executeOptions.idempotencyKey);
|
|
164
165
|
if (prepared.body !== void 0) headers.set("content-type", "application/json");
|
|
165
166
|
return headers;
|
|
@@ -362,11 +363,38 @@ function createGscdumpV1Client(options) {
|
|
|
362
363
|
return {
|
|
363
364
|
execute,
|
|
364
365
|
getUserLifecycle: (input, executeOptions) => execute("partner.users.lifecycle.get", input, executeOptions),
|
|
366
|
+
listAvailableSites: (input, executeOptions) => execute("partner.users.sites.available.list", input, executeOptions),
|
|
367
|
+
createSite: (input, executeOptions) => execute("partner.users.sites.create", input, executeOptions),
|
|
368
|
+
createUser: (input, executeOptions) => execute("partner.users.create", input, executeOptions),
|
|
369
|
+
updateUserTokens: (input, executeOptions) => execute("partner.users.tokens.update", input, executeOptions),
|
|
370
|
+
getSiteIndexing: (input, executeOptions) => execute("partner.sites.indexing.get", input, executeOptions),
|
|
371
|
+
listSiteIndexingUrls: (input, executeOptions) => execute("partner.sites.indexing.urls.list", input, executeOptions),
|
|
372
|
+
getSiteIndexingDiagnostics: (input, executeOptions) => execute("partner.sites.indexing.diagnostics.get", input, executeOptions),
|
|
373
|
+
getSiteSitemaps: (input, executeOptions) => execute("partner.sites.sitemaps.get", input, executeOptions),
|
|
374
|
+
getSiteSitemapChanges: (input, executeOptions) => execute("partner.sites.sitemaps.changes.get", input, executeOptions),
|
|
375
|
+
getSiteAnalysis: (input, executeOptions) => execute("partner.sites.analysis.get", input, executeOptions),
|
|
376
|
+
getSiteAnalysisBundle: (input, executeOptions) => execute("partner.sites.analysis.bundle.get", input, executeOptions),
|
|
377
|
+
deleteSite: (input, executeOptions) => execute("partner.sites.delete", input, executeOptions),
|
|
365
378
|
queryAnalyticsRows: (input, executeOptions) => execute("analytics.rows.query", input, executeOptions),
|
|
379
|
+
queryAnalyticsReport: (input, executeOptions) => execute("analytics.reports.query", input, executeOptions),
|
|
380
|
+
queryAnalyticsReportDetail: (input, executeOptions) => execute("analytics.reports.detail.query", input, executeOptions),
|
|
366
381
|
getRealtimeStreamHead: (input = {}, executeOptions) => execute("realtime.stream.head.get", input, executeOptions),
|
|
367
382
|
createRealtimeTicket: (input, executeOptions) => execute("realtime.tickets.create", input, executeOptions)
|
|
368
383
|
};
|
|
369
384
|
}
|
|
385
|
+
function utf8Size(value) {
|
|
386
|
+
let bytes = 0;
|
|
387
|
+
for (let index = 0; index < value.length; index++) {
|
|
388
|
+
const code = value.charCodeAt(index);
|
|
389
|
+
if (code <= 127) bytes++;
|
|
390
|
+
else if (code <= 2047) bytes += 2;
|
|
391
|
+
else if (code >= 55296 && code <= 56319 && index + 1 < value.length && value.charCodeAt(index + 1) >= 56320 && value.charCodeAt(index + 1) <= 57343) {
|
|
392
|
+
bytes += 4;
|
|
393
|
+
index++;
|
|
394
|
+
} else bytes += 3;
|
|
395
|
+
}
|
|
396
|
+
return bytes;
|
|
397
|
+
}
|
|
370
398
|
const GSCDUMP_REALTIME_V1_SDK_VERSION = "0.37.7";
|
|
371
399
|
var GscdumpRealtimeV1Error = class extends Error {
|
|
372
400
|
tag = "GscdumpRealtimeV1Error";
|
|
@@ -417,13 +445,14 @@ function defaultRuntime() {
|
|
|
417
445
|
now: () => Date.now()
|
|
418
446
|
};
|
|
419
447
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
448
|
+
const UTF8_DECODER = new TextDecoder();
|
|
449
|
+
const REALTIME_EVENT_NAMES = new Set(REALTIME_V1_EVENT_NAMES);
|
|
450
|
+
const REALTIME_RESOURCE_TYPES = new Set(REALTIME_V1_RESOURCE_TYPES);
|
|
451
|
+
const APPLIED_EVENT_CACHE_MAX = 1e4;
|
|
423
452
|
async function messageText(raw) {
|
|
424
453
|
if (typeof raw === "string") return raw;
|
|
425
|
-
if (raw instanceof ArrayBuffer) return
|
|
426
|
-
if (ArrayBuffer.isView(raw)) return
|
|
454
|
+
if (raw instanceof ArrayBuffer) return UTF8_DECODER.decode(raw);
|
|
455
|
+
if (ArrayBuffer.isView(raw)) return UTF8_DECODER.decode(new Uint8Array(raw.buffer, raw.byteOffset, raw.byteLength));
|
|
427
456
|
if (typeof Blob !== "undefined" && raw instanceof Blob) return raw.text();
|
|
428
457
|
throw new TypeError("Realtime frames must be text or UTF-8 binary data.");
|
|
429
458
|
}
|
|
@@ -472,6 +501,7 @@ function createGscdumpRealtimeV1Client(options) {
|
|
|
472
501
|
const eventFailures = /* @__PURE__ */ new Map();
|
|
473
502
|
const appliedEventIds = /* @__PURE__ */ new Set();
|
|
474
503
|
const appliedEventOrder = [];
|
|
504
|
+
let appliedEventCursor = 0;
|
|
475
505
|
function getSnapshot() {
|
|
476
506
|
return {
|
|
477
507
|
transport,
|
|
@@ -605,23 +635,25 @@ function createGscdumpRealtimeV1Client(options) {
|
|
|
605
635
|
const key = eventDedupeKey(stream, id);
|
|
606
636
|
if (appliedEventIds.has(key)) return;
|
|
607
637
|
appliedEventIds.add(key);
|
|
608
|
-
appliedEventOrder.push(key);
|
|
609
|
-
|
|
610
|
-
const oldest = appliedEventOrder
|
|
638
|
+
if (appliedEventOrder.length < APPLIED_EVENT_CACHE_MAX) appliedEventOrder.push(key);
|
|
639
|
+
else {
|
|
640
|
+
const oldest = appliedEventOrder[appliedEventCursor];
|
|
611
641
|
if (oldest) appliedEventIds.delete(oldest);
|
|
642
|
+
appliedEventOrder[appliedEventCursor] = key;
|
|
643
|
+
appliedEventCursor = (appliedEventCursor + 1) % APPLIED_EVENT_CACHE_MAX;
|
|
612
644
|
}
|
|
613
645
|
}
|
|
614
646
|
function eventFailureKey(event) {
|
|
615
647
|
return `${event.cursor?.streamId ?? "ephemeral"}:${event.id}:${event.cursor?.sequence ?? "ephemeral"}`;
|
|
616
648
|
}
|
|
617
649
|
function eventForRequiredEffect(event) {
|
|
618
|
-
return
|
|
650
|
+
return REALTIME_EVENT_NAMES.has(event.name) && event.eventVersion === 1 ? event : {
|
|
619
651
|
...event,
|
|
620
652
|
data: null
|
|
621
653
|
};
|
|
622
654
|
}
|
|
623
655
|
function eventAdvisories(event) {
|
|
624
|
-
if (!
|
|
656
|
+
if (!REALTIME_EVENT_NAMES.has(event.name)) observe({
|
|
625
657
|
type: "advisory",
|
|
626
658
|
code: "unknown_event",
|
|
627
659
|
event
|
|
@@ -631,7 +663,7 @@ function createGscdumpRealtimeV1Client(options) {
|
|
|
631
663
|
code: "unsupported_event_version",
|
|
632
664
|
event
|
|
633
665
|
});
|
|
634
|
-
if (event.changes.some((change) => !
|
|
666
|
+
if (event.changes.some((change) => !REALTIME_RESOURCE_TYPES.has(change.type))) observe({
|
|
635
667
|
type: "advisory",
|
|
636
668
|
code: "unknown_resource",
|
|
637
669
|
event
|
|
@@ -1058,7 +1090,8 @@ function createGscdumpRealtimeV1Client(options) {
|
|
|
1058
1090
|
context.lastPongAt = runtime.now();
|
|
1059
1091
|
return;
|
|
1060
1092
|
}
|
|
1061
|
-
|
|
1093
|
+
const textBytes = utf8Size(text);
|
|
1094
|
+
if (textBytes > GSCDUMP_REALTIME_LIMITS.outboundFrameMaxBytes) throw new GscdumpRealtimeV1Error({
|
|
1062
1095
|
code: "protocol_error",
|
|
1063
1096
|
message: "A server frame exceeded the v1 outbound frame limit.",
|
|
1064
1097
|
retryable: false,
|
|
@@ -1086,8 +1119,7 @@ function createGscdumpRealtimeV1Client(options) {
|
|
|
1086
1119
|
cause: parsed.error
|
|
1087
1120
|
});
|
|
1088
1121
|
if (parsed.data.type === "event") {
|
|
1089
|
-
|
|
1090
|
-
if (utf8Size(text) > eventLimit) throw new GscdumpRealtimeV1Error({
|
|
1122
|
+
if (textBytes > (parsed.data.delivery === "durable" ? GSCDUMP_REALTIME_LIMITS.durableEventMaxBytes : GSCDUMP_REALTIME_LIMITS.ephemeralEventMaxBytes)) throw new GscdumpRealtimeV1Error({
|
|
1091
1123
|
code: "protocol_error",
|
|
1092
1124
|
message: `A ${parsed.data.delivery} event exceeded its v1 size limit.`,
|
|
1093
1125
|
retryable: false,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gscdump/sdk",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.40.1",
|
|
5
5
|
"description": "Consumer SDK for hosted gscdump.com integrations.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Harlan Wilton",
|
|
@@ -49,10 +49,10 @@
|
|
|
49
49
|
"date-fns": "^4.4.0",
|
|
50
50
|
"ofetch": "^1.5.1",
|
|
51
51
|
"zod": "^4.4.3",
|
|
52
|
-
"@gscdump/
|
|
53
|
-
"@gscdump/
|
|
54
|
-
"gscdump": "0.
|
|
55
|
-
"
|
|
52
|
+
"@gscdump/analysis": "0.40.1",
|
|
53
|
+
"@gscdump/contracts": "0.40.1",
|
|
54
|
+
"@gscdump/engine": "0.40.1",
|
|
55
|
+
"gscdump": "0.40.1"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"typescript": "^6.0.3",
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
5
|
-
var __exportAll = (all, no_symbols) => {
|
|
6
|
-
let target = {};
|
|
7
|
-
for (var name in all) __defProp(target, name, {
|
|
8
|
-
get: all[name],
|
|
9
|
-
enumerable: true
|
|
10
|
-
});
|
|
11
|
-
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
12
|
-
return target;
|
|
13
|
-
};
|
|
14
|
-
var __copyProps = (to, from, except, desc) => {
|
|
15
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
16
|
-
key = keys[i];
|
|
17
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
18
|
-
get: ((k) => from[k]).bind(null, key),
|
|
19
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
return to;
|
|
23
|
-
};
|
|
24
|
-
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
25
|
-
export { __exportAll, __reExport };
|