gscdump 0.11.3 → 0.11.5

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.
@@ -1,80 +1,2 @@
1
- /**
2
- * Canonical cross-package contracts. Type-only zero runtime cost.
3
- *
4
- * Imported by @gscdump/engine, @gscdump/analysis, @gscdump/cli, @gscdump/mcp,
5
- * @gscdump/cloud as the single source of truth for cross-cutting types so
6
- * schema identifiers, tenant shape, and analyzer IO can't drift across
7
- * packages.
8
- */
9
- /** Logical table / dataset identifier. Canonical across query builder + storage engine. */
10
- type TableName = 'pages' | 'keywords' | 'countries' | 'devices' | 'page_keywords' | 'search_appearance';
11
- /** Untyped row shape crossing storage/query boundaries. */
12
- type Row = Record<string, unknown>;
13
- type ColumnType = 'DATE' | 'VARCHAR' | 'INTEGER' | 'BIGINT' | 'DOUBLE';
14
- interface ColumnDef {
15
- name: string;
16
- type: ColumnType;
17
- nullable: boolean;
18
- }
19
- interface TableSchema {
20
- name: TableName;
21
- columns: ColumnDef[];
22
- sortKey: string[];
23
- /**
24
- * Monotonically increasing version. Tagged onto every manifest entry written
25
- * for this table; bump when columns are added/removed/retyped so readers can
26
- * detect stale on-disk data.
27
- */
28
- version: number;
29
- }
30
- /** Tenant identity for multi-user / multi-site storage. */
31
- interface TenantCtx {
32
- userId: string;
33
- siteId?: string;
34
- }
35
- /**
36
- * Dimensions accepted by the Google Search Console Search Analytics API.
37
- *
38
- * This intentionally excludes package-only logical dimensions such as
39
- * `queryCanonical`; host apps must route those through an engine-backed path.
40
- */
41
- type GscSearchAnalyticsDimension = 'page' | 'query' | 'country' | 'device' | 'date' | 'searchAppearance';
42
- type GscSearchAnalyticsFilterOperator = 'equals' | 'notEquals' | 'contains' | 'notContains' | 'includingRegex' | 'excludingRegex';
43
- interface GscSearchAnalyticsFilter {
44
- dimension: GscSearchAnalyticsDimension;
45
- expression: string;
46
- operator?: GscSearchAnalyticsFilterOperator;
47
- }
48
- interface GscSearchAnalyticsFilterGroup {
49
- groupType?: 'and' | 'or';
50
- filters: GscSearchAnalyticsFilter[];
51
- }
52
- type GscSearchType = 'web' | 'image' | 'video' | 'news' | 'discover' | 'googleNews';
53
- /**
54
- * Canonical host-facing Search Analytics request body.
55
- *
56
- * Google's generated client type also has deprecated/alternate fields. The
57
- * gscdump query builder emits `searchType`, so apps should forward that field
58
- * unchanged rather than translating it to `type`.
59
- */
60
- interface GscSearchAnalyticsRequest {
61
- startDate: string;
62
- endDate: string;
63
- dimensions?: GscSearchAnalyticsDimension[];
64
- dimensionFilterGroups?: GscSearchAnalyticsFilterGroup[];
65
- rowLimit?: number;
66
- startRow?: number;
67
- searchType?: GscSearchType;
68
- }
69
- interface GscSearchAnalyticsRow {
70
- keys: string[];
71
- clicks: number;
72
- impressions: number;
73
- ctr: number;
74
- position: number;
75
- }
76
- interface GscSearchAnalyticsResponse {
77
- rows?: GscSearchAnalyticsRow[];
78
- responseAggregationType?: string;
79
- }
80
- export { ColumnDef, ColumnType, GscSearchAnalyticsDimension, GscSearchAnalyticsFilter, GscSearchAnalyticsFilterGroup, GscSearchAnalyticsFilterOperator, GscSearchAnalyticsRequest, GscSearchAnalyticsResponse, GscSearchAnalyticsRow, GscSearchType, Row, TableName, TableSchema, TenantCtx };
1
+ import { ColumnDef, ColumnType, GscSearchAnalyticsDimension, GscSearchAnalyticsFilter, GscSearchAnalyticsFilterGroup, GscSearchAnalyticsFilterOperator, GscSearchAnalyticsRequest, GscSearchAnalyticsResponse, GscSearchAnalyticsRow, GscSearchType, Row, TableName, TableSchema, TenantCtx } from "@gscdump/contracts";
2
+ export { type ColumnDef, type ColumnType, type GscSearchAnalyticsDimension, type GscSearchAnalyticsFilter, type GscSearchAnalyticsFilterGroup, type GscSearchAnalyticsFilterOperator, type GscSearchAnalyticsRequest, type GscSearchAnalyticsResponse, type GscSearchAnalyticsRow, type GscSearchType, type Row, type TableName, type TableSchema, type TenantCtx };
package/dist/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { $Fetch, FetchOptions } from "ofetch";
2
2
  import { indexing_v3 } from "@googleapis/indexing/build/v3";
3
+ import { GscSearchAnalyticsRequest } from "@gscdump/contracts";
3
4
  import { searchconsole_v1 } from "@googleapis/searchconsole/build/v1";
