gscdump 3.4.4 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -7
- package/dist/api/batch.d.mts +2 -3
- package/dist/api/batch.mjs +2 -0
- package/dist/api/indexing.d.mts +7 -8
- package/dist/api/indexing.mjs +1 -1
- package/dist/api/inspection.d.mts +21 -22
- package/dist/api/oauth.d.mts +8 -9
- package/dist/api/oauth.mjs +9 -1
- package/dist/api/sites.d.mts +9 -10
- package/dist/api/verification.d.mts +8 -9
- package/dist/bing/client.d.mts +3 -4
- package/dist/bing/client.mjs +10 -4
- package/dist/bing/normalize.d.mts +9 -10
- package/dist/bing/types.d.mts +42 -38
- package/dist/contracts.d.mts +12 -12
- package/dist/core/canonical.d.mts +3 -4
- package/dist/core/client.d.mts +16 -17
- package/dist/core/client.mjs +16 -13
- package/dist/core/errors.d.mts +9 -10
- package/dist/core/errors.mjs +2 -1
- package/dist/core/gsc-dates.d.mts +22 -23
- package/dist/core/indexing-issues.d.mts +10 -11
- package/dist/core/property.d.mts +9 -10
- package/dist/core/quota.d.mts +1 -2
- package/dist/core/result.d.mts +8 -9
- package/dist/core/scope-values.d.mts +5 -6
- package/dist/core/scopes.d.mts +3 -4
- package/dist/core/site-url.d.mts +4 -5
- package/dist/core/types.d.mts +29 -30
- package/dist/core/window.d.mts +5 -6
- package/dist/normalize.d.mts +1 -2
- package/dist/query/builder.d.mts +4 -5
- package/dist/query/columns.d.mts +13 -14
- package/dist/query/constants.d.mts +5 -5
- package/dist/query/errors.d.mts +7 -8
- package/dist/query/errors.mjs +1 -1
- package/dist/query/index.d.mts +3 -3
- package/dist/query/operators.d.mts +22 -23
- package/dist/query/plan.d.mts +18 -18
- package/dist/query/plan.mjs +7 -4
- package/dist/query/resolver.d.mts +10 -19
- package/dist/query/resolver.mjs +125 -61
- package/dist/query/types.d.mts +22 -23
- package/dist/query/utils/dayjs.d.mts +2 -3
- package/dist/sitemap-identity.d.mts +8 -9
- package/dist/tenant.d.mts +3 -4
- package/dist/url.d.mts +1 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -25,20 +25,36 @@ const client = googleSearchConsole({ accessToken: 'ya29.xxx' })
|
|
|
25
25
|
const sites = await client.sites()
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
+
Use `fetchOptions` for custom headers, request hooks, or retry settings:
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
const client = googleSearchConsole('ya29.xxx', {
|
|
32
|
+
fetchOptions: {
|
|
33
|
+
headers: new Headers({ 'x-project': 'analytics' }),
|
|
34
|
+
retry: 0,
|
|
35
|
+
timeout: 10_000,
|
|
36
|
+
onRequest({ options }) {
|
|
37
|
+
options.headers.set('x-request-id', crypto.randomUUID())
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
})
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Request hooks run after authentication. The client awaits each hook, including arrays of hooks.
|
|
44
|
+
If you omit retry settings, requests use three retries and respect Google's `Retry-After` header.
|
|
45
|
+
|
|
28
46
|
Use `gscdump/query` to build a request. `client.query()` paginates through Google's 25,000-row pages and yields each non-empty batch.
|
|
29
47
|
|
|
30
48
|
```ts
|
|
31
49
|
import { googleSearchConsole } from 'gscdump'
|
|
32
|
-
import {
|
|
50
|
+
import { between, date, daysAgo, gsc, page, query } from 'gscdump/query'
|
|
33
51
|
|
|
34
52
|
const client = googleSearchConsole('ya29.xxx')
|
|
35
53
|
const siteUrl = 'sc-domain:example.com'
|
|
36
54
|
|
|
37
55
|
const request = gsc
|
|
38
56
|
.select(page, query)
|
|
39
|
-
.where(
|
|
40
|
-
between(date, daysAgo(28), today()),
|
|
41
|
-
))
|
|
57
|
+
.where(between(date, daysAgo(30), daysAgo(3)))
|
|
42
58
|
|
|
43
59
|
for await (const rows of client.query(siteUrl, request)) {
|
|
44
60
|
for (const row of rows)
|
|
@@ -59,7 +75,7 @@ const response = await client.searchAnalytics.query(siteUrl, {
|
|
|
59
75
|
|
|
60
76
|
## Other Google resources
|
|
61
77
|
|
|
62
|
-
|
|
78
|
+
Use the same client for sitemaps, inspections, and eligible Indexing API notifications:
|
|
63
79
|
|
|
64
80
|
```ts
|
|
65
81
|
const sitemapList = await client.sitemaps.list(siteUrl)
|
|
@@ -71,17 +87,21 @@ await client.indexing.publish(
|
|
|
71
87
|
)
|
|
72
88
|
```
|
|
73
89
|
|
|
90
|
+
Indexing notifications apply only to eligible job or livestream pages.
|
|
91
|
+
See [URL inspection and indexing](../../docs/guides/url-indexing.md).
|
|
92
|
+
|
|
74
93
|
The package root also exports batch and projection helpers such as `fetchSitesWithSitemaps`, `batchInspectUrlsFlatSettled`, `inspectUrlFlat`, and `batchRequestIndexing`.
|
|
75
94
|
|
|
76
95
|
## Read Bing Indexing Evidence
|
|
77
96
|
|
|
78
|
-
Use `gscdump/bing` with an OAuth access token. The client returns tagged
|
|
97
|
+
Use `gscdump/bing` with an OAuth access token or Bing Webmaster API key. The client returns tagged
|
|
79
98
|
`Result` values and never infers an indexed verdict from crawl evidence.
|
|
80
99
|
|
|
81
100
|
```ts
|
|
82
101
|
import { bingWebmaster } from 'gscdump/bing'
|
|
83
102
|
|
|
84
103
|
const client = bingWebmaster({ accessToken: 'access-token' })
|
|
104
|
+
// API key alternative: bingWebmaster({ apiKey: 'bing-webmaster-api-key' })
|
|
85
105
|
const evidence = await client.getIndexingEvidence(
|
|
86
106
|
'https://example.com/',
|
|
87
107
|
'https://example.com/docs',
|
|
@@ -97,12 +117,21 @@ const [pages, queries, crawl] = await Promise.all([
|
|
|
97
117
|
])
|
|
98
118
|
```
|
|
99
119
|
|
|
100
|
-
|
|
120
|
+
`accessToken` also accepts a function returning a string or `Promise<string>`.
|
|
121
|
+
The client calls that function before each request, so callers can refresh expiring tokens during long exports.
|
|
122
|
+
The CLI manages this refresh when you use `gscdump bing login --mode local --oauth`.
|
|
123
|
+
|
|
124
|
+
Sitemap XML reading and traversal live in `sitemapd`. Product feed scoping and
|
|
101
125
|
exact membership hashing live in `gscdump/sitemap-identity`. Hosted canonical
|
|
102
126
|
sitemap membership is available through `@gscdump/sdk/v1`.
|
|
103
127
|
|
|
104
128
|
## Public subpaths
|
|
105
129
|
|
|
130
|
+
- `gscdump/client`: Google client and authentication types
|
|
131
|
+
- `gscdump/indexing`: inspection and indexing helpers
|
|
132
|
+
- `gscdump/errors`: typed Google API failures
|
|
133
|
+
- `gscdump/sites`: Site helpers
|
|
134
|
+
- `gscdump/sitemap-identity`: sitemap scope and membership hashing
|
|
106
135
|
- `gscdump/query`: query builder, columns, operators, Pacific date helpers, and logical query plans
|
|
107
136
|
- `gscdump/query/plan`: logical query planning only
|
|
108
137
|
- `gscdump/bing`: Bing Site, URL, traffic, and crawl evidence calls
|
package/dist/api/batch.d.mts
CHANGED
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
* (concurrency = 1) because the underlying APIs rate-limit aggressively;
|
|
5
5
|
* callers that know their quota headroom can opt into parallelism.
|
|
6
6
|
*/
|
|
7
|
-
declare function runSequentialBatch<I, R>(items: I[], operation: (item: I, index: number) => Promise<R>, options?: {
|
|
7
|
+
export declare function runSequentialBatch<I, R>(items: I[], operation: (item: I, index: number) => Promise<R>, options?: {
|
|
8
8
|
delayMs?: number;
|
|
9
9
|
concurrency?: number;
|
|
10
10
|
onProgress?: (result: R, index: number, total: number) => void;
|
|
11
|
-
}): Promise<R[]>;
|
|
12
|
-
export { runSequentialBatch };
|
|
11
|
+
}): Promise<R[]>;
|
package/dist/api/batch.mjs
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
async function runSequentialBatch(items, operation, options = {}) {
|
|
2
2
|
const { delayMs = 0, concurrency = 1, onProgress } = options;
|
|
3
|
+
if (!Number.isInteger(concurrency) || concurrency < 1) throw new RangeError("concurrency must be a positive integer.");
|
|
4
|
+
if (!Number.isFinite(delayMs) || delayMs < 0) throw new RangeError("delayMs must be a finite, nonnegative number.");
|
|
3
5
|
const results = Array.from({ length: items.length });
|
|
4
6
|
let completed = 0;
|
|
5
7
|
if (concurrency <= 1) {
|
package/dist/api/indexing.d.mts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { UrlNotification } from "../core/types.mjs";
|
|
2
2
|
import { GoogleSearchConsoleClient } from "../core/client.mjs";
|
|
3
|
-
type IndexingNotificationType = 'URL_UPDATED' | 'URL_DELETED';
|
|
4
|
-
interface IndexingResult {
|
|
3
|
+
export type IndexingNotificationType = 'URL_UPDATED' | 'URL_DELETED';
|
|
4
|
+
export interface IndexingResult {
|
|
5
5
|
url: string;
|
|
6
6
|
type: IndexingNotificationType;
|
|
7
7
|
notifyTime?: string;
|
|
8
8
|
}
|
|
9
|
-
interface IndexingMetadata {
|
|
9
|
+
export interface IndexingMetadata {
|
|
10
10
|
url: string;
|
|
11
11
|
latestUpdate?: UrlNotification;
|
|
12
12
|
latestRemove?: UrlNotification;
|
|
@@ -16,22 +16,21 @@ interface IndexingMetadata {
|
|
|
16
16
|
* Note: The Indexing API officially supports only job posting and livestream content,
|
|
17
17
|
* but can be used for any URL with varying success.
|
|
18
18
|
*/
|
|
19
|
-
declare function requestIndexing(client: GoogleSearchConsoleClient, url: string, options?: {
|
|
19
|
+
export declare function requestIndexing(client: GoogleSearchConsoleClient, url: string, options?: {
|
|
20
20
|
type?: IndexingNotificationType;
|
|
21
21
|
}): Promise<IndexingResult>;
|
|
22
22
|
/**
|
|
23
23
|
* Get the indexing notification metadata for a URL.
|
|
24
24
|
* Returns when Google was last notified about updates/removals.
|
|
25
25
|
*/
|
|
26
|
-
declare function getIndexingMetadata(client: GoogleSearchConsoleClient, url: string): Promise<IndexingMetadata>;
|
|
26
|
+
export declare function getIndexingMetadata(client: GoogleSearchConsoleClient, url: string): Promise<IndexingMetadata>;
|
|
27
27
|
/**
|
|
28
28
|
* Batch request indexing for multiple URLs with rate limiting.
|
|
29
29
|
* Returns results for each URL.
|
|
30
30
|
*/
|
|
31
|
-
declare function batchRequestIndexing(client: GoogleSearchConsoleClient, urls: string[], options?: {
|
|
31
|
+
export declare function batchRequestIndexing(client: GoogleSearchConsoleClient, urls: string[], options?: {
|
|
32
32
|
type?: IndexingNotificationType;
|
|
33
33
|
delayMs?: number;
|
|
34
34
|
concurrency?: number;
|
|
35
35
|
onProgress?: (result: IndexingResult, index: number, total: number) => void;
|
|
36
|
-
}): Promise<IndexingResult[]>;
|
|
37
|
-
export { IndexingMetadata, IndexingNotificationType, IndexingResult, batchRequestIndexing, getIndexingMetadata, requestIndexing };
|
|
36
|
+
}): Promise<IndexingResult[]>;
|
package/dist/api/indexing.mjs
CHANGED
|
@@ -4,7 +4,7 @@ async function requestIndexing(client, url, options = {}) {
|
|
|
4
4
|
return client.indexing.publish(url, type).then((r) => ({
|
|
5
5
|
url,
|
|
6
6
|
type,
|
|
7
|
-
notifyTime: r.urlNotificationMetadata?.latestUpdate?.notifyTime || void 0
|
|
7
|
+
notifyTime: (type === "URL_DELETED" ? r.urlNotificationMetadata?.latestRemove : r.urlNotificationMetadata?.latestUpdate)?.notifyTime || void 0
|
|
8
8
|
}));
|
|
9
9
|
}
|
|
10
10
|
async function getIndexingMetadata(client, url) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { UrlInspectionResult } from "../core/types.mjs";
|
|
2
2
|
import { CallOptions, GoogleSearchConsoleClient } from "../core/client.mjs";
|
|
3
|
-
interface InspectUrlResult {
|
|
3
|
+
export interface InspectUrlResult {
|
|
4
4
|
url: string;
|
|
5
5
|
inspection?: UrlInspectionResult;
|
|
6
6
|
isIndexed: boolean;
|
|
@@ -8,7 +8,7 @@ interface InspectUrlResult {
|
|
|
8
8
|
/**
|
|
9
9
|
* Inspects a URL in Google Search Console to check its indexing status.
|
|
10
10
|
*/
|
|
11
|
-
declare function inspectUrl(client: GoogleSearchConsoleClient, siteUrl: string, inspectionUrl: string): Promise<{
|
|
11
|
+
export declare function inspectUrl(client: GoogleSearchConsoleClient, siteUrl: string, inspectionUrl: string): Promise<{
|
|
12
12
|
inspection: UrlInspectionResult | undefined;
|
|
13
13
|
isIndexed: boolean;
|
|
14
14
|
}>;
|
|
@@ -16,12 +16,12 @@ declare function inspectUrl(client: GoogleSearchConsoleClient, siteUrl: string,
|
|
|
16
16
|
* Batch inspect multiple URLs with rate limiting.
|
|
17
17
|
* Returns inspection results for each URL.
|
|
18
18
|
*/
|
|
19
|
-
declare function batchInspectUrls(client: GoogleSearchConsoleClient, siteUrl: string, urls: string[], options?: {
|
|
19
|
+
export declare function batchInspectUrls(client: GoogleSearchConsoleClient, siteUrl: string, urls: string[], options?: {
|
|
20
20
|
delayMs?: number;
|
|
21
21
|
concurrency?: number;
|
|
22
22
|
onProgress?: (result: InspectUrlResult, index: number, total: number) => void;
|
|
23
23
|
}): Promise<InspectUrlResult[]>;
|
|
24
|
-
interface ParsedIndexingResult {
|
|
24
|
+
export interface ParsedIndexingResult {
|
|
25
25
|
url: string;
|
|
26
26
|
verdict: string | null;
|
|
27
27
|
coverageState: string | null;
|
|
@@ -50,10 +50,10 @@ interface ParsedIndexingResult {
|
|
|
50
50
|
ampIssues: string | null;
|
|
51
51
|
inspectionResultLink: string | null;
|
|
52
52
|
}
|
|
53
|
-
declare function inspectUrlFlat(client: GoogleSearchConsoleClient, siteUrl: string, inspectionUrl: string, options?: CallOptions): Promise<ParsedIndexingResult>;
|
|
53
|
+
export declare function inspectUrlFlat(client: GoogleSearchConsoleClient, siteUrl: string, inspectionUrl: string, options?: CallOptions): Promise<ParsedIndexingResult>;
|
|
54
54
|
/** Maximum parallel URL Inspection requests started by the settled flat batch helper. */
|
|
55
|
-
declare const MAX_FLAT_INSPECTION_BATCH_CONCURRENCY = 10;
|
|
56
|
-
type InspectUrlFlatSettledResult = {
|
|
55
|
+
export declare const MAX_FLAT_INSPECTION_BATCH_CONCURRENCY = 10;
|
|
56
|
+
export type InspectUrlFlatSettledResult = {
|
|
57
57
|
url: string;
|
|
58
58
|
status: 'fulfilled';
|
|
59
59
|
value: ParsedIndexingResult;
|
|
@@ -62,7 +62,7 @@ type InspectUrlFlatSettledResult = {
|
|
|
62
62
|
status: 'rejected';
|
|
63
63
|
reason: unknown;
|
|
64
64
|
};
|
|
65
|
-
interface BatchInspectUrlsFlatSettledOptions extends CallOptions {
|
|
65
|
+
export interface BatchInspectUrlsFlatSettledOptions extends CallOptions {
|
|
66
66
|
/** Delay after each request handled by a worker. Defaults to 200ms. */
|
|
67
67
|
delayMs?: number;
|
|
68
68
|
/** Number of workers. Defaults to 1 and is capped at {@link MAX_FLAT_INSPECTION_BATCH_CONCURRENCY}. */
|
|
@@ -74,10 +74,10 @@ interface BatchInspectUrlsFlatSettledOptions extends CallOptions {
|
|
|
74
74
|
* when one URL fails. Results retain input order and include each URL so
|
|
75
75
|
* callers can persist successes and classify individual failures safely.
|
|
76
76
|
*/
|
|
77
|
-
declare function batchInspectUrlsFlatSettled(client: GoogleSearchConsoleClient, siteUrl: string, urls: readonly string[], options?: BatchInspectUrlsFlatSettledOptions): Promise<InspectUrlFlatSettledResult[]>;
|
|
78
|
-
type LegacyInspectionPriority = 'high' | 'medium' | 'low';
|
|
79
|
-
type ValueWeightedInspectionPriority = 'critical' | 'high' | 'elevated' | 'normal' | 'dormant';
|
|
80
|
-
type InspectionPriority = LegacyInspectionPriority | ValueWeightedInspectionPriority;
|
|
77
|
+
export declare function batchInspectUrlsFlatSettled(client: GoogleSearchConsoleClient, siteUrl: string, urls: readonly string[], options?: BatchInspectUrlsFlatSettledOptions): Promise<InspectUrlFlatSettledResult[]>;
|
|
78
|
+
export type LegacyInspectionPriority = 'high' | 'medium' | 'low';
|
|
79
|
+
export type ValueWeightedInspectionPriority = 'critical' | 'high' | 'elevated' | 'normal' | 'dormant';
|
|
80
|
+
export type InspectionPriority = LegacyInspectionPriority | ValueWeightedInspectionPriority;
|
|
81
81
|
/**
|
|
82
82
|
* Derive the recheck tier.
|
|
83
83
|
*
|
|
@@ -85,19 +85,18 @@ type InspectionPriority = LegacyInspectionPriority | ValueWeightedInspectionPrio
|
|
|
85
85
|
* signal freshness and the 90-day stable-zero guard, and should omit the value
|
|
86
86
|
* until those conditions make a dormant classification safe.
|
|
87
87
|
*/
|
|
88
|
-
declare function getNextCheckPriority(result: Pick<ParsedIndexingResult, 'verdict'>): LegacyInspectionPriority;
|
|
89
|
-
declare function getNextCheckPriority(result: Pick<ParsedIndexingResult, 'verdict'>, impressions28d: undefined): LegacyInspectionPriority;
|
|
90
|
-
declare function getNextCheckPriority(result: Pick<ParsedIndexingResult, 'verdict'>, impressions28d: number): ValueWeightedInspectionPriority;
|
|
91
|
-
declare function getNextCheckPriority(result: Pick<ParsedIndexingResult, 'verdict'>, impressions28d: number | undefined): InspectionPriority;
|
|
88
|
+
export declare function getNextCheckPriority(result: Pick<ParsedIndexingResult, 'verdict'>): LegacyInspectionPriority;
|
|
89
|
+
export declare function getNextCheckPriority(result: Pick<ParsedIndexingResult, 'verdict'>, impressions28d: undefined): LegacyInspectionPriority;
|
|
90
|
+
export declare function getNextCheckPriority(result: Pick<ParsedIndexingResult, 'verdict'>, impressions28d: number): ValueWeightedInspectionPriority;
|
|
91
|
+
export declare function getNextCheckPriority(result: Pick<ParsedIndexingResult, 'verdict'>, impressions28d: number | undefined): InspectionPriority;
|
|
92
92
|
/** Next-check unix seconds for a given priority. */
|
|
93
|
-
declare function getNextCheckAfter(priority: InspectionPriority): number;
|
|
94
|
-
declare function canUseUrlInspection(permissionLevel: string | null | undefined): boolean;
|
|
95
|
-
type IndexingIneligibleReason = 'missing_gsc_read_scope' | 'insufficient_gsc_permission';
|
|
96
|
-
interface IndexingEligibility {
|
|
93
|
+
export declare function getNextCheckAfter(priority: InspectionPriority): number;
|
|
94
|
+
export declare function canUseUrlInspection(permissionLevel: string | null | undefined): boolean;
|
|
95
|
+
export type IndexingIneligibleReason = 'missing_gsc_read_scope' | 'insufficient_gsc_permission';
|
|
96
|
+
export interface IndexingEligibility {
|
|
97
97
|
indexingEligible: boolean;
|
|
98
98
|
indexingIneligibleReason?: IndexingIneligibleReason;
|
|
99
99
|
indexingPermissionLevel?: string | null;
|
|
100
100
|
grantedScopes?: string[];
|
|
101
101
|
}
|
|
102
|
-
declare function getIndexingEligibility(grantedScopes: string | null | undefined, permissionLevel: string | null | undefined): IndexingEligibility;
|
|
103
|
-
export { BatchInspectUrlsFlatSettledOptions, IndexingEligibility, IndexingIneligibleReason, InspectUrlFlatSettledResult, InspectUrlResult, InspectionPriority, LegacyInspectionPriority, MAX_FLAT_INSPECTION_BATCH_CONCURRENCY, ParsedIndexingResult, ValueWeightedInspectionPriority, batchInspectUrls, batchInspectUrlsFlatSettled, canUseUrlInspection, getIndexingEligibility, getNextCheckAfter, getNextCheckPriority, inspectUrl, inspectUrlFlat };
|
|
102
|
+
export declare function getIndexingEligibility(grantedScopes: string | null | undefined, permissionLevel: string | null | undefined): IndexingEligibility;
|
package/dist/api/oauth.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Result } from "../core/result.mjs";
|
|
2
2
|
import { GscError } from "../core/errors.mjs";
|
|
3
|
-
interface OAuthTokens {
|
|
3
|
+
export interface OAuthTokens {
|
|
4
4
|
accessToken: string;
|
|
5
5
|
/** Unix seconds. */
|
|
6
6
|
expiresAt: number;
|
|
@@ -8,7 +8,7 @@ interface OAuthTokens {
|
|
|
8
8
|
scope?: string;
|
|
9
9
|
}
|
|
10
10
|
/** Normalized response from Google's access-token introspection endpoint. */
|
|
11
|
-
interface OAuthTokenInfo {
|
|
11
|
+
export interface OAuthTokenInfo {
|
|
12
12
|
issuedTo?: string;
|
|
13
13
|
audience?: string;
|
|
14
14
|
authorizedParty?: string;
|
|
@@ -28,21 +28,20 @@ interface OAuthTokenInfo {
|
|
|
28
28
|
* failures; surfaces HTTP failures (invalid_grant, etc.) immediately as
|
|
29
29
|
* `GscApiError` so callers can mark the refresh token as bad.
|
|
30
30
|
*/
|
|
31
|
-
declare function refreshAccessToken(refreshToken: string, clientId: string, clientSecret: string): Promise<OAuthTokens>;
|
|
31
|
+
export declare function refreshAccessToken(refreshToken: string, clientId: string, clientSecret: string): Promise<OAuthTokens>;
|
|
32
32
|
/**
|
|
33
33
|
* Exchange an authorization code (from the OAuth consent redirect) for
|
|
34
34
|
* access + refresh tokens. Same retry / surface model and `auth-expired` vs
|
|
35
35
|
* `transport` classification as {@link refreshAccessTokenResult}.
|
|
36
36
|
*/
|
|
37
|
-
declare function exchangeAuthCodeResult(code: string, clientId: string, clientSecret: string, redirectUri: string): Promise<Result<OAuthTokens & {
|
|
37
|
+
export declare function exchangeAuthCodeResult(code: string, clientId: string, clientSecret: string, redirectUri: string): Promise<Result<OAuthTokens & {
|
|
38
38
|
refreshToken?: string;
|
|
39
39
|
}, GscError>>;
|
|
40
40
|
/** Inspect an access token without throwing on expected OAuth failures. */
|
|
41
|
-
declare function introspectAccessTokenResult(accessToken: string): Promise<Result<OAuthTokenInfo, GscError>>;
|
|
41
|
+
export declare function introspectAccessTokenResult(accessToken: string): Promise<Result<OAuthTokenInfo, GscError>>;
|
|
42
42
|
/** Throwing convenience wrapper for {@link introspectAccessTokenResult}. */
|
|
43
|
-
declare function introspectAccessToken(accessToken: string): Promise<OAuthTokenInfo>;
|
|
43
|
+
export declare function introspectAccessToken(accessToken: string): Promise<OAuthTokenInfo>;
|
|
44
44
|
/** Revoke an access or refresh token without throwing on expected OAuth failures. */
|
|
45
|
-
declare function revokeOAuthTokenResult(token: string): Promise<Result<void, GscError>>;
|
|
45
|
+
export declare function revokeOAuthTokenResult(token: string): Promise<Result<void, GscError>>;
|
|
46
46
|
/** Throwing convenience wrapper for {@link revokeOAuthTokenResult}. */
|
|
47
|
-
declare function revokeOAuthToken(token: string): Promise<void>;
|
|
48
|
-
export { OAuthTokenInfo, OAuthTokens, exchangeAuthCodeResult, introspectAccessToken, introspectAccessTokenResult, refreshAccessToken, revokeOAuthToken, revokeOAuthTokenResult };
|
|
47
|
+
export declare function revokeOAuthToken(token: string): Promise<void>;
|
package/dist/api/oauth.mjs
CHANGED
|
@@ -99,6 +99,12 @@ async function postOAuthTokenResult(body, op) {
|
|
|
99
99
|
const parsed = await readOAuthJsonResult(response.value, op);
|
|
100
100
|
if (!parsed.ok) return parsed;
|
|
101
101
|
const data = parsed.value;
|
|
102
|
+
if (typeof data.access_token !== "string" || !data.access_token.trim() || typeof data.expires_in !== "number" || !Number.isFinite(data.expires_in) || data.expires_in < 0 || data.refresh_token !== void 0 && typeof data.refresh_token !== "string" || data.scope !== void 0 && typeof data.scope !== "string") return err({
|
|
103
|
+
kind: "transport",
|
|
104
|
+
message: `Invalid ${op} token response`,
|
|
105
|
+
status: response.value.status,
|
|
106
|
+
cause: /* @__PURE__ */ new TypeError("OAuth response requires a nonempty access_token and a finite, nonnegative expires_in.")
|
|
107
|
+
});
|
|
102
108
|
return ok({
|
|
103
109
|
accessToken: data.access_token,
|
|
104
110
|
expiresAt: Math.floor(Date.now() / 1e3) + data.expires_in,
|
|
@@ -133,7 +139,9 @@ async function requestOAuthResult(url, init, op) {
|
|
|
133
139
|
}
|
|
134
140
|
async function readOAuthJsonResult(response, op) {
|
|
135
141
|
try {
|
|
136
|
-
|
|
142
|
+
const value = await response.json();
|
|
143
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) throw new TypeError("OAuth response must be an object.");
|
|
144
|
+
return ok(value);
|
|
137
145
|
} catch (cause) {
|
|
138
146
|
return err({
|
|
139
147
|
kind: "transport",
|
package/dist/api/sites.d.mts
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
import { ApiSite, ApiSitemap, Site } from "../core/types.mjs";
|
|
2
2
|
import { GoogleSearchConsoleClient } from "../core/client.mjs";
|
|
3
|
-
interface FetchSitesWithSitemapsOptions {
|
|
3
|
+
export interface FetchSitesWithSitemapsOptions {
|
|
4
4
|
/** Maximum concurrent sitemap-list requests. Defaults to 4. */
|
|
5
5
|
concurrency?: number;
|
|
6
6
|
}
|
|
7
7
|
/**
|
|
8
8
|
* Fetches all sites the authenticated user has access to in Google Search Console.
|
|
9
9
|
*/
|
|
10
|
-
declare function fetchSites(client: GoogleSearchConsoleClient): Promise<ApiSite[]>;
|
|
10
|
+
export declare function fetchSites(client: GoogleSearchConsoleClient): Promise<ApiSite[]>;
|
|
11
11
|
/**
|
|
12
12
|
* Fetches all verified sites with their sitemaps from Google Search Console.
|
|
13
13
|
*/
|
|
14
|
-
declare function fetchSitesWithSitemaps(client: GoogleSearchConsoleClient, options?: FetchSitesWithSitemapsOptions): Promise<(Site & {
|
|
14
|
+
export declare function fetchSitesWithSitemaps(client: GoogleSearchConsoleClient, options?: FetchSitesWithSitemapsOptions): Promise<(Site & {
|
|
15
15
|
sitemaps: ApiSitemap[];
|
|
16
16
|
})[]>;
|
|
17
17
|
/**
|
|
18
18
|
* Fetches all sitemaps for a site.
|
|
19
19
|
*/
|
|
20
|
-
declare function fetchSitemaps(client: GoogleSearchConsoleClient, siteUrl: string): Promise<ApiSitemap[]>;
|
|
20
|
+
export declare function fetchSitemaps(client: GoogleSearchConsoleClient, siteUrl: string): Promise<ApiSitemap[]>;
|
|
21
21
|
/**
|
|
22
22
|
* Fetches a specific sitemap.
|
|
23
23
|
*/
|
|
24
|
-
declare function fetchSitemap(client: GoogleSearchConsoleClient, siteUrl: string, feedpath: string): Promise<ApiSitemap>;
|
|
24
|
+
export declare function fetchSitemap(client: GoogleSearchConsoleClient, siteUrl: string, feedpath: string): Promise<ApiSitemap>;
|
|
25
25
|
/**
|
|
26
26
|
* Submits a sitemap to Google Search Console.
|
|
27
27
|
*/
|
|
28
|
-
declare function submitSitemap(client: GoogleSearchConsoleClient, siteUrl: string, feedpath: string): Promise<void>;
|
|
28
|
+
export declare function submitSitemap(client: GoogleSearchConsoleClient, siteUrl: string, feedpath: string): Promise<void>;
|
|
29
29
|
/**
|
|
30
30
|
* Deletes a sitemap from Google Search Console.
|
|
31
31
|
*/
|
|
32
|
-
declare function deleteSitemap(client: GoogleSearchConsoleClient, siteUrl: string, feedpath: string): Promise<void>;
|
|
32
|
+
export declare function deleteSitemap(client: GoogleSearchConsoleClient, siteUrl: string, feedpath: string): Promise<void>;
|
|
33
33
|
/**
|
|
34
34
|
* Add a property to the user's Search Console account.
|
|
35
35
|
*
|
|
@@ -37,9 +37,8 @@ declare function deleteSitemap(client: GoogleSearchConsoleClient, siteUrl: strin
|
|
|
37
37
|
* must be proven via the Site Verification API (see `verifySite`) before any
|
|
38
38
|
* data is accessible.
|
|
39
39
|
*/
|
|
40
|
-
declare function addSite(client: GoogleSearchConsoleClient, siteUrl: string): Promise<void>;
|
|
40
|
+
export declare function addSite(client: GoogleSearchConsoleClient, siteUrl: string): Promise<void>;
|
|
41
41
|
/**
|
|
42
42
|
* Remove a property from the user's Search Console account.
|
|
43
43
|
*/
|
|
44
|
-
declare function deleteSite(client: GoogleSearchConsoleClient, siteUrl: string): Promise<void>;
|
|
45
|
-
export { FetchSitesWithSitemapsOptions, addSite, deleteSite, deleteSitemap, fetchSitemap, fetchSitemaps, fetchSites, fetchSitesWithSitemaps, submitSitemap };
|
|
44
|
+
export declare function deleteSite(client: GoogleSearchConsoleClient, siteUrl: string): Promise<void>;
|
|
@@ -3,9 +3,9 @@ import { GoogleSearchConsoleClient, VerificationMethod, VerificationSite, Verifi
|
|
|
3
3
|
* Resolve a Search Console site URL (`https://example.com/` or
|
|
4
4
|
* `sc-domain:example.com`) to the Site Verification API's site shape.
|
|
5
5
|
*/
|
|
6
|
-
declare function siteUrlToVerificationSite(siteUrl: string): VerificationSite;
|
|
6
|
+
export declare function siteUrlToVerificationSite(siteUrl: string): VerificationSite;
|
|
7
7
|
/** Resolve a Search Console property and method to Google's verification target. */
|
|
8
|
-
declare function resolveVerificationTarget(siteUrl: string, method?: VerificationMethod): {
|
|
8
|
+
export declare function resolveVerificationTarget(siteUrl: string, method?: VerificationMethod): {
|
|
9
9
|
site: VerificationSite;
|
|
10
10
|
method: VerificationMethod;
|
|
11
11
|
};
|
|
@@ -13,31 +13,30 @@ declare function resolveVerificationTarget(siteUrl: string, method?: Verificatio
|
|
|
13
13
|
* Methods valid for a given site shape. SITE properties can use META/FILE/
|
|
14
14
|
* ANALYTICS/TAG_MANAGER; INET_DOMAIN must use DNS_TXT or DNS_CNAME.
|
|
15
15
|
*/
|
|
16
|
-
declare function verificationMethodsFor(site: VerificationSite): VerificationMethod[];
|
|
16
|
+
export declare function verificationMethodsFor(site: VerificationSite): VerificationMethod[];
|
|
17
17
|
/**
|
|
18
18
|
* Get the verification token Google expects to find on the site or DNS.
|
|
19
19
|
*/
|
|
20
|
-
declare function getVerificationToken(client: GoogleSearchConsoleClient, siteUrl: string, method: VerificationMethod): Promise<VerificationToken & {
|
|
20
|
+
export declare function getVerificationToken(client: GoogleSearchConsoleClient, siteUrl: string, method: VerificationMethod): Promise<VerificationToken & {
|
|
21
21
|
site: VerificationSite;
|
|
22
22
|
}>;
|
|
23
23
|
/**
|
|
24
24
|
* Trigger Google to validate the placed token. Caller is responsible for
|
|
25
25
|
* having placed the token (HTML tag / file / DNS record) before calling.
|
|
26
26
|
*/
|
|
27
|
-
declare function verifySite(client: GoogleSearchConsoleClient, siteUrl: string, method: VerificationMethod): Promise<VerificationWebResource>;
|
|
27
|
+
export declare function verifySite(client: GoogleSearchConsoleClient, siteUrl: string, method: VerificationMethod): Promise<VerificationWebResource>;
|
|
28
28
|
/**
|
|
29
29
|
* List all verified WebResources for the authed user.
|
|
30
30
|
*/
|
|
31
|
-
declare function listVerifiedSites(client: GoogleSearchConsoleClient): Promise<VerificationWebResource[]>;
|
|
31
|
+
export declare function listVerifiedSites(client: GoogleSearchConsoleClient): Promise<VerificationWebResource[]>;
|
|
32
32
|
/**
|
|
33
33
|
* Fetch a single verified WebResource by id.
|
|
34
34
|
*/
|
|
35
|
-
declare function getVerifiedSite(client: GoogleSearchConsoleClient, id: string): Promise<VerificationWebResource>;
|
|
35
|
+
export declare function getVerifiedSite(client: GoogleSearchConsoleClient, id: string): Promise<VerificationWebResource>;
|
|
36
36
|
/**
|
|
37
37
|
* Drop the calling user's verified ownership of a WebResource. The placed
|
|
38
38
|
* verification token (meta tag / file / DNS record) MUST be removed first,
|
|
39
39
|
* otherwise Google may auto-re-verify and the call will fail. Other owners
|
|
40
40
|
* on the property are unaffected.
|
|
41
41
|
*/
|
|
42
|
-
declare function unverifySite(client: GoogleSearchConsoleClient, id: string): Promise<void>;
|
|
43
|
-
export { getVerificationToken, getVerifiedSite, listVerifiedSites, resolveVerificationTarget, siteUrlToVerificationSite, unverifySite, verificationMethodsFor, verifySite };
|
|
42
|
+
export declare function unverifySite(client: GoogleSearchConsoleClient, id: string): Promise<void>;
|
package/dist/bing/client.d.mts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { BingWebmasterClient, BingWebmasterOptions } from "./types.mjs";
|
|
2
|
-
declare const DEFAULT_BING_WEBMASTER_API_URL = "https://www.bing.com/webmaster/api.svc/json";
|
|
3
|
-
declare const DEFAULT_BING_CHILD_PAGE_LIMIT = 100;
|
|
4
|
-
declare function bingWebmaster(options: BingWebmasterOptions): BingWebmasterClient;
|
|
5
|
-
export { DEFAULT_BING_CHILD_PAGE_LIMIT, DEFAULT_BING_WEBMASTER_API_URL, bingWebmaster };
|
|
2
|
+
export declare const DEFAULT_BING_WEBMASTER_API_URL = "https://www.bing.com/webmaster/api.svc/json";
|
|
3
|
+
export declare const DEFAULT_BING_CHILD_PAGE_LIMIT = 100;
|
|
4
|
+
export declare function bingWebmaster(options: BingWebmasterOptions): BingWebmasterClient;
|
package/dist/bing/client.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { err, ok } from "../core/result.mjs";
|
|
2
2
|
import { normalizeBingCrawlIssue, normalizeBingCrawlStats, normalizeBingIndexingEvidence, normalizeBingPageStats, normalizeBingQueryStats, normalizeBingRankAndTrafficStats, normalizeBingSite, normalizeBingUrlInfo, normalizeBingUrlTrafficInfo } from "./normalize.mjs";
|
|
3
3
|
const DEFAULT_BING_WEBMASTER_API_URL = "https://www.bing.com/webmaster/api.svc/json";
|
|
4
|
+
const DEFAULT_BING_API_KEY_URL = "https://ssl.bing.com/webmaster/api.svc/json";
|
|
4
5
|
const DEFAULT_BING_CHILD_PAGE_LIMIT = 100;
|
|
5
6
|
const BING_MAX_CHILD_PAGE_COUNT = 65536;
|
|
6
7
|
function isRecord(value) {
|
|
@@ -109,24 +110,29 @@ function toFilterProperties(filters = {}) {
|
|
|
109
110
|
};
|
|
110
111
|
}
|
|
111
112
|
function bingWebmaster(options) {
|
|
112
|
-
const baseUrl = (options.baseUrl ?? "https://www.bing.com/webmaster/api.svc/json").replace(/\/+$/, "");
|
|
113
|
+
const baseUrl = (options.baseUrl ?? (options.apiKey === void 0 ? "https://www.bing.com/webmaster/api.svc/json" : DEFAULT_BING_API_KEY_URL)).replace(/\/+$/, "");
|
|
113
114
|
const clock = options.clock ?? (() => /* @__PURE__ */ new Date());
|
|
114
115
|
const fetch = options.fetch ?? globalThis.fetch.bind(globalThis);
|
|
115
116
|
const request = async (operation, parser, input = {}) => {
|
|
116
|
-
|
|
117
|
+
const accessToken = typeof options.accessToken === "function" ? await options.accessToken() : options.accessToken;
|
|
118
|
+
if (!(options.apiKey ?? accessToken)?.trim()) return err({ _tag: "AuthenticationRequired" });
|
|
117
119
|
const url = new URL(`${baseUrl}/${operation}`);
|
|
120
|
+
if (options.apiKey !== void 0) url.searchParams.set("apikey", options.apiKey);
|
|
118
121
|
for (const [key, value] of Object.entries(input.query ?? {})) url.searchParams.set(key, value);
|
|
119
122
|
const response = await fetch(url.toString(), {
|
|
120
123
|
...input.body === void 0 ? {} : { body: JSON.stringify(input.body) },
|
|
121
124
|
headers: {
|
|
122
125
|
Accept: "application/json",
|
|
123
|
-
Authorization: `Bearer ${
|
|
126
|
+
...accessToken === void 0 ? {} : { Authorization: `Bearer ${accessToken}` },
|
|
124
127
|
...input.body === void 0 ? {} : { "Content-Type": "application/json; charset=utf-8" }
|
|
125
128
|
},
|
|
126
129
|
method: input.method ?? "GET",
|
|
127
130
|
signal: input.signal
|
|
128
131
|
});
|
|
129
|
-
const payload = await response.json().then((value) => ok(value)).catch(() =>
|
|
132
|
+
const payload = await response.json().then((value) => ok(value)).catch((cause) => {
|
|
133
|
+
if (cause instanceof SyntaxError) return err("invalid-json");
|
|
134
|
+
throw cause;
|
|
135
|
+
});
|
|
130
136
|
if (!response.ok) return err(mapResponseError(response, payload.ok ? payload.value : void 0, clock()));
|
|
131
137
|
if (!payload.ok) return err({
|
|
132
138
|
_tag: "MalformedResponse",
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { Result } from "../core/result.mjs";
|
|
2
2
|
import { BingCrawlStats, BingEvidenceError, BingIndexingEvidence, BingPageStats, BingQueryStats, BingRankAndTrafficStats, BingSite, BingUrlInfo, BingUrlTrafficInfo, BingUrlWithCrawlIssues } from "./types.mjs";
|
|
3
|
-
declare function normalizeBingSite(value: unknown): Result<BingSite, 'invalid-payload'>;
|
|
4
|
-
declare function normalizeBingUrlInfo(value: unknown): Result<BingUrlInfo, 'invalid-payload'>;
|
|
5
|
-
declare function normalizeBingUrlTrafficInfo(value: unknown): Result<BingUrlTrafficInfo, 'invalid-payload'>;
|
|
6
|
-
declare function normalizeBingPageStats(value: unknown): Result<BingPageStats, 'invalid-payload'>;
|
|
7
|
-
declare function normalizeBingQueryStats(value: unknown): Result<BingQueryStats, 'invalid-payload'>;
|
|
8
|
-
declare function normalizeBingRankAndTrafficStats(value: unknown): Result<BingRankAndTrafficStats, 'invalid-payload'>;
|
|
9
|
-
declare function normalizeBingCrawlStats(value: unknown): Result<BingCrawlStats, 'invalid-payload'>;
|
|
10
|
-
declare function normalizeBingCrawlIssue(value: unknown): Result<BingUrlWithCrawlIssues, 'invalid-payload'>;
|
|
11
|
-
declare function normalizeBingIndexingEvidence(info: BingUrlInfo | null, url: string, observedAt: Date): Result<BingIndexingEvidence, BingEvidenceError>;
|
|
12
|
-
export { normalizeBingCrawlIssue, normalizeBingCrawlStats, normalizeBingIndexingEvidence, normalizeBingPageStats, normalizeBingQueryStats, normalizeBingRankAndTrafficStats, normalizeBingSite, normalizeBingUrlInfo, normalizeBingUrlTrafficInfo };
|
|
3
|
+
export declare function normalizeBingSite(value: unknown): Result<BingSite, 'invalid-payload'>;
|
|
4
|
+
export declare function normalizeBingUrlInfo(value: unknown): Result<BingUrlInfo, 'invalid-payload'>;
|
|
5
|
+
export declare function normalizeBingUrlTrafficInfo(value: unknown): Result<BingUrlTrafficInfo, 'invalid-payload'>;
|
|
6
|
+
export declare function normalizeBingPageStats(value: unknown): Result<BingPageStats, 'invalid-payload'>;
|
|
7
|
+
export declare function normalizeBingQueryStats(value: unknown): Result<BingQueryStats, 'invalid-payload'>;
|
|
8
|
+
export declare function normalizeBingRankAndTrafficStats(value: unknown): Result<BingRankAndTrafficStats, 'invalid-payload'>;
|
|
9
|
+
export declare function normalizeBingCrawlStats(value: unknown): Result<BingCrawlStats, 'invalid-payload'>;
|
|
10
|
+
export declare function normalizeBingCrawlIssue(value: unknown): Result<BingUrlWithCrawlIssues, 'invalid-payload'>;
|
|
11
|
+
export declare function normalizeBingIndexingEvidence(info: BingUrlInfo | null, url: string, observedAt: Date): Result<BingIndexingEvidence, BingEvidenceError>;
|