4
5
  /**
5
6
  * Batch runner with optional concurrency, inter-call delay, and progress.
@@ -12,40 +13,6 @@ declare function runSequentialBatch<I, R>(items: I[], operation: (item: I, index
12
13
  concurrency?: number;
13
14
  onProgress?: (result: R, index: number, total: number) => void;
14
15
  }): Promise<R[]>;
15
- /**
16
- * Dimensions accepted by the Google Search Console Search Analytics API.
17
- *
18
- * This intentionally excludes package-only logical dimensions such as
19
- * `queryCanonical`; host apps must route those through an engine-backed path.
20
- */
21
- type GscSearchAnalyticsDimension = 'page' | 'query' | 'country' | 'device' | 'date' | 'searchAppearance';
22
- type GscSearchAnalyticsFilterOperator = 'equals' | 'notEquals' | 'contains' | 'notContains' | 'includingRegex' | 'excludingRegex';
23
- interface GscSearchAnalyticsFilter {
24
- dimension: GscSearchAnalyticsDimension;
25
- expression: string;
26
- operator?: GscSearchAnalyticsFilterOperator;
27
- }
28
- interface GscSearchAnalyticsFilterGroup {
29
- groupType?: 'and' | 'or';
30
- filters: GscSearchAnalyticsFilter[];
31
- }
32
- type GscSearchType = 'web' | 'image' | 'video' | 'news' | 'discover' | 'googleNews';
33
- /**
34
- * Canonical host-facing Search Analytics request body.
35
- *
36
- * Google's generated client type also has deprecated/alternate fields. The
37
- * gscdump query builder emits `searchType`, so apps should forward that field
38
- * unchanged rather than translating it to `type`.
39
- */
40
- interface GscSearchAnalyticsRequest {
41
- startDate: string;
42
- endDate: string;
43
- dimensions?: GscSearchAnalyticsDimension[];
44
- dimensionFilterGroups?: GscSearchAnalyticsFilterGroup[];
45
- rowLimit?: number;
46
- startRow?: number;
47
- searchType?: GscSearchType;
48
- }
49
16
  declare const _default: {
50
17
  name: string;
51
18
  'alpha-2': string;
@@ -595,6 +562,112 @@ declare const INDEXING_EFFECTIVE_LIMIT = 1800;
595
562
  declare function hasGscReadScope(scopes: string | null | undefined): boolean;
596
563
  declare function hasGscWriteScope(scopes: string | null | undefined): boolean;
597
564
  declare function hasIndexingScope(scopes: string | null | undefined): boolean;
565
+ declare const GSCDUMP_ONBOARDING_CONTRACT_VERSION: "2026-05-11";
566
+ declare const GSCDUMP_REQUIRED_ANALYTICS_SCOPE: "https://www.googleapis.com/auth/webmasters.readonly";
567
+ declare const GSCDUMP_OPTIONAL_INDEXING_SCOPE: "https://www.googleapis.com/auth/indexing";
568
+ declare const accountStatuses: readonly ["disconnected", "oauth_received", "scope_missing", "refresh_missing", "db_provisioning", "ready", "reauth_required"];
569
+ declare const accountNextActions: readonly ["connect_google", "reconnect_google", "wait_for_provisioning", "none"];
570
+ declare const propertyStatuses: readonly ["no_local_site", "no_gsc_property", "unverified_property", "verified_candidate", "registered", "linked"];
571
+ declare const propertyNextActions: readonly ["create_site", "verify_gsc_property", "choose_property", "register_site", "none"];
572
+ declare const analyticsStatuses: readonly ["not_registered", "queued", "preparing", "syncing", "queryable_live", "queryable_partial", "ready", "failed"];
573
+ declare const analyticsNextActions: readonly ["wait_for_sync", "retry_sync", "none"];
574
+ declare const querySourceModes: readonly ["none", "live", "d1", "r2", "mixed"];
575
+ declare const sitemapStatuses: readonly ["unknown", "discovering", "none_found", "auto_submitted", "syncing", "ready", "failed"];
576
+ declare const sitemapNextActions: readonly ["submit_sitemap", "wait_for_sitemaps", "retry_sitemaps", "none"];
577
+ declare const indexingStatuses: readonly ["not_requested", "missing_scope", "insufficient_permission", "waiting_for_sitemaps", "discovering", "checking", "ready", "budget_exhausted", "no_urls", "failed"];
578
+ declare const indexingNextActions: readonly ["reconnect_google", "fix_gsc_permission", "wait_for_sitemaps", "wait_for_indexing", "retry_indexing", "none"];
579
+ declare const lifecycleWebhookEvents: readonly ["user.lifecycle.changed", "site.lifecycle.changed", "site.analytics.ready", "site.indexing.ready", "site.auth.failed", "job.failed"];
580
+ declare const lifecycleErrorCodes: readonly ["missing_refresh_token", "missing_analytics_scope", "missing_indexing_scope", "token_refresh_failed", "permission_lost", "insufficient_gsc_permission", "gsc_property_not_found", "gsc_property_unverified", "user_database_not_provisioned", "sync_failed", "sitemap_sync_failed", "indexing_failed"];
581
+ type AccountStatus = typeof accountStatuses[number];
582
+ type AccountNextAction = typeof accountNextActions[number];
583
+ type PropertyStatus = typeof propertyStatuses[number];
584
+ type PropertyNextAction = typeof propertyNextActions[number];
585
+ type AnalyticsStatus = typeof analyticsStatuses[number];
586
+ type AnalyticsNextAction = typeof analyticsNextActions[number];
587
+ type QuerySourceMode = typeof querySourceModes[number];
588
+ type SitemapStatus = typeof sitemapStatuses[number];
589
+ type SitemapNextAction = typeof sitemapNextActions[number];
590
+ type IndexingStatus = typeof indexingStatuses[number];
591
+ type IndexingNextAction = typeof indexingNextActions[number];
592
+ type LifecycleWebhookEvent = typeof lifecycleWebhookEvents[number];
593
+ type LifecycleErrorCode = typeof lifecycleErrorCodes[number];
594
+ interface LifecycleProgress {
595
+ completed: number;
596
+ failed: number;
597
+ total: number;
598
+ percent: number;
599
+ }
600
+ interface LifecycleError {
601
+ code: LifecycleErrorCode;
602
+ message: string;
603
+ retryable: boolean;
604
+ }
605
+ interface PartnerLifecycleAccount {
606
+ status: AccountStatus;
607
+ grantedScopes: string[];
608
+ missingScopes: string[];
609
+ nextAction: AccountNextAction;
610
+ }
611
+ interface PartnerLifecycleSite {
612
+ siteId: string;
613
+ externalSiteId: string | null;
614
+ requestedUrl: string;
615
+ gscPropertyUrl: string | null;
616
+ permissionLevel: string | null;
617
+ property: {
618
+ status: PropertyStatus;
619
+ nextAction: PropertyNextAction;
620
+ };
621
+ analytics: {
622
+ status: AnalyticsStatus;
623
+ progress: LifecycleProgress;
624
+ queryable: boolean;
625
+ sourceMode: QuerySourceMode;
626
+ syncedRange: {
627
+ oldest: string | null;
628
+ newest: string | null;
629
+ };
630
+ nextAction: AnalyticsNextAction;
631
+ };
632
+ sitemaps: {
633
+ status: SitemapStatus;
634
+ discoveredCount: number;
635
+ nextAction: SitemapNextAction;
636
+ };
637
+ indexing: {
638
+ status: IndexingStatus;
639
+ eligible: boolean;
640
+ reason: string | null;
641
+ progress: LifecycleProgress;
642
+ nextAction: IndexingNextAction;
643
+ };
644
+ latestError: LifecycleError | null;
645
+ lifecycleRevision: number;
646
+ updatedAt: string;
647
+ }
648
+ interface PartnerLifecycleResponse {
649
+ contractVersion: typeof GSCDUMP_ONBOARDING_CONTRACT_VERSION;
650
+ userId: string;
651
+ partnerId: string | null;
652
+ account: PartnerLifecycleAccount;
653
+ sites: PartnerLifecycleSite[];
654
+ }
655
+ interface LifecycleWebhookEnvelope<TData extends Record<string, unknown> = Record<string, unknown>> {
656
+ contractVersion: typeof GSCDUMP_ONBOARDING_CONTRACT_VERSION;
657
+ deliveryId: string;
658
+ event: LifecycleWebhookEvent;
659
+ partnerId: string;
660
+ userId: string;
661
+ siteId?: string;
662
+ externalUserId?: string | null;
663
+ externalSiteId?: string | null;
664
+ lifecycleRevision: number;
665
+ occurredAt: string;
666
+ data: TData;
667
+ }
668
+ declare function parseGrantedScopes(scopes: string | null | undefined): string[];
669
+ declare function hasRequiredAnalyticsScope(scopes: string | string[] | null | undefined): boolean;
670
+ declare function hasOptionalIndexingScope(scopes: string | string[] | null | undefined): boolean;
598
671
  interface DiscoverSitemapOptions {
599
672
  /** User-Agent sent on the discovery requests. */
600
673
  userAgent?: string;
@@ -620,4 +693,4 @@ interface FetchSitemapUrlsOptions extends DiscoverSitemapOptions {
620
693
  * `<loc>https://...</loc>` shape but doesn't validate the schema.
621
694
  */
622
695
  declare function fetchSitemapUrls(sitemapUrl: string, options?: FetchSitemapUrlsOptions): Promise<string[]>;
623
- export { ApiSite, ApiSitemap, ApiSitemapContent, Auth, AuthClient, AuthOptions, BackfillProgress, CallOptions, DAYS_PER_RANGE, DataRow, DimensionFilter, DimensionFilterGroup, DiscoverSitemapOptions, FetchSitemapUrlsOptions, GSC_FINALIZED_LAG_DAYS, GSC_FRESHEST_LAG_DAYS, GSC_QUOTAS, GSC_RETENTION_MONTHS, GoogleSearchConsoleClient, GoogleSearchConsoleClientOptions, GscError, GscErrorKind, GscdumpApiOptions, INDEXING_DAILY_LIMIT, INDEXING_EFFECTIVE_LIMIT, INDEXING_ISSUE_FILTERS, INDEXING_ISSUE_LABELS, INDEXING_ISSUE_SEVERITY, IndexStatusResult, IndexingIssueType, IndexingMetadata, IndexingNotificationType, IndexingResult, InspectUrlIndexResponse, InspectUrlResult, MS_PER_DAY, MobileUsabilityResult, Period, PublishUrlNotificationResponse, RequiredNonNullable, ResolvedAnalyticsRange, RichResultsResult, SearchAnalyticsQuery, SearchAnalyticsResponse, Site, SiteAnalytics, UrlInspectionResult, UrlNotificationMetadata, VerificationMethod, VerificationSite, VerificationSiteType, VerificationToken, VerificationWebResource, addDays, addSite, batchInspectUrls, batchRequestIndexing, classifyError, countDays, createAuth, createFetch, daysAgo, deleteSite, deleteSitemap, discoverSitemap, fetchSitemap, fetchSitemapUrls, fetchSitemaps, fetchSites, fetchSitesWithSitemaps, formatErrorForCli, generateGscDateRange, getBackfillProgress, getDateRange, getFreshestGscDate, getIndexingMetadata, getLatestGscDate, getNextDate, getOldestGscDate, getPendingDates, getPreviousDate, getPstDate, getVerificationToken, getVerifiedSite, googleSearchConsole, groupIntoRanges, gscdumpApi, hasGscReadScope, hasGscWriteScope, hasIndexingScope, inspectUrl, isPermissionDeniedError, isValidGscDate, listVerifiedSites, progressBar, requestIndexing, rowWithMetricDefaults, runSequentialBatch, siteUrlToVerificationSite, storageError, submitSitemap, toIsoDate, unverifySite, verificationMethodsFor, verifySite };
696
+ export { AccountNextAction, AccountStatus, AnalyticsNextAction, AnalyticsStatus, ApiSite, ApiSitemap, ApiSitemapContent, Auth, AuthClient, AuthOptions, BackfillProgress, CallOptions, DAYS_PER_RANGE, DataRow, DimensionFilter, DimensionFilterGroup, DiscoverSitemapOptions, FetchSitemapUrlsOptions, GSCDUMP_ONBOARDING_CONTRACT_VERSION, GSCDUMP_OPTIONAL_INDEXING_SCOPE, GSCDUMP_REQUIRED_ANALYTICS_SCOPE, GSC_FINALIZED_LAG_DAYS, GSC_FRESHEST_LAG_DAYS, GSC_QUOTAS, GSC_RETENTION_MONTHS, GoogleSearchConsoleClient, GoogleSearchConsoleClientOptions, GscError, GscErrorKind, GscdumpApiOptions, INDEXING_DAILY_LIMIT, INDEXING_EFFECTIVE_LIMIT, INDEXING_ISSUE_FILTERS, INDEXING_ISSUE_LABELS, INDEXING_ISSUE_SEVERITY, IndexStatusResult, IndexingIssueType, IndexingMetadata, IndexingNextAction, IndexingNotificationType, IndexingResult, IndexingStatus, InspectUrlIndexResponse, InspectUrlResult, LifecycleError, LifecycleErrorCode, LifecycleProgress, LifecycleWebhookEnvelope, LifecycleWebhookEvent, MS_PER_DAY, MobileUsabilityResult, PartnerLifecycleAccount, PartnerLifecycleResponse, PartnerLifecycleSite, Period, PropertyNextAction, PropertyStatus, PublishUrlNotificationResponse, QuerySourceMode, RequiredNonNullable, ResolvedAnalyticsRange, RichResultsResult, SearchAnalyticsQuery, SearchAnalyticsResponse, Site, SiteAnalytics, SitemapNextAction, SitemapStatus, UrlInspectionResult, UrlNotificationMetadata, VerificationMethod, VerificationSite, VerificationSiteType, VerificationToken, VerificationWebResource, accountNextActions, accountStatuses, addDays, addSite, analyticsNextActions, analyticsStatuses, batchInspectUrls, batchRequestIndexing, classifyError, countDays, createAuth, createFetch, daysAgo, deleteSite, deleteSitemap, discoverSitemap, fetchSitemap, fetchSitemapUrls, fetchSitemaps, fetchSites, fetchSitesWithSitemaps, formatErrorForCli, generateGscDateRange, getBackfillProgress, getDateRange, getFreshestGscDate, getIndexingMetadata, getLatestGscDate, getNextDate, getOldestGscDate, getPendingDates, getPreviousDate, getPstDate, getVerificationToken, getVerifiedSite, googleSearchConsole, groupIntoRanges, gscdumpApi, hasGscReadScope, hasGscWriteScope, hasIndexingScope, hasOptionalIndexingScope, hasRequiredAnalyticsScope, indexingNextActions, indexingStatuses, inspectUrl, isPermissionDeniedError, isValidGscDate, lifecycleErrorCodes, lifecycleWebhookEvents, listVerifiedSites, parseGrantedScopes, progressBar, propertyNextActions, propertyStatuses, querySourceModes, requestIndexing, rowWithMetricDefaults, runSequentialBatch, siteUrlToVerificationSite, sitemapNextActions, sitemapStatuses, storageError, submitSitemap, toIsoDate, unverifySite, verificationMethodsFor, verifySite };
package/dist/index.mjs CHANGED
@@ -929,6 +929,127 @@ function hasIndexingScope(scopes) {
929
929
  if (!scopes) return false;
930
930
  return scopes.includes("googleapis.com/auth/indexing");
931
931
  }
932
+ const GSCDUMP_ONBOARDING_CONTRACT_VERSION = "2026-05-11";
933
+ const GSCDUMP_REQUIRED_ANALYTICS_SCOPE = "https://www.googleapis.com/auth/webmasters.readonly";
934
+ const GSCDUMP_OPTIONAL_INDEXING_SCOPE = "https://www.googleapis.com/auth/indexing";
935
+ const accountStatuses = [
936
+ "disconnected",
937
+ "oauth_received",
938
+ "scope_missing",
939
+ "refresh_missing",
940
+ "db_provisioning",
941
+ "ready",
942
+ "reauth_required"
943
+ ];
944
+ const accountNextActions = [
945
+ "connect_google",
946
+ "reconnect_google",
947
+ "wait_for_provisioning",
948
+ "none"
949
+ ];
950
+ const propertyStatuses = [
951
+ "no_local_site",
952
+ "no_gsc_property",
953
+ "unverified_property",
954
+ "verified_candidate",
955
+ "registered",
956
+ "linked"
957
+ ];
958
+ const propertyNextActions = [
959
+ "create_site",
960
+ "verify_gsc_property",
961
+ "choose_property",
962
+ "register_site",
963
+ "none"
964
+ ];
965
+ const analyticsStatuses = [
966
+ "not_registered",
967
+ "queued",
968
+ "preparing",
969
+ "syncing",
970
+ "queryable_live",
971
+ "queryable_partial",
972
+ "ready",
973
+ "failed"
974
+ ];
975
+ const analyticsNextActions = [
976
+ "wait_for_sync",
977
+ "retry_sync",
978
+ "none"
979
+ ];
980
+ const querySourceModes = [
981
+ "none",
982
+ "live",
983
+ "d1",
984
+ "r2",
985
+ "mixed"
986
+ ];
987
+ const sitemapStatuses = [
988
+ "unknown",
989
+ "discovering",
990
+ "none_found",
991
+ "auto_submitted",
992
+ "syncing",
993
+ "ready",
994
+ "failed"
995
+ ];
996
+ const sitemapNextActions = [
997
+ "submit_sitemap",
998
+ "wait_for_sitemaps",
999
+ "retry_sitemaps",
1000
+ "none"
1001
+ ];
1002
+ const indexingStatuses = [
1003
+ "not_requested",
1004
+ "missing_scope",
1005
+ "insufficient_permission",
1006
+ "waiting_for_sitemaps",
1007
+ "discovering",
1008
+ "checking",
1009
+ "ready",
1010
+ "budget_exhausted",
1011
+ "no_urls",
1012
+ "failed"
1013
+ ];
1014
+ const indexingNextActions = [
1015
+ "reconnect_google",
1016
+ "fix_gsc_permission",
1017
+ "wait_for_sitemaps",
1018
+ "wait_for_indexing",
1019
+ "retry_indexing",
1020
+ "none"
1021
+ ];
1022
+ const lifecycleWebhookEvents = [
1023
+ "user.lifecycle.changed",
1024
+ "site.lifecycle.changed",
1025
+ "site.analytics.ready",
1026
+ "site.indexing.ready",
1027
+ "site.auth.failed",
1028
+ "job.failed"
1029
+ ];
1030
+ const lifecycleErrorCodes = [
1031
+ "missing_refresh_token",
1032
+ "missing_analytics_scope",
1033
+ "missing_indexing_scope",
1034
+ "token_refresh_failed",
1035
+ "permission_lost",
1036
+ "insufficient_gsc_permission",
1037
+ "gsc_property_not_found",
1038
+ "gsc_property_unverified",
1039
+ "user_database_not_provisioned",
1040
+ "sync_failed",
1041
+ "sitemap_sync_failed",
1042
+ "indexing_failed"
1043
+ ];
1044
+ function parseGrantedScopes(scopes) {
1045
+ return (scopes ?? "").split(/\s+/).map((s) => s.trim()).filter(Boolean);
1046
+ }
1047
+ function hasRequiredAnalyticsScope(scopes) {
1048
+ return (Array.isArray(scopes) ? scopes : parseGrantedScopes(scopes)).includes(GSCDUMP_REQUIRED_ANALYTICS_SCOPE);
1049
+ }
1050
+ function hasOptionalIndexingScope(scopes) {
1051
+ return (Array.isArray(scopes) ? scopes : parseGrantedScopes(scopes)).includes(GSCDUMP_OPTIONAL_INDEXING_SCOPE);
1052
+ }
932
1053
  const FETCH_TIMEOUT_MS = 1e4;
933
1054
  const COMMON_PATHS = ["/sitemap.xml", "/sitemap_index.xml"];
934
1055
  const SITEMAP_DIRECTIVE_RE = /^Sitemap:\s*(\S+)/im;
@@ -996,4 +1117,4 @@ async function fetchSitemapUrls(sitemapUrl, options = {}) {
996
1117
  await visit(sitemapUrl, 0);
997
1118
  return out;
998
1119
  }
999
- export { DAYS_PER_RANGE, GSC_FINALIZED_LAG_DAYS, GSC_FRESHEST_LAG_DAYS, GSC_QUOTAS, GSC_RETENTION_MONTHS, INDEXING_DAILY_LIMIT, INDEXING_EFFECTIVE_LIMIT, INDEXING_ISSUE_FILTERS, INDEXING_ISSUE_LABELS, INDEXING_ISSUE_SEVERITY, MS_PER_DAY, addDays, addSite, batchInspectUrls, batchRequestIndexing, classifyError, countDays, createAuth, createFetch, daysAgo, deleteSite, deleteSitemap, discoverSitemap, fetchSitemap, fetchSitemapUrls, fetchSitemaps, fetchSites, fetchSitesWithSitemaps, formatErrorForCli, generateGscDateRange, getBackfillProgress, getDateRange, getFreshestGscDate, getIndexingMetadata, getLatestGscDate, getNextDate, getOldestGscDate, getPendingDates, getPreviousDate, getPstDate, getVerificationToken, getVerifiedSite, googleSearchConsole, groupIntoRanges, gscdumpApi, hasGscReadScope, hasGscWriteScope, hasIndexingScope, inspectUrl, isPermissionDeniedError, isValidGscDate, listVerifiedSites, progressBar, requestIndexing, rowWithMetricDefaults, runSequentialBatch, siteUrlToVerificationSite, storageError, submitSitemap, toIsoDate, unverifySite, verificationMethodsFor, verifySite };
1120
+ export { DAYS_PER_RANGE, GSCDUMP_ONBOARDING_CONTRACT_VERSION, GSCDUMP_OPTIONAL_INDEXING_SCOPE, GSCDUMP_REQUIRED_ANALYTICS_SCOPE, GSC_FINALIZED_LAG_DAYS, GSC_FRESHEST_LAG_DAYS, GSC_QUOTAS, GSC_RETENTION_MONTHS, INDEXING_DAILY_LIMIT, INDEXING_EFFECTIVE_LIMIT, INDEXING_ISSUE_FILTERS, INDEXING_ISSUE_LABELS, INDEXING_ISSUE_SEVERITY, MS_PER_DAY, accountNextActions, accountStatuses, addDays, addSite, analyticsNextActions, analyticsStatuses, batchInspectUrls, batchRequestIndexing, classifyError, countDays, createAuth, createFetch, daysAgo, deleteSite, deleteSitemap, discoverSitemap, fetchSitemap, fetchSitemapUrls, fetchSitemaps, fetchSites, fetchSitesWithSitemaps, formatErrorForCli, generateGscDateRange, getBackfillProgress, getDateRange, getFreshestGscDate, getIndexingMetadata, getLatestGscDate, getNextDate, getOldestGscDate, getPendingDates, getPreviousDate, getPstDate, getVerificationToken, getVerifiedSite, googleSearchConsole, groupIntoRanges, gscdumpApi, hasGscReadScope, hasGscWriteScope, hasIndexingScope, hasOptionalIndexingScope, hasRequiredAnalyticsScope, indexingNextActions, indexingStatuses, inspectUrl, isPermissionDeniedError, isValidGscDate, lifecycleErrorCodes, lifecycleWebhookEvents, listVerifiedSites, parseGrantedScopes, progressBar, propertyNextActions, propertyStatuses, querySourceModes, requestIndexing, rowWithMetricDefaults, runSequentialBatch, siteUrlToVerificationSite, sitemapNextActions, sitemapStatuses, storageError, submitSitemap, toIsoDate, unverifySite, verificationMethodsFor, verifySite };
@@ -0,0 +1,107 @@
1
+ declare const GSCDUMP_ONBOARDING_CONTRACT_VERSION: "2026-05-11";
2
+ declare const GSCDUMP_REQUIRED_ANALYTICS_SCOPE: "https://www.googleapis.com/auth/webmasters.readonly";
3
+ declare const GSCDUMP_OPTIONAL_INDEXING_SCOPE: "https://www.googleapis.com/auth/indexing";
4
+ declare const accountStatuses: readonly ["disconnected", "oauth_received", "scope_missing", "refresh_missing", "db_provisioning", "ready", "reauth_required"];
5
+ declare const accountNextActions: readonly ["connect_google", "reconnect_google", "wait_for_provisioning", "none"];
6
+ declare const propertyStatuses: readonly ["no_local_site", "no_gsc_property", "unverified_property", "verified_candidate", "registered", "linked"];
7
+ declare const propertyNextActions: readonly ["create_site", "verify_gsc_property", "choose_property", "register_site", "none"];
8
+ declare const analyticsStatuses: readonly ["not_registered", "queued", "preparing", "syncing", "queryable_live", "queryable_partial", "ready", "failed"];
9
+ declare const analyticsNextActions: readonly ["wait_for_sync", "retry_sync", "none"];
10
+ declare const querySourceModes: readonly ["none", "live", "d1", "r2", "mixed"];
11
+ declare const sitemapStatuses: readonly ["unknown", "discovering", "none_found", "auto_submitted", "syncing", "ready", "failed"];
12
+ declare const sitemapNextActions: readonly ["submit_sitemap", "wait_for_sitemaps", "retry_sitemaps", "none"];
13
+ declare const indexingStatuses: readonly ["not_requested", "missing_scope", "insufficient_permission", "waiting_for_sitemaps", "discovering", "checking", "ready", "budget_exhausted", "no_urls", "failed"];
14
+ declare const indexingNextActions: readonly ["reconnect_google", "fix_gsc_permission", "wait_for_sitemaps", "wait_for_indexing", "retry_indexing", "none"];
15
+ declare const lifecycleWebhookEvents: readonly ["user.lifecycle.changed", "site.lifecycle.changed", "site.analytics.ready", "site.indexing.ready", "site.auth.failed", "job.failed"];
16
+ declare const lifecycleErrorCodes: readonly ["missing_refresh_token", "missing_analytics_scope", "missing_indexing_scope", "token_refresh_failed", "permission_lost", "insufficient_gsc_permission", "gsc_property_not_found", "gsc_property_unverified", "user_database_not_provisioned", "sync_failed", "sitemap_sync_failed", "indexing_failed"];
17
+ type AccountStatus = typeof accountStatuses[number];
18
+ type AccountNextAction = typeof accountNextActions[number];
19
+ type PropertyStatus = typeof propertyStatuses[number];
20
+ type PropertyNextAction = typeof propertyNextActions[number];
21
+ type AnalyticsStatus = typeof analyticsStatuses[number];
22
+ type AnalyticsNextAction = typeof analyticsNextActions[number];
23
+ type QuerySourceMode = typeof querySourceModes[number];
24
+ type SitemapStatus = typeof sitemapStatuses[number];
25
+ type SitemapNextAction = typeof sitemapNextActions[number];
26
+ type IndexingStatus = typeof indexingStatuses[number];
27
+ type IndexingNextAction = typeof indexingNextActions[number];
28
+ type LifecycleWebhookEvent = typeof lifecycleWebhookEvents[number];
29
+ type LifecycleErrorCode = typeof lifecycleErrorCodes[number];
30
+ interface LifecycleProgress {
31
+ completed: number;
32
+ failed: number;
33
+ total: number;
34
+ percent: number;
35
+ }
36
+ interface LifecycleError {
37
+ code: LifecycleErrorCode;
38
+ message: string;
39
+ retryable: boolean;
40
+ }
41
+ interface PartnerLifecycleAccount {
42
+ status: AccountStatus;
43
+ grantedScopes: string[];
44
+ missingScopes: string[];
45
+ nextAction: AccountNextAction;
46
+ }
47
+ interface PartnerLifecycleSite {
48
+ siteId: string;
49
+ externalSiteId: string | null;
50
+ requestedUrl: string;
51
+ gscPropertyUrl: string | null;
52
+ permissionLevel: string | null;
53
+ property: {
54
+ status: PropertyStatus;
55
+ nextAction: PropertyNextAction;
56
+ };
57
+ analytics: {
58
+ status: AnalyticsStatus;
59
+ progress: LifecycleProgress;
60
+ queryable: boolean;
61
+ sourceMode: QuerySourceMode;
62
+ syncedRange: {
63
+ oldest: string | null;
64
+ newest: string | null;
65
+ };
66
+ nextAction: AnalyticsNextAction;
67
+ };
68
+ sitemaps: {
69
+ status: SitemapStatus;
70
+ discoveredCount: number;
71
+ nextAction: SitemapNextAction;
72
+ };
73
+ indexing: {
74
+ status: IndexingStatus;
75
+ eligible: boolean;
76
+ reason: string | null;
77
+ progress: LifecycleProgress;
78
+ nextAction: IndexingNextAction;
79
+ };
80
+ latestError: LifecycleError | null;
81
+ lifecycleRevision: number;
82
+ updatedAt: string;
83
+ }
84
+ interface PartnerLifecycleResponse {
85
+ contractVersion: typeof GSCDUMP_ONBOARDING_CONTRACT_VERSION;
86
+ userId: string;
87
+ partnerId: string | null;
88
+ account: PartnerLifecycleAccount;
89
+ sites: PartnerLifecycleSite[];
90
+ }
91
+ interface LifecycleWebhookEnvelope<TData extends Record<string, unknown> = Record<string, unknown>> {
92
+ contractVersion: typeof GSCDUMP_ONBOARDING_CONTRACT_VERSION;
93
+ deliveryId: string;
94
+ event: LifecycleWebhookEvent;
95
+ partnerId: string;
96
+ userId: string;
97
+ siteId?: string;
98
+ externalUserId?: string | null;
99
+ externalSiteId?: string | null;
100
+ lifecycleRevision: number;
101
+ occurredAt: string;
102
+ data: TData;
103
+ }
104
+ declare function parseGrantedScopes(scopes: string | null | undefined): string[];
105
+ declare function hasRequiredAnalyticsScope(scopes: string | string[] | null | undefined): boolean;
106
+ declare function hasOptionalIndexingScope(scopes: string | string[] | null | undefined): boolean;
107
+ export { AccountNextAction, AccountStatus, AnalyticsNextAction, AnalyticsStatus, GSCDUMP_ONBOARDING_CONTRACT_VERSION, GSCDUMP_OPTIONAL_INDEXING_SCOPE, GSCDUMP_REQUIRED_ANALYTICS_SCOPE, IndexingNextAction, IndexingStatus, LifecycleError, LifecycleErrorCode, LifecycleProgress, LifecycleWebhookEnvelope, LifecycleWebhookEvent, PartnerLifecycleAccount, PartnerLifecycleResponse, PartnerLifecycleSite, PropertyNextAction, PropertyStatus, QuerySourceMode, SitemapNextAction, SitemapStatus, accountNextActions, accountStatuses, analyticsNextActions, analyticsStatuses, hasOptionalIndexingScope, hasRequiredAnalyticsScope, indexingNextActions, indexingStatuses, lifecycleErrorCodes, lifecycleWebhookEvents, parseGrantedScopes, propertyNextActions, propertyStatuses, querySourceModes, sitemapNextActions, sitemapStatuses };
@@ -0,0 +1,122 @@
1
+ const GSCDUMP_ONBOARDING_CONTRACT_VERSION = "2026-05-11";
2
+ const GSCDUMP_REQUIRED_ANALYTICS_SCOPE = "https://www.googleapis.com/auth/webmasters.readonly";
3
+ const GSCDUMP_OPTIONAL_INDEXING_SCOPE = "https://www.googleapis.com/auth/indexing";
4
+ const accountStatuses = [
5
+ "disconnected",
6
+ "oauth_received",
7
+ "scope_missing",
8
+ "refresh_missing",
9
+ "db_provisioning",
10
+ "ready",
11
+ "reauth_required"
12
+ ];
13
+ const accountNextActions = [
14
+ "connect_google",
15
+ "reconnect_google",
16
+ "wait_for_provisioning",
17
+ "none"
18
+ ];
19
+ const propertyStatuses = [
20
+ "no_local_site",
21
+ "no_gsc_property",
22
+ "unverified_property",
23
+ "verified_candidate",
24
+ "registered",
25
+ "linked"
26
+ ];
27
+ const propertyNextActions = [
28
+ "create_site",
29
+ "verify_gsc_property",
30
+ "choose_property",
31
+ "register_site",
32
+ "none"
33
+ ];
34
+ const analyticsStatuses = [
35
+ "not_registered",
36
+ "queued",
37
+ "preparing",
38
+ "syncing",
39
+ "queryable_live",
40
+ "queryable_partial",
41
+ "ready",
42
+ "failed"
43
+ ];
44
+ const analyticsNextActions = [
45
+ "wait_for_sync",
46
+ "retry_sync",
47
+ "none"
48
+ ];
49
+ const querySourceModes = [
50
+ "none",
51
+ "live",
52
+ "d1",
53
+ "r2",
54
+ "mixed"
55
+ ];
56
+ const sitemapStatuses = [
57
+ "unknown",
58
+ "discovering",
59
+ "none_found",
60
+ "auto_submitted",
61
+ "syncing",
62
+ "ready",
63
+ "failed"
64
+ ];
65
+ const sitemapNextActions = [
66
+ "submit_sitemap",
67
+ "wait_for_sitemaps",
68
+ "retry_sitemaps",
69
+ "none"
70
+ ];
71
+ const indexingStatuses = [
72
+ "not_requested",
73
+ "missing_scope",
74
+ "insufficient_permission",
75
+ "waiting_for_sitemaps",
76
+ "discovering",
77
+ "checking",
78
+ "ready",
79
+ "budget_exhausted",
80
+ "no_urls",
81
+ "failed"
82
+ ];
83
+ const indexingNextActions = [
84
+ "reconnect_google",
85
+ "fix_gsc_permission",
86
+ "wait_for_sitemaps",
87
+ "wait_for_indexing",
88
+ "retry_indexing",
89
+ "none"
90
+ ];
91
+ const lifecycleWebhookEvents = [
92
+ "user.lifecycle.changed",
93
+ "site.lifecycle.changed",
94
+ "site.analytics.ready",
95
+ "site.indexing.ready",
96
+ "site.auth.failed",
97
+ "job.failed"
98
+ ];
99
+ const lifecycleErrorCodes = [
100
+ "missing_refresh_token",
101
+ "missing_analytics_scope",
102
+ "missing_indexing_scope",
103
+ "token_refresh_failed",
104
+ "permission_lost",
105
+ "insufficient_gsc_permission",
106
+ "gsc_property_not_found",
107
+ "gsc_property_unverified",
108
+ "user_database_not_provisioned",
109
+ "sync_failed",
110
+ "sitemap_sync_failed",
111
+ "indexing_failed"
112
+ ];
113
+ function parseGrantedScopes(scopes) {
114
+ return (scopes ?? "").split(/\s+/).map((s) => s.trim()).filter(Boolean);
115
+ }
116
+ function hasRequiredAnalyticsScope(scopes) {
117
+ return (Array.isArray(scopes) ? scopes : parseGrantedScopes(scopes)).includes(GSCDUMP_REQUIRED_ANALYTICS_SCOPE);
118
+ }
119
+ function hasOptionalIndexingScope(scopes) {
120
+ return (Array.isArray(scopes) ? scopes : parseGrantedScopes(scopes)).includes(GSCDUMP_OPTIONAL_INDEXING_SCOPE);
121
+ }
122
+ export { GSCDUMP_ONBOARDING_CONTRACT_VERSION, GSCDUMP_OPTIONAL_INDEXING_SCOPE, GSCDUMP_REQUIRED_ANALYTICS_SCOPE, accountNextActions, accountStatuses, analyticsNextActions, analyticsStatuses, hasOptionalIndexingScope, hasRequiredAnalyticsScope, indexingNextActions, indexingStatuses, lifecycleErrorCodes, lifecycleWebhookEvents, parseGrantedScopes, propertyNextActions, propertyStatuses, querySourceModes, sitemapNextActions, sitemapStatuses };
@@ -1,48 +1,5 @@
1
1
  import _dayjs, { Dayjs } from "dayjs";
2
- /**
3
- * Canonical cross-package contracts. Type-only — zero runtime cost.
4
- *
5
- * Imported by @gscdump/engine, @gscdump/analysis, @gscdump/cli, @gscdump/mcp,
6
- * @gscdump/cloud as the single source of truth for cross-cutting types so
7
- * schema identifiers, tenant shape, and analyzer IO can't drift across
8
- * packages.
9
- */
10
- /** Logical table / dataset identifier. Canonical across query builder + storage engine. */
11
- type TableName = 'pages' | 'keywords' | 'countries' | 'devices' | 'page_keywords' | 'search_appearance';
12
- /**
13
- * Dimensions accepted by the Google Search Console Search Analytics API.
14
- *
15
- * This intentionally excludes package-only logical dimensions such as
16
- * `queryCanonical`; host apps must route those through an engine-backed path.
17
- */
18
- type GscSearchAnalyticsDimension = 'page' | 'query' | 'country' | 'device' | 'date' | 'searchAppearance';
19
- type GscSearchAnalyticsFilterOperator = 'equals' | 'notEquals' | 'contains' | 'notContains' | 'includingRegex' | 'excludingRegex';
20
- interface GscSearchAnalyticsFilter {
21
- dimension: GscSearchAnalyticsDimension;
22
- expression: string;
23
- operator?: GscSearchAnalyticsFilterOperator;
24
- }
25
- interface GscSearchAnalyticsFilterGroup {
26
- groupType?: 'and' | 'or';
27
- filters: GscSearchAnalyticsFilter[];
28
- }
29
- type GscSearchType = 'web' | 'image' | 'video' | 'news' | 'discover' | 'googleNews';
30
- /**
31
- * Canonical host-facing Search Analytics request body.
32
- *
33
- * Google's generated client type also has deprecated/alternate fields. The
34
- * gscdump query builder emits `searchType`, so apps should forward that field
35
- * unchanged rather than translating it to `type`.
36
- */
37
- interface GscSearchAnalyticsRequest {
38
- startDate: string;
39
- endDate: string;
40
- dimensions?: GscSearchAnalyticsDimension[];
41
- dimensionFilterGroups?: GscSearchAnalyticsFilterGroup[];
42
- rowLimit?: number;
43
- startRow?: number;
44
- searchType?: GscSearchType;
45
- }
2
+ import { GscSearchAnalyticsRequest, TableName } from "@gscdump/contracts";
46
3
  declare const _default: {
47
4
  name: string;
48
5
  'alpha-2': string;
@@ -1,13 +1,4 @@
1
- /**
2
- * Canonical cross-package contracts. Type-only — zero runtime cost.
3
- *
4
- * Imported by @gscdump/engine, @gscdump/analysis, @gscdump/cli, @gscdump/mcp,
5
- * @gscdump/cloud as the single source of truth for cross-cutting types so
6
- * schema identifiers, tenant shape, and analyzer IO can't drift across
7
- * packages.
8
- */
9
- /** Logical table / dataset identifier. Canonical across query builder + storage engine. */
10
- type TableName = 'pages' | 'keywords' | 'countries' | 'devices' | 'page_keywords' | 'search_appearance';
1
+ import { TableName } from "@gscdump/contracts";
11
2
  declare const _default: {
12
3
  name: string;
13
4
  'alpha-2': string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gscdump",
3
3
  "type": "module",
4
- "version": "0.11.3",
4
+ "version": "0.11.5",
5
5
  "description": "Google Search Console API wrapper with typed query builder, streaming pagination, and SEO analysis functions",
6
6
  "author": {
7
7
  "name": "Harlan Wilton",
@@ -76,6 +76,11 @@
76
76
  "types": "./dist/sitemap.d.mts",
77
77
  "import": "./dist/sitemap.mjs",
78
78
  "default": "./dist/sitemap.mjs"
79
+ },
80
+ "./onboarding": {
81
+ "types": "./dist/onboarding.d.mts",
82
+ "import": "./dist/onboarding.mjs",
83
+ "default": "./dist/onboarding.mjs"
79
84
  }
80
85
  },
81
86
  "main": "./dist/index.mjs",
@@ -102,7 +107,8 @@
102
107
  "dayjs": "^1.11.20",
103
108
  "defu": "^6.1.7",
104
109
  "ofetch": "^1.5.1",
105
- "ufo": "^1.6.4"
110
+ "ufo": "^1.6.4",
111
+ "@gscdump/contracts": "0.11.5"
106
112
  },
107
113
  "devDependencies": {
108
114
  "@googleapis/indexing": "^6.0.1",