gscdump 0.1.3 → 0.3.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 +4 -9
- package/dist/analysis/index.d.mts +513 -0
- package/dist/analysis/index.mjs +872 -0
- package/dist/index.d.mts +126 -908
- package/dist/index.mjs +290 -3413
- package/dist/query/index.d.mts +72 -55
- package/dist/query/index.mjs +208 -87
- package/package.json +5 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import _dayjs, { Dayjs } from "dayjs";
|
|
2
1
|
import { $Fetch, FetchOptions } from "ofetch";
|
|
3
2
|
import { indexing_v3 } from "@googleapis/indexing/v3";
|
|
4
3
|
import { searchconsole_v1 } from "@googleapis/searchconsole/v1";
|
|
@@ -71,500 +70,109 @@ interface SiteAnalytics {
|
|
|
71
70
|
}[];
|
|
72
71
|
}
|
|
73
72
|
//#endregion
|
|
74
|
-
//#region src/
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
domain?: string;
|
|
82
|
-
filters?: DimensionFilter[];
|
|
83
|
-
/** Data type: web, image, video, news, discover, googleNews. Default: web */
|
|
84
|
-
type?: DataType;
|
|
85
|
-
/** Data state: final (settled data) or all (includes fresh/unfinalized). Default: all */
|
|
86
|
-
dataState?: DataState;
|
|
87
|
-
/**
|
|
88
|
-
* Aggregation type: byPage (per-URL metrics) or byProperty (domain-level rollup).
|
|
89
|
-
* Use byProperty for sc-domain: properties to get true totals.
|
|
90
|
-
* byPage can undercount when same query hits multiple pages.
|
|
91
|
-
* Default: byPage
|
|
92
|
-
*/
|
|
93
|
-
aggregationType?: AggregationType;
|
|
94
|
-
/** Maximum rows to return. Default: 25000 (GSC API limit per request) */
|
|
95
|
-
rowLimit?: number;
|
|
96
|
-
}
|
|
97
|
-
interface ComparisonResult<T> {
|
|
98
|
-
current: T[];
|
|
99
|
-
previous: T[];
|
|
100
|
-
metadata?: {
|
|
101
|
-
currentCount: number;
|
|
102
|
-
previousCount: number;
|
|
103
|
-
[key: string]: unknown;
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
interface DeviceData extends Omit<DataRow, 'keys'> {
|
|
107
|
-
dimension: 'device';
|
|
108
|
-
device: string;
|
|
109
|
-
keys: null;
|
|
110
|
-
}
|
|
111
|
-
interface CountryData extends Omit<DataRow, 'keys'> {
|
|
112
|
-
dimension: 'country';
|
|
113
|
-
countryCodeGsc: string;
|
|
114
|
-
country: string;
|
|
115
|
-
countryCode: string;
|
|
116
|
-
keywords?: number;
|
|
117
|
-
keys: null;
|
|
118
|
-
}
|
|
119
|
-
interface AnalyticsData extends Omit<DataRow, 'keys'> {
|
|
120
|
-
keywords: DataRow[];
|
|
121
|
-
}
|
|
122
|
-
interface PageData extends Omit<DataRow, 'keys'> {
|
|
123
|
-
dimension: 'page';
|
|
124
|
-
page: string;
|
|
125
|
-
keyword?: string;
|
|
126
|
-
keywordPosition?: number;
|
|
127
|
-
prevClicks?: number;
|
|
128
|
-
clicksPercent?: number;
|
|
129
|
-
prevImpressions?: number;
|
|
130
|
-
impressionsPercent?: number;
|
|
131
|
-
lost?: boolean;
|
|
132
|
-
keys: null;
|
|
133
|
-
}
|
|
134
|
-
interface KeywordData extends Omit<DataRow, 'keys'> {
|
|
135
|
-
dimension: 'query';
|
|
136
|
-
keyword: string;
|
|
137
|
-
page?: string | null;
|
|
138
|
-
positionPercent?: number;
|
|
139
|
-
prevPosition?: number;
|
|
140
|
-
ctrPercent?: number;
|
|
141
|
-
prevCtr?: number;
|
|
142
|
-
lost?: boolean;
|
|
143
|
-
prevClicks?: number;
|
|
144
|
-
prevImpressions?: number;
|
|
145
|
-
keys: null;
|
|
146
|
-
}
|
|
147
|
-
interface DateData extends Omit<DataRow, 'keys'> {
|
|
148
|
-
dimension: 'date';
|
|
149
|
-
date: string;
|
|
150
|
-
keys: null;
|
|
151
|
-
}
|
|
152
|
-
interface SearchAppearanceData extends Omit<DataRow, 'keys'> {
|
|
153
|
-
dimension: 'searchAppearance';
|
|
154
|
-
searchAppearance: string;
|
|
155
|
-
keys: null;
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Discriminated union of all query result row types.
|
|
159
|
-
* Use the `dimension` field to narrow to specific types.
|
|
160
|
-
*/
|
|
161
|
-
type QueryResultRow = DateData | DeviceData | CountryData | PageData | KeywordData | SearchAppearanceData;
|
|
162
|
-
interface DateRow extends Omit<DataRow, 'keys'> {
|
|
163
|
-
date: string;
|
|
164
|
-
keys: null;
|
|
165
|
-
}
|
|
166
|
-
interface KeywordRow extends Omit<DataRow, 'keys'> {
|
|
167
|
-
keyword: string;
|
|
168
|
-
keys: null;
|
|
169
|
-
}
|
|
170
|
-
interface PageRow extends Omit<DataRow, 'keys'> {
|
|
171
|
-
page: string;
|
|
172
|
-
keys: null;
|
|
173
|
-
}
|
|
174
|
-
interface FetchPageResult {
|
|
175
|
-
dates: DateRow[];
|
|
176
|
-
keywords: KeywordRow[];
|
|
177
|
-
}
|
|
178
|
-
interface FetchKeywordResult {
|
|
179
|
-
dates: DateRow[];
|
|
180
|
-
pages: PageRow[];
|
|
181
|
-
}
|
|
73
|
+
//#region src/query/utils/countries.d.ts
|
|
74
|
+
declare const _default: {
|
|
75
|
+
name: string;
|
|
76
|
+
'alpha-2': string;
|
|
77
|
+
'alpha-3': string;
|
|
78
|
+
'country-code': string;
|
|
79
|
+
}[];
|
|
182
80
|
//#endregion
|
|
183
|
-
//#region src/
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
nonBrand: KeywordData[];
|
|
200
|
-
summary: BrandSummary;
|
|
201
|
-
}
|
|
202
|
-
/**
|
|
203
|
-
* Segments keywords into brand and non-brand based on provided brand terms.
|
|
204
|
-
* Simple string matching - keyword contains any brand term (case-insensitive).
|
|
205
|
-
*/
|
|
206
|
-
declare function analyzeBrandSegmentation(keywords: KeywordData[], options: BrandSegmentationOptions): BrandSegmentationResult;
|
|
81
|
+
//#region src/query/constants.d.ts
|
|
82
|
+
declare const Devices: {
|
|
83
|
+
readonly MOBILE: "MOBILE";
|
|
84
|
+
readonly DESKTOP: "DESKTOP";
|
|
85
|
+
readonly TABLET: "TABLET";
|
|
86
|
+
};
|
|
87
|
+
type Device = typeof Devices[keyof typeof Devices];
|
|
88
|
+
declare const SearchTypes: {
|
|
89
|
+
readonly WEB: "web";
|
|
90
|
+
readonly IMAGE: "image";
|
|
91
|
+
readonly VIDEO: "video";
|
|
92
|
+
readonly NEWS: "news";
|
|
93
|
+
};
|
|
94
|
+
type SearchType = typeof SearchTypes[keyof typeof SearchTypes];
|
|
95
|
+
declare const Countries: { [K in (typeof _default)[number]["alpha-3"]]: Lowercase<K> };
|
|
96
|
+
type Country = typeof Countries[keyof typeof Countries];
|
|
207
97
|
//#endregion
|
|
208
|
-
//#region src/
|
|
209
|
-
|
|
210
|
-
* Shared types for pure analysis functions.
|
|
211
|
-
* These types describe the inputs and outputs of analysis functions
|
|
212
|
-
* that operate on data, independent of how it was fetched.
|
|
213
|
-
*/
|
|
214
|
-
type SortOrder = 'asc' | 'desc';
|
|
215
|
-
/** Base search metrics present on all data rows */
|
|
216
|
-
interface BaseMetrics {
|
|
217
|
-
clicks: number;
|
|
218
|
-
impressions: number;
|
|
219
|
-
ctr: number;
|
|
220
|
-
position: number;
|
|
221
|
-
}
|
|
222
|
-
/** Row with both query and page dimensions */
|
|
223
|
-
interface QueryPageRow extends BaseMetrics {
|
|
98
|
+
//#region src/query/types.d.ts
|
|
99
|
+
interface DimensionValueMap {
|
|
224
100
|
query: string;
|
|
101
|
+
queryCanonical: string;
|
|
225
102
|
page: string;
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
103
|
+
country: Country;
|
|
104
|
+
device: Device;
|
|
105
|
+
searchAppearance: string;
|
|
229
106
|
date: string;
|
|
230
107
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
declare function createSorter<T, M extends string>(getValue: (item: T, metric: M) => number, defaultMetric: M, defaultOrder?: SortOrder): (items: T[], sortBy?: M, sortOrder?: SortOrder) => T[];
|
|
235
|
-
//#endregion
|
|
236
|
-
//#region src/analysis/cannibalization.d.ts
|
|
237
|
-
type CannibalizationSortMetric = 'clicks' | 'impressions' | 'positionSpread' | 'pageCount';
|
|
238
|
-
interface CannibalizationOptions {
|
|
239
|
-
/** Minimum impressions for a query to be considered. Default: 10 */
|
|
240
|
-
minImpressions?: number;
|
|
241
|
-
/** Maximum position spread to flag as cannibalization. Default: 10 */
|
|
242
|
-
maxPositionSpread?: number;
|
|
243
|
-
/** Minimum number of pages ranking for same query. Default: 2 */
|
|
244
|
-
minPages?: number;
|
|
245
|
-
/** Sort metric. Default: clicks */
|
|
246
|
-
sortBy?: CannibalizationSortMetric;
|
|
247
|
-
/** Sort order. Default: desc */
|
|
248
|
-
sortOrder?: SortOrder;
|
|
249
|
-
}
|
|
250
|
-
interface CannibalizationPage {
|
|
251
|
-
page: string;
|
|
252
|
-
clicks: number;
|
|
253
|
-
impressions: number;
|
|
254
|
-
ctr: number;
|
|
255
|
-
position: number;
|
|
256
|
-
}
|
|
257
|
-
interface CannibalizationResult {
|
|
258
|
-
query: string;
|
|
259
|
-
pages: CannibalizationPage[];
|
|
260
|
-
totalClicks: number;
|
|
261
|
-
totalImpressions: number;
|
|
262
|
-
positionSpread: number;
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Detects keyword cannibalization - queries ranking for multiple pages.
|
|
266
|
-
* Returns queries where multiple pages compete for the same search term.
|
|
267
|
-
*
|
|
268
|
-
* @param rows Query+page data rows
|
|
269
|
-
* @param options Filtering and sorting options
|
|
270
|
-
*/
|
|
271
|
-
declare function analyzeCannibalization(rows: QueryPageRow[], options?: CannibalizationOptions): CannibalizationResult[];
|
|
272
|
-
//#endregion
|
|
273
|
-
//#region src/analysis/clustering.d.ts
|
|
274
|
-
type ClusterType = 'prefix' | 'intent' | 'both';
|
|
275
|
-
interface ClusteringOptions {
|
|
276
|
-
/** Minimum keywords for a cluster to be reported. Default: 2 */
|
|
277
|
-
minClusterSize?: number;
|
|
278
|
-
/** Minimum impressions for a keyword to be included. Default: 10 */
|
|
279
|
-
minImpressions?: number;
|
|
280
|
-
/** Clustering method. Default: 'both' */
|
|
281
|
-
clusterBy?: ClusterType;
|
|
282
|
-
}
|
|
283
|
-
interface KeywordCluster {
|
|
284
|
-
clusterName: string;
|
|
285
|
-
clusterType: 'prefix' | 'intent';
|
|
286
|
-
keywords: KeywordData[];
|
|
287
|
-
totalClicks: number;
|
|
288
|
-
totalImpressions: number;
|
|
289
|
-
avgPosition: number;
|
|
290
|
-
keywordCount: number;
|
|
291
|
-
}
|
|
292
|
-
interface ClusteringResult {
|
|
293
|
-
clusters: KeywordCluster[];
|
|
294
|
-
unclustered: KeywordData[];
|
|
295
|
-
}
|
|
296
|
-
/**
|
|
297
|
-
* Clusters keywords by intent prefix or common word prefix.
|
|
298
|
-
* Simple regex/prefix approach - no external NLP dependencies.
|
|
299
|
-
*
|
|
300
|
-
* @param keywords Array of keyword data
|
|
301
|
-
* @param options Clustering options
|
|
302
|
-
*/
|
|
303
|
-
declare function analyzeClustering(keywords: KeywordData[], options?: ClusteringOptions): ClusteringResult;
|
|
304
|
-
//#endregion
|
|
305
|
-
//#region src/analysis/concentration.d.ts
|
|
306
|
-
/**
|
|
307
|
-
* Traffic concentration analysis - measures distribution across pages/keywords.
|
|
308
|
-
* Pure function operating on page or keyword data.
|
|
309
|
-
*/
|
|
310
|
-
type ConcentrationRiskLevel = 'low' | 'medium' | 'high';
|
|
311
|
-
interface ConcentrationOptions {
|
|
312
|
-
/** Number of top items to report. Default: 10 */
|
|
313
|
-
topN?: number;
|
|
314
|
-
}
|
|
315
|
-
interface ConcentrationItem {
|
|
316
|
-
key: string;
|
|
317
|
-
clicks: number;
|
|
318
|
-
share: number;
|
|
319
|
-
}
|
|
320
|
-
interface ConcentrationResult {
|
|
321
|
-
/** Gini coefficient: 0 = equal distribution, 1 = fully concentrated */
|
|
322
|
-
giniCoefficient: number;
|
|
323
|
-
/** Herfindahl-Hirschman Index: 0-10000, >2500 = highly concentrated */
|
|
324
|
-
hhi: number;
|
|
325
|
-
/** Percentage of total clicks from top N items */
|
|
326
|
-
topNConcentration: number;
|
|
327
|
-
topNItems: ConcentrationItem[];
|
|
328
|
-
totalItems: number;
|
|
329
|
-
totalClicks: number;
|
|
330
|
-
/** Risk level derived from HHI: <1500 low, 1500-2500 medium, >2500 high */
|
|
331
|
-
riskLevel: ConcentrationRiskLevel;
|
|
332
|
-
}
|
|
333
|
-
/** Item with a key and clicks for concentration analysis */
|
|
334
|
-
interface ConcentrationInput {
|
|
335
|
-
key: string;
|
|
336
|
-
clicks: number;
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Analyzes traffic concentration across items (pages or keywords).
|
|
340
|
-
* Returns Gini coefficient, HHI, and top-N concentration metrics.
|
|
341
|
-
*
|
|
342
|
-
* @param items Array of items with key and clicks
|
|
343
|
-
* @param options Configuration options
|
|
344
|
-
*/
|
|
345
|
-
declare function analyzeConcentration(items: ConcentrationInput[], options?: ConcentrationOptions): ConcentrationResult;
|
|
346
|
-
/** Item with page and optional/nullable clicks */
|
|
347
|
-
interface PageLike {
|
|
348
|
-
page: string;
|
|
349
|
-
clicks?: number | null;
|
|
350
|
-
}
|
|
351
|
-
/** Item with keyword and optional/nullable clicks */
|
|
352
|
-
interface KeywordLike {
|
|
353
|
-
keyword: string;
|
|
354
|
-
clicks?: number | null;
|
|
355
|
-
}
|
|
356
|
-
/**
|
|
357
|
-
* Convenience wrapper for page concentration analysis.
|
|
358
|
-
*/
|
|
359
|
-
declare function analyzePageConcentration(pages: PageLike[], options?: ConcentrationOptions): ConcentrationResult;
|
|
360
|
-
/**
|
|
361
|
-
* Convenience wrapper for keyword concentration analysis.
|
|
362
|
-
*/
|
|
363
|
-
declare function analyzeKeywordConcentration(keywords: KeywordLike[], options?: ConcentrationOptions): ConcentrationResult;
|
|
364
|
-
//#endregion
|
|
365
|
-
//#region src/analysis/decay.d.ts
|
|
366
|
-
type DecaySortMetric = 'lostClicks' | 'declinePercent' | 'currentClicks';
|
|
367
|
-
interface DecayOptions {
|
|
368
|
-
/** Minimum clicks in previous period to consider. Default: 50 */
|
|
369
|
-
minPreviousClicks?: number;
|
|
370
|
-
/** Minimum decline percentage (0-1). Default: 0.2 (20%) */
|
|
371
|
-
threshold?: number;
|
|
372
|
-
/** Metric to sort results by. Default: lostClicks */
|
|
373
|
-
sortBy?: DecaySortMetric;
|
|
374
|
-
}
|
|
375
|
-
interface DecayInput {
|
|
376
|
-
current: PageData[];
|
|
377
|
-
previous: PageData[];
|
|
378
|
-
}
|
|
379
|
-
interface DecayResult {
|
|
380
|
-
page: string;
|
|
381
|
-
currentClicks: number;
|
|
382
|
-
previousClicks: number;
|
|
383
|
-
lostClicks: number;
|
|
384
|
-
declinePercent: number;
|
|
385
|
-
currentPosition: number;
|
|
386
|
-
previousPosition: number;
|
|
387
|
-
positionDrop: number;
|
|
388
|
-
}
|
|
389
|
-
/**
|
|
390
|
-
* Identifies "decaying" content - pages that have lost significant traffic.
|
|
391
|
-
* Useful for finding old content that needs updating.
|
|
392
|
-
*
|
|
393
|
-
* @param input Current and previous period page data
|
|
394
|
-
* @param options Filtering and sorting options
|
|
395
|
-
*/
|
|
396
|
-
declare function analyzeDecay(input: DecayInput, options?: DecayOptions): DecayResult[];
|
|
397
|
-
//#endregion
|
|
398
|
-
//#region src/analysis/movers.d.ts
|
|
399
|
-
type MoversSortMetric = 'clicks' | 'impressions' | 'clicksChange' | 'impressionsChange' | 'positionChange';
|
|
400
|
-
interface MoversOptions {
|
|
401
|
-
/** Minimum change threshold to flag. Default: 0.2 (20%) */
|
|
402
|
-
changeThreshold?: number;
|
|
403
|
-
/** Minimum impressions in recent period. Default: 50 */
|
|
404
|
-
minImpressions?: number;
|
|
405
|
-
/** Metric to sort results by. Default: clicksChange */
|
|
406
|
-
sortBy?: MoversSortMetric;
|
|
407
|
-
}
|
|
408
|
-
interface MoversInput {
|
|
409
|
-
current: KeywordData[];
|
|
410
|
-
previous: KeywordData[];
|
|
411
|
-
/** If periods have different lengths, provide normalization factor (previous/current) */
|
|
412
|
-
normalizationFactor?: number;
|
|
413
|
-
}
|
|
414
|
-
interface MoverData {
|
|
415
|
-
keyword: string;
|
|
416
|
-
page: string | null;
|
|
417
|
-
recentClicks: number;
|
|
418
|
-
recentImpressions: number;
|
|
419
|
-
recentPosition: number;
|
|
420
|
-
baselineClicks: number;
|
|
421
|
-
baselineImpressions: number;
|
|
422
|
-
baselinePosition: number;
|
|
423
|
-
clicksChange: number;
|
|
424
|
-
clicksChangePercent: number;
|
|
425
|
-
impressionsChangePercent: number;
|
|
426
|
-
positionChange: number;
|
|
427
|
-
}
|
|
428
|
-
interface MoversResult {
|
|
429
|
-
rising: MoverData[];
|
|
430
|
-
declining: MoverData[];
|
|
431
|
-
stable: MoverData[];
|
|
108
|
+
type Dimension = keyof DimensionValueMap;
|
|
109
|
+
interface QueryParamValueMap {
|
|
110
|
+
searchType: SearchType;
|
|
432
111
|
}
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
* @param options Filtering and sorting options
|
|
439
|
-
*/
|
|
440
|
-
declare function analyzeMovers(input: MoversInput, options?: MoversOptions): MoversResult;
|
|
441
|
-
//#endregion
|
|
442
|
-
//#region src/analysis/opportunity.d.ts
|
|
443
|
-
type OpportunitySortMetric = 'opportunityScore' | 'potentialClicks' | 'impressions' | 'position';
|
|
444
|
-
interface OpportunityWeights {
|
|
445
|
-
position?: number;
|
|
446
|
-
impressions?: number;
|
|
447
|
-
ctrGap?: number;
|
|
112
|
+
type QueryParamName = keyof QueryParamValueMap;
|
|
113
|
+
declare const ColumnBrand: unique symbol;
|
|
114
|
+
interface Column<D extends Dimension> {
|
|
115
|
+
readonly [ColumnBrand]: D;
|
|
116
|
+
readonly dimension: D;
|
|
448
117
|
}
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
118
|
+
type FilterOperator = 'equals' | 'notEquals' | 'contains' | 'notContains' | 'includingRegex' | 'excludingRegex';
|
|
119
|
+
type DateOperator = 'gte' | 'gt' | 'lte' | 'lt' | 'between';
|
|
120
|
+
type MetricOperator = 'metricGte' | 'metricGt' | 'metricLte' | 'metricLt' | 'metricBetween';
|
|
121
|
+
type SpecialOperator = 'topLevel';
|
|
122
|
+
interface InternalFilter {
|
|
123
|
+
dimension: Dimension | QueryParamName | Metric;
|
|
124
|
+
operator: FilterOperator | DateOperator | MetricOperator | SpecialOperator;
|
|
125
|
+
expression: string;
|
|
126
|
+
expression2?: string;
|
|
456
127
|
}
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
128
|
+
declare const FilterBrand: unique symbol;
|
|
129
|
+
interface Filter<C = object> {
|
|
130
|
+
readonly [FilterBrand]: true;
|
|
131
|
+
readonly _constraints: C;
|
|
132
|
+
readonly _filters: InternalFilter[];
|
|
133
|
+
readonly _nestedGroups?: Filter<any>[];
|
|
134
|
+
readonly _groupType?: 'and' | 'or';
|
|
461
135
|
}
|
|
462
|
-
|
|
463
|
-
keyword: string;
|
|
464
|
-
page: string | null;
|
|
136
|
+
type GSCRow<D extends Dimension[], C> = { [K in D[number]]: K extends keyof C ? C[K] : DimensionValueMap[K] } & {
|
|
465
137
|
clicks: number;
|
|
466
138
|
impressions: number;
|
|
467
139
|
ctr: number;
|
|
468
140
|
position: number;
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
* Composite score combining position, impressions, and CTR gap factors.
|
|
476
|
-
*/
|
|
477
|
-
declare function analyzeOpportunity(keywords: KeywordData[], options?: OpportunityOptions): OpportunityResult[];
|
|
478
|
-
//#endregion
|
|
479
|
-
//#region src/analysis/seasonality.d.ts
|
|
480
|
-
type SeasonalityMetric = 'clicks' | 'impressions';
|
|
481
|
-
interface SeasonalityOptions {
|
|
482
|
-
/** Metric to analyze for seasonality. Default: clicks */
|
|
483
|
-
metric?: SeasonalityMetric;
|
|
484
|
-
}
|
|
485
|
-
interface MonthlyData {
|
|
486
|
-
month: string;
|
|
487
|
-
value: number;
|
|
488
|
-
vsAverage: number;
|
|
489
|
-
isPeak: boolean;
|
|
490
|
-
isTrough: boolean;
|
|
491
|
-
}
|
|
492
|
-
interface SeasonalityResult {
|
|
493
|
-
hasSeasonality: boolean;
|
|
494
|
-
/** Coefficient of variation: std dev / mean. Higher = more seasonal. */
|
|
495
|
-
strength: number;
|
|
496
|
-
peakMonths: string[];
|
|
497
|
-
troughMonths: string[];
|
|
498
|
-
monthlyBreakdown: MonthlyData[];
|
|
499
|
-
insufficientData: boolean;
|
|
500
|
-
}
|
|
501
|
-
/**
|
|
502
|
-
* Detects seasonality patterns by analyzing monthly traffic variation.
|
|
503
|
-
* Identifies peaks (>1.5x average) and troughs (<0.5x average).
|
|
504
|
-
*
|
|
505
|
-
* @param dates Array of date metrics (each row is one day)
|
|
506
|
-
* @param options Analysis options
|
|
507
|
-
*/
|
|
508
|
-
declare function analyzeSeasonality(dates: DateMetrics[], options?: SeasonalityOptions): SeasonalityResult;
|
|
509
|
-
//#endregion
|
|
510
|
-
//#region src/analysis/striking-distance.d.ts
|
|
511
|
-
type StrikingDistanceSortMetric = 'clicks' | 'impressions' | 'ctr' | 'position' | 'potentialClicks';
|
|
512
|
-
interface StrikingDistanceOptions {
|
|
513
|
-
/** Minimum position (inclusive). Default: 4 */
|
|
514
|
-
minPosition?: number;
|
|
515
|
-
/** Maximum position (inclusive). Default: 20 */
|
|
516
|
-
maxPosition?: number;
|
|
517
|
-
/** Minimum impressions. Default: 100 */
|
|
518
|
-
minImpressions?: number;
|
|
519
|
-
/** Maximum CTR (queries with low CTR have more potential). Default: 0.05 (5%) */
|
|
520
|
-
maxCtr?: number;
|
|
521
|
-
/** Sort metric. Default: potentialClicks */
|
|
522
|
-
sortBy?: StrikingDistanceSortMetric;
|
|
523
|
-
/** Sort order. Default: desc */
|
|
524
|
-
sortOrder?: SortOrder;
|
|
141
|
+
};
|
|
142
|
+
type Metric = 'clicks' | 'impressions' | 'ctr' | 'position';
|
|
143
|
+
declare const MetricColumnBrand: unique symbol;
|
|
144
|
+
interface MetricColumn<M extends Metric> {
|
|
145
|
+
readonly [MetricColumnBrand]: M;
|
|
146
|
+
readonly metric: M;
|
|
525
147
|
}
|
|
526
|
-
interface
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
148
|
+
interface BuilderState {
|
|
149
|
+
dimensions: Dimension[];
|
|
150
|
+
metrics?: Metric[];
|
|
151
|
+
filter?: Filter<any>;
|
|
152
|
+
orderBy?: {
|
|
153
|
+
column: Metric | 'date';
|
|
154
|
+
dir: 'asc' | 'desc';
|
|
155
|
+
};
|
|
156
|
+
rowLimit?: number;
|
|
157
|
+
startRow?: number;
|
|
535
158
|
}
|
|
536
|
-
/**
|
|
537
|
-
* Finds striking distance keywords - high impressions, low CTR, position 4-20.
|
|
538
|
-
* These are "quick wins" that could gain significant traffic with small ranking improvements.
|
|
539
|
-
*/
|
|
540
|
-
declare function analyzeStrikingDistance(keywords: KeywordData[], options?: StrikingDistanceOptions): StrikingDistanceResult[];
|
|
541
159
|
//#endregion
|
|
542
|
-
//#region src/
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
position: number;
|
|
160
|
+
//#region src/query/builder.d.ts
|
|
161
|
+
type SelectableColumn = Column<Dimension> | MetricColumn<Metric>;
|
|
162
|
+
type OrderableColumn = MetricColumn<Metric> | Column<'date'>;
|
|
163
|
+
type ExtractDimensions<T extends SelectableColumn[]> = { [K in keyof T]: T[K] extends Column<infer D> ? D : never }[number] extends infer U ? Exclude<U, never>[] : never;
|
|
164
|
+
interface GSCQueryBuilder<D extends Dimension[] = [], C = object> {
|
|
165
|
+
select: {
|
|
166
|
+
<T extends Dimension[]>(...dims: T): GSCQueryBuilder<T, C>;
|
|
167
|
+
<T extends SelectableColumn[]>(...cols: T): GSCQueryBuilder<ExtractDimensions<T> & Dimension[], C>;
|
|
168
|
+
};
|
|
169
|
+
where: <F extends Filter<any>>(filter: F) => GSCQueryBuilder<D, C & F['_constraints']>;
|
|
170
|
+
orderBy: (col: OrderableColumn, dir: 'asc' | 'desc') => GSCQueryBuilder<D, C>;
|
|
171
|
+
limit: (n: number) => GSCQueryBuilder<D, C>;
|
|
172
|
+
offset: (n: number) => GSCQueryBuilder<D, C>;
|
|
173
|
+
toBody: () => SearchAnalyticsQuery;
|
|
174
|
+
getState: () => BuilderState;
|
|
558
175
|
}
|
|
559
|
-
/**
|
|
560
|
-
* Identifies potential "Zero-Click" queries.
|
|
561
|
-
* These are high-volume queries where you rank well but get few clicks,
|
|
562
|
-
* often due to SERP features (Answer Boxes, Knowledge Panels, AI Overviews).
|
|
563
|
-
*
|
|
564
|
-
* @param rows Query+page data rows
|
|
565
|
-
* @param options Filtering options
|
|
566
|
-
*/
|
|
567
|
-
declare function analyzeZeroClick(rows: QueryPageRow[], options?: ZeroClickOptions): ZeroClickResult[];
|
|
568
176
|
//#endregion
|
|
569
177
|
//#region src/core/client.d.ts
|
|
570
178
|
/**
|
|
@@ -592,29 +200,26 @@ type Auth = string | {
|
|
|
592
200
|
} | AuthClient | AuthOptions;
|
|
593
201
|
declare function createFetch(auth: Auth, options?: FetchOptions): $Fetch;
|
|
594
202
|
interface GoogleSearchConsoleClient {
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
203
|
+
/** Query search analytics with builder, returns async generator yielding typed row batches */
|
|
204
|
+
query: <D extends Dimension[], C>(siteUrl: string, builder: GSCQueryBuilder<D, C>) => AsyncGenerator<GSCRow<D, C>[]>;
|
|
205
|
+
/** List all sites */
|
|
206
|
+
sites: () => Promise<ApiSite[]>;
|
|
207
|
+
/** Inspect a URL */
|
|
208
|
+
inspect: (siteUrl: string, url: string) => Promise<InspectUrlIndexResponse>;
|
|
209
|
+
/** Sitemap operations */
|
|
600
210
|
sitemaps: {
|
|
601
|
-
list: (siteUrl: string) => Promise<
|
|
602
|
-
sitemap?: ApiSitemap[];
|
|
603
|
-
}>;
|
|
211
|
+
list: (siteUrl: string) => Promise<ApiSitemap[]>;
|
|
604
212
|
get: (siteUrl: string, feedpath: string) => Promise<ApiSitemap>;
|
|
605
213
|
submit: (siteUrl: string, feedpath: string) => Promise<void>;
|
|
606
214
|
delete: (siteUrl: string, feedpath: string) => Promise<void>;
|
|
607
215
|
};
|
|
608
|
-
|
|
609
|
-
query: (siteUrl: string, body: SearchAnalyticsQuery) => Promise<SearchAnalyticsResponse>;
|
|
610
|
-
};
|
|
611
|
-
urlInspection: {
|
|
612
|
-
inspect: (siteUrl: string, inspectionUrl: string) => Promise<InspectUrlIndexResponse>;
|
|
613
|
-
};
|
|
216
|
+
/** Indexing API operations */
|
|
614
217
|
indexing: {
|
|
615
218
|
publish: (url: string, type: 'URL_UPDATED' | 'URL_DELETED') => Promise<PublishUrlNotificationResponse>;
|
|
616
219
|
getMetadata: (url: string) => Promise<UrlNotificationMetadata>;
|
|
617
220
|
};
|
|
221
|
+
/** @internal */
|
|
222
|
+
_rawQuery: (siteUrl: string, body: SearchAnalyticsQuery) => Promise<SearchAnalyticsResponse>;
|
|
618
223
|
}
|
|
619
224
|
interface GoogleSearchConsoleClientOptions {
|
|
620
225
|
fetchOptions?: FetchOptions;
|
|
@@ -682,287 +287,23 @@ declare function batchInspectUrls(client: GoogleSearchConsoleClient, siteUrl: st
|
|
|
682
287
|
onProgress?: (result: InspectUrlResult, index: number, total: number) => void;
|
|
683
288
|
}): Promise<InspectUrlResult[]>;
|
|
684
289
|
//#endregion
|
|
685
|
-
//#region src/api/search-analytics/analytics.d.ts
|
|
686
|
-
/**
|
|
687
|
-
* Fetches overall site analytics summary with period comparison and keyword data.
|
|
688
|
-
*/
|
|
689
|
-
declare function fetchAnalyticsWithComparison(client: GoogleSearchConsoleClient, siteUrl: string, options?: QueryOptions): Promise<ComparisonResult<AnalyticsData>>;
|
|
690
|
-
//#endregion
|
|
691
|
-
//#region src/api/search-analytics/breakdowns.d.ts
|
|
692
|
-
/**
|
|
693
|
-
* Fetches device breakdown (desktop, mobile, tablet) with period comparison.
|
|
694
|
-
*/
|
|
695
|
-
declare function fetchDevicesWithComparison(client: GoogleSearchConsoleClient, siteUrl: string, options?: QueryOptions): Promise<ComparisonResult<DeviceData>>;
|
|
696
|
-
/**
|
|
697
|
-
* Fetches device breakdown (desktop, mobile, tablet).
|
|
698
|
-
*/
|
|
699
|
-
declare function fetchDevices(client: GoogleSearchConsoleClient, siteUrl: string, options?: QueryOptions): Promise<DeviceData[]>;
|
|
700
|
-
/**
|
|
701
|
-
* Fetches top countries by traffic with period comparison and keyword counts per country.
|
|
702
|
-
*/
|
|
703
|
-
declare function fetchCountriesWithComparison(client: GoogleSearchConsoleClient, siteUrl: string, options?: QueryOptions): Promise<ComparisonResult<CountryData>>;
|
|
704
|
-
/**
|
|
705
|
-
* Fetches top countries by traffic.
|
|
706
|
-
*/
|
|
707
|
-
declare function fetchCountries(client: GoogleSearchConsoleClient, siteUrl: string, options?: QueryOptions): Promise<CountryData[]>;
|
|
708
|
-
/**
|
|
709
|
-
* Fetches search appearance breakdown (AMP, rich results, etc.) with period comparison.
|
|
710
|
-
*/
|
|
711
|
-
declare function fetchSearchAppearanceWithComparison(client: GoogleSearchConsoleClient, siteUrl: string, options?: QueryOptions): Promise<ComparisonResult<SearchAppearanceData>>;
|
|
712
|
-
/**
|
|
713
|
-
* Fetches search appearance breakdown (AMP, rich results, etc.).
|
|
714
|
-
*/
|
|
715
|
-
declare function fetchSearchAppearance(client: GoogleSearchConsoleClient, siteUrl: string, options?: QueryOptions): Promise<SearchAppearanceData[]>;
|
|
716
|
-
//#endregion
|
|
717
|
-
//#region src/api/search-analytics/dates.d.ts
|
|
718
|
-
interface DatesComparisonResult {
|
|
719
|
-
current: DateData[];
|
|
720
|
-
previous: DateData[];
|
|
721
|
-
metadata: {
|
|
722
|
-
currentCount: number;
|
|
723
|
-
previousCount: number;
|
|
724
|
-
totals: {
|
|
725
|
-
current: {
|
|
726
|
-
clicks: number;
|
|
727
|
-
impressions: number;
|
|
728
|
-
ctr: number;
|
|
729
|
-
position: number;
|
|
730
|
-
};
|
|
731
|
-
previous: {
|
|
732
|
-
clicks: number;
|
|
733
|
-
impressions: number;
|
|
734
|
-
ctr: number;
|
|
735
|
-
position: number;
|
|
736
|
-
};
|
|
737
|
-
clicksPercent: number;
|
|
738
|
-
impressionsPercent: number;
|
|
739
|
-
ctrPercent: number;
|
|
740
|
-
positionPercent: number;
|
|
741
|
-
};
|
|
742
|
-
};
|
|
743
|
-
}
|
|
744
|
-
/**
|
|
745
|
-
* Fetches daily search analytics data with period-over-period comparison.
|
|
746
|
-
*/
|
|
747
|
-
declare function fetchDatesWithComparison(client: GoogleSearchConsoleClient, siteUrl: string, options?: QueryOptions): Promise<DatesComparisonResult>;
|
|
748
|
-
interface YoYComparisonOptions {
|
|
749
|
-
/** Current period to compare. If not provided, uses last 28 days */
|
|
750
|
-
period?: Period;
|
|
751
|
-
}
|
|
752
|
-
interface YoYMetrics {
|
|
753
|
-
clicks: number;
|
|
754
|
-
impressions: number;
|
|
755
|
-
ctr: number;
|
|
756
|
-
position: number;
|
|
757
|
-
}
|
|
758
|
-
interface YoYComparisonResult {
|
|
759
|
-
current: YoYMetrics;
|
|
760
|
-
previous: YoYMetrics;
|
|
761
|
-
change: {
|
|
762
|
-
clicks: number;
|
|
763
|
-
clicksPercent: number;
|
|
764
|
-
impressions: number;
|
|
765
|
-
impressionsPercent: number;
|
|
766
|
-
ctr: number;
|
|
767
|
-
ctrPercent: number;
|
|
768
|
-
position: number;
|
|
769
|
-
positionPercent: number;
|
|
770
|
-
};
|
|
771
|
-
periodDays: number;
|
|
772
|
-
withinLimit: boolean;
|
|
773
|
-
}
|
|
774
|
-
/**
|
|
775
|
-
* Fetches year-over-year comparison for site metrics.
|
|
776
|
-
* GSC has ~16 months history, so works for periods up to ~4 months.
|
|
777
|
-
*/
|
|
778
|
-
declare function fetchYoYComparison(client: GoogleSearchConsoleClient, siteUrl: string, options?: YoYComparisonOptions): Promise<YoYComparisonResult>;
|
|
779
|
-
/**
|
|
780
|
-
* Fetches daily search analytics data for a site.
|
|
781
|
-
*/
|
|
782
|
-
declare function fetchDates(client: GoogleSearchConsoleClient, siteUrl: string, options?: QueryOptions): Promise<DateData[]>;
|
|
783
|
-
//#endregion
|
|
784
|
-
//#region src/api/search-analytics/keywords.d.ts
|
|
785
|
-
/**
|
|
786
|
-
* Fetches keyword/query performance data with period comparison and associated pages.
|
|
787
|
-
*/
|
|
788
|
-
declare function fetchKeywordsWithComparison(client: GoogleSearchConsoleClient, siteUrl: string, options?: QueryOptions): Promise<ComparisonResult<KeywordData>>;
|
|
789
|
-
/**
|
|
790
|
-
* Fetches all keywords with their performance data using recursive pagination.
|
|
791
|
-
*/
|
|
792
|
-
declare function fetchKeywords(client: GoogleSearchConsoleClient, siteUrl: string, options?: QueryOptions): Promise<KeywordData[]>;
|
|
793
|
-
interface FetchKeywordOptions extends QueryOptions {
|
|
794
|
-
/** Maximum pages to return. Default: 5 */
|
|
795
|
-
rowLimit?: number;
|
|
796
|
-
}
|
|
797
|
-
/**
|
|
798
|
-
* Fetches detailed data for a specific keyword including daily trends and top pages.
|
|
799
|
-
*/
|
|
800
|
-
declare function fetchKeyword(client: GoogleSearchConsoleClient, siteUrl: string, keyword: string, options?: FetchKeywordOptions): Promise<FetchKeywordResult>;
|
|
801
|
-
//#endregion
|
|
802
|
-
//#region src/api/search-analytics/pages.d.ts
|
|
803
|
-
interface Page {
|
|
804
|
-
page: string;
|
|
805
|
-
}
|
|
806
|
-
/**
|
|
807
|
-
* Fetches all pages with their performance data using recursive pagination.
|
|
808
|
-
*/
|
|
809
|
-
declare function fetchPages(client: GoogleSearchConsoleClient, siteUrl: string, options?: QueryOptions): Promise<Page[]>;
|
|
810
|
-
/**
|
|
811
|
-
* Fetches page performance data with period comparison, including top keyword per page.
|
|
812
|
-
*/
|
|
813
|
-
declare function fetchPagesWithComparison(client: GoogleSearchConsoleClient, siteUrl: string, options?: QueryOptions): Promise<ComparisonResult<PageData>>;
|
|
814
|
-
interface FetchPageOptions extends QueryOptions {
|
|
815
|
-
/** Maximum keywords to return. Default: 5 */
|
|
816
|
-
rowLimit?: number;
|
|
817
|
-
}
|
|
818
|
-
/**
|
|
819
|
-
* Fetches detailed data for a specific page including daily trends and top keywords.
|
|
820
|
-
*/
|
|
821
|
-
declare function fetchPage(client: GoogleSearchConsoleClient, siteUrl: string, url: string, options?: FetchPageOptions): Promise<FetchPageResult>;
|
|
822
|
-
//#endregion
|
|
823
|
-
//#region src/api/search-analytics/query.d.ts
|
|
824
|
-
/**
|
|
825
|
-
* Recursively queries GSC search analytics, automatically handling pagination for large datasets.
|
|
826
|
-
*/
|
|
827
|
-
declare function queryRecursive(client: GoogleSearchConsoleClient, siteUrl: string, query: SearchAnalyticsQuery, options?: {
|
|
828
|
-
onProgress?: (rows: number) => void;
|
|
829
|
-
}): Promise<{
|
|
830
|
-
rows: DataRow[];
|
|
831
|
-
pages: number;
|
|
832
|
-
}>;
|
|
833
|
-
/**
|
|
834
|
-
* Creates a GSC search analytics query request body with standard defaults.
|
|
835
|
-
*/
|
|
836
|
-
declare function createQueryBody(options?: QueryOptions): SearchAnalyticsQuery;
|
|
837
|
-
/**
|
|
838
|
-
* Helper to add search appearance dimension filter.
|
|
839
|
-
* Use with spread: createQueryBody({ ...withSearchAppearance('AMP'), period })
|
|
840
|
-
*/
|
|
841
|
-
declare function withSearchAppearance(appearance: string): Pick<QueryOptions, 'filters'>;
|
|
842
|
-
/**
|
|
843
|
-
* Helper to set data type (web, image, video, news, discover, googleNews).
|
|
844
|
-
* Use with spread: createQueryBody({ ...withDataType('image'), period })
|
|
845
|
-
*/
|
|
846
|
-
declare function withDataType(type: DataType): Pick<QueryOptions, 'type'>;
|
|
847
|
-
/**
|
|
848
|
-
* Helper to include fresh/unfinalized data (last 3 days).
|
|
849
|
-
* Use with spread: createQueryBody({ ...withFreshData(), period })
|
|
850
|
-
*/
|
|
851
|
-
declare function withFreshData(): Pick<QueryOptions, 'dataState'>;
|
|
852
|
-
/**
|
|
853
|
-
* Helper to use only finalized data (excludes last 3 days).
|
|
854
|
-
* Use with spread: createQueryBody({ ...withFinalData(), period })
|
|
855
|
-
*/
|
|
856
|
-
declare function withFinalData(): Pick<QueryOptions, 'dataState'>;
|
|
857
|
-
/**
|
|
858
|
-
* Helper to use byProperty aggregation (domain-level rollup).
|
|
859
|
-
* Use for sc-domain: properties to get true totals.
|
|
860
|
-
* Use with spread: createQueryBody({ ...withPropertyAggregation(), period })
|
|
861
|
-
*/
|
|
862
|
-
declare function withPropertyAggregation(): Pick<QueryOptions, 'aggregationType'>;
|
|
863
|
-
//#endregion
|
|
864
|
-
//#region src/api/search-analytics/stream.d.ts
|
|
865
|
-
/**
|
|
866
|
-
* Supported GSC dimensions for streaming queries.
|
|
867
|
-
* Maps to GSC API dimension names.
|
|
868
|
-
*/
|
|
869
|
-
type DimensionKey = 'query' | 'page' | 'date' | 'device' | 'country';
|
|
870
|
-
/**
|
|
871
|
-
* Maps each dimension to its output field name.
|
|
872
|
-
* Note: 'query' maps to 'keyword' to match existing API conventions.
|
|
873
|
-
*/
|
|
874
|
-
interface DimensionFields {
|
|
875
|
-
query: {
|
|
876
|
-
keyword: string;
|
|
877
|
-
};
|
|
878
|
-
page: {
|
|
879
|
-
page: string;
|
|
880
|
-
};
|
|
881
|
-
date: {
|
|
882
|
-
date: string;
|
|
883
|
-
};
|
|
884
|
-
device: {
|
|
885
|
-
device: string;
|
|
886
|
-
};
|
|
887
|
-
country: {
|
|
888
|
-
country: string;
|
|
889
|
-
};
|
|
890
|
-
}
|
|
891
|
-
/**
|
|
892
|
-
* Recursively extracts and merges fields for each dimension in a tuple.
|
|
893
|
-
* Used for type inference from dimensions array.
|
|
894
|
-
*/
|
|
895
|
-
type ExtractFields<D extends readonly DimensionKey[]> = D extends readonly [infer First extends DimensionKey, ...infer Rest extends DimensionKey[]] ? DimensionFields[First] & ExtractFields<Rest> : object;
|
|
896
|
-
/**
|
|
897
|
-
* Output row type for streaming queries.
|
|
898
|
-
* Combines GSC metrics (clicks, impressions, ctr, position) with
|
|
899
|
-
* typed dimension fields based on the dimensions array.
|
|
900
|
-
*
|
|
901
|
-
* @example
|
|
902
|
-
* // For dimensions: ['query', 'page']
|
|
903
|
-
* // StreamRow = { keyword: string, page: string, clicks?: number, impressions?: number, ctr?: number, position?: number }
|
|
904
|
-
*/
|
|
905
|
-
type StreamRow<D extends readonly DimensionKey[]> = Omit<DataRow, 'keys'> & ExtractFields<D>;
|
|
906
|
-
/**
|
|
907
|
-
* Async generator for memory-efficient pagination of GSC search analytics.
|
|
908
|
-
* Yields batches of typed rows as they're fetched, avoiding accumulation in memory.
|
|
909
|
-
*
|
|
910
|
-
* **Design:** Single generic function with type inference replaces separate
|
|
911
|
-
* `fetchPagesStream`, `fetchKeywordsStream` wrappers. Output type is inferred
|
|
912
|
-
* from the dimensions tuple:
|
|
913
|
-
* - `['query']` → `{ keyword: string, clicks, impressions, ctr, position }`
|
|
914
|
-
* - `['page']` → `{ page: string, clicks, impressions, ctr, position }`
|
|
915
|
-
* - `['query', 'page']` → `{ keyword: string, page: string, ... }`
|
|
916
|
-
*
|
|
917
|
-
* Each yield contains up to 25,000 rows (one API page). Use `collectStream()`
|
|
918
|
-
* to gather all batches if full array is needed.
|
|
919
|
-
*
|
|
920
|
-
* @param client - GSC client instance
|
|
921
|
-
* @param siteUrl - Site URL (e.g., 'https://example.com/' or 'sc-domain:example.com')
|
|
922
|
-
* @param query - Query with dimensions array (requires `as const` for type inference)
|
|
923
|
-
*
|
|
924
|
-
* @example
|
|
925
|
-
* ```ts
|
|
926
|
-
* // Stream keyword+page combinations
|
|
927
|
-
* for await (const batch of queryRecursiveStream(client, url, {
|
|
928
|
-
* dimensions: ['query', 'page'] as const,
|
|
929
|
-
* startDate: '2024-01-01',
|
|
930
|
-
* endDate: '2024-01-31',
|
|
931
|
-
* })) {
|
|
932
|
-
* // batch: { keyword: string, page: string, clicks, impressions, ctr, position }[]
|
|
933
|
-
* await db.insert(batch)
|
|
934
|
-
* }
|
|
935
|
-
*
|
|
936
|
-
* // Or collect all at once
|
|
937
|
-
* const allRows = await collectStream(queryRecursiveStream(client, url, {
|
|
938
|
-
* dimensions: ['page'] as const,
|
|
939
|
-
* startDate: '2024-01-01',
|
|
940
|
-
* endDate: '2024-01-31',
|
|
941
|
-
* }))
|
|
942
|
-
* ```
|
|
943
|
-
*
|
|
944
|
-
* @remarks
|
|
945
|
-
* - Requires `as const` on dimensions array for proper type inference
|
|
946
|
-
* - Use for large datasets (>25k rows) where memory is a concern
|
|
947
|
-
* - Non-paginating queries (devices, countries) don't benefit from streaming
|
|
948
|
-
*/
|
|
949
|
-
declare function queryRecursiveStream<const D extends readonly DimensionKey[]>(client: GoogleSearchConsoleClient, siteUrl: string, query: Omit<SearchAnalyticsQuery, 'dimensions'> & {
|
|
950
|
-
dimensions: D;
|
|
951
|
-
}): AsyncGenerator<StreamRow<D>[], void, undefined>;
|
|
952
|
-
/** Collect all batches into single array (for testing / simple cases) */
|
|
953
|
-
declare function collectStream<T>(gen: AsyncGenerator<T[], void, undefined>): Promise<T[]>;
|
|
954
|
-
//#endregion
|
|
955
290
|
//#region src/api/sites.d.ts
|
|
956
291
|
/**
|
|
957
292
|
* Fetches all sites the authenticated user has access to in Google Search Console.
|
|
958
293
|
*/
|
|
959
294
|
declare function fetchSites(client: GoogleSearchConsoleClient): Promise<ApiSite[]>;
|
|
960
295
|
/**
|
|
961
|
-
* Fetches sitemaps
|
|
296
|
+
* Fetches all verified sites with their sitemaps from Google Search Console.
|
|
297
|
+
*/
|
|
298
|
+
declare function fetchSitesWithSitemaps(client: GoogleSearchConsoleClient): Promise<(Site & {
|
|
299
|
+
sitemaps: RequiredNonNullable<ApiSitemap>[];
|
|
300
|
+
})[]>;
|
|
301
|
+
/**
|
|
302
|
+
* Fetches all sitemaps for a site.
|
|
962
303
|
*/
|
|
963
304
|
declare function fetchSitemaps(client: GoogleSearchConsoleClient, siteUrl: string): Promise<ApiSitemap[]>;
|
|
964
305
|
/**
|
|
965
|
-
*
|
|
306
|
+
* Fetches a specific sitemap.
|
|
966
307
|
*/
|
|
967
308
|
declare function fetchSitemap(client: GoogleSearchConsoleClient, siteUrl: string, feedpath: string): Promise<ApiSitemap>;
|
|
968
309
|
/**
|
|
@@ -973,12 +314,29 @@ declare function submitSitemap(client: GoogleSearchConsoleClient, siteUrl: strin
|
|
|
973
314
|
* Deletes a sitemap from Google Search Console.
|
|
974
315
|
*/
|
|
975
316
|
declare function deleteSitemap(client: GoogleSearchConsoleClient, siteUrl: string, feedpath: string): Promise<void>;
|
|
317
|
+
//#endregion
|
|
318
|
+
//#region src/core/api-client.d.ts
|
|
319
|
+
interface GscdumpApiOptions {
|
|
320
|
+
/** API key (gsd_user_xxx or gsd_prod_xxx) */
|
|
321
|
+
apiKey: string;
|
|
322
|
+
/** Base URL (defaults to https://gscdump.com) */
|
|
323
|
+
baseUrl?: string;
|
|
324
|
+
}
|
|
976
325
|
/**
|
|
977
|
-
*
|
|
326
|
+
* Create a client that queries GSC data through gscdump.com API
|
|
327
|
+
* instead of directly to Google. Useful when you don't have OAuth credentials.
|
|
328
|
+
*
|
|
329
|
+
* @example
|
|
330
|
+
* ```ts
|
|
331
|
+
* const client = gscdumpApi({ apiKey: 'gsd_user_xxx' })
|
|
332
|
+
*
|
|
333
|
+
* // Same query builder usage as direct client
|
|
334
|
+
* for await (const rows of client.query(siteId, gsc.select('page', 'query').where(...))) {
|
|
335
|
+
* console.log(rows)
|
|
336
|
+
* }
|
|
337
|
+
* ```
|
|
978
338
|
*/
|
|
979
|
-
declare function
|
|
980
|
-
sitemaps: RequiredNonNullable<ApiSitemap>[];
|
|
981
|
-
})[]>;
|
|
339
|
+
declare function gscdumpApi(options: GscdumpApiOptions): GoogleSearchConsoleClient;
|
|
982
340
|
//#endregion
|
|
983
341
|
//#region src/core/errors.d.ts
|
|
984
342
|
/**
|
|
@@ -1036,144 +394,4 @@ declare function analyzeError(error: unknown): ErrorInfo;
|
|
|
1036
394
|
*/
|
|
1037
395
|
declare function formatErrorForCli(error: unknown): string;
|
|
1038
396
|
//#endregion
|
|
1039
|
-
|
|
1040
|
-
declare const _default: {
|
|
1041
|
-
name: string;
|
|
1042
|
-
'alpha-2': string;
|
|
1043
|
-
'alpha-3': string;
|
|
1044
|
-
'country-code': string;
|
|
1045
|
-
}[];
|
|
1046
|
-
//#endregion
|
|
1047
|
-
//#region src/query/constants.d.ts
|
|
1048
|
-
declare const Device: {
|
|
1049
|
-
readonly MOBILE: "MOBILE";
|
|
1050
|
-
readonly DESKTOP: "DESKTOP";
|
|
1051
|
-
readonly TABLET: "TABLET";
|
|
1052
|
-
};
|
|
1053
|
-
type Device = typeof Device[keyof typeof Device];
|
|
1054
|
-
declare const Country: { [K in (typeof _default)[number]["alpha-3"]]: Lowercase<K> };
|
|
1055
|
-
type Country = typeof Country[keyof typeof Country];
|
|
1056
|
-
//#endregion
|
|
1057
|
-
//#region src/query/types.d.ts
|
|
1058
|
-
interface DimensionValueMap {
|
|
1059
|
-
query: string;
|
|
1060
|
-
page: string;
|
|
1061
|
-
country: Country;
|
|
1062
|
-
device: Device;
|
|
1063
|
-
searchAppearance: string;
|
|
1064
|
-
date: string;
|
|
1065
|
-
}
|
|
1066
|
-
type Dimension = keyof DimensionValueMap;
|
|
1067
|
-
declare const ColumnBrand: unique symbol;
|
|
1068
|
-
interface Column<D extends Dimension> {
|
|
1069
|
-
readonly [ColumnBrand]: D;
|
|
1070
|
-
readonly dimension: D;
|
|
1071
|
-
}
|
|
1072
|
-
type FilterOperator = 'equals' | 'notEquals' | 'contains' | 'notContains' | 'includingRegex' | 'excludingRegex';
|
|
1073
|
-
type DateOperator = 'gte' | 'gt' | 'lte' | 'lt' | 'between';
|
|
1074
|
-
interface InternalFilter {
|
|
1075
|
-
dimension: Dimension;
|
|
1076
|
-
operator: FilterOperator | DateOperator;
|
|
1077
|
-
expression: string;
|
|
1078
|
-
expression2?: string;
|
|
1079
|
-
}
|
|
1080
|
-
declare const FilterBrand: unique symbol;
|
|
1081
|
-
interface Filter<C = object> {
|
|
1082
|
-
readonly [FilterBrand]: true;
|
|
1083
|
-
readonly _constraints: C;
|
|
1084
|
-
readonly _filters: InternalFilter[];
|
|
1085
|
-
readonly _groupType?: 'and' | 'or';
|
|
1086
|
-
}
|
|
1087
|
-
type MergeConstraints<F extends Filter<any>[]> = UnionToIntersection<F[number]['_constraints']>;
|
|
1088
|
-
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
|
|
1089
|
-
interface GSCResult<D extends Dimension[], C> {
|
|
1090
|
-
rows: Array<GSCRow<D, C>>;
|
|
1091
|
-
}
|
|
1092
|
-
type GSCRow<D extends Dimension[], C> = { [K in D[number]]: K extends keyof C ? C[K] : DimensionValueMap[K] } & {
|
|
1093
|
-
clicks: number;
|
|
1094
|
-
impressions: number;
|
|
1095
|
-
ctr: number;
|
|
1096
|
-
position: number;
|
|
1097
|
-
};
|
|
1098
|
-
interface BuilderState {
|
|
1099
|
-
dimensions: Dimension[];
|
|
1100
|
-
filters: Filter<any>[];
|
|
1101
|
-
siteUrl?: string;
|
|
1102
|
-
rowLimit?: number;
|
|
1103
|
-
startRow?: number;
|
|
1104
|
-
}
|
|
1105
|
-
//#endregion
|
|
1106
|
-
//#region src/query/builder.d.ts
|
|
1107
|
-
interface GSCQueryBuilder<D extends Dimension[] = [], C = object> {
|
|
1108
|
-
select: <T extends Dimension[]>(...dims: T) => GSCQueryBuilder<T, C>;
|
|
1109
|
-
where: <F extends Filter<any>>(filter: F) => GSCQueryBuilder<D, C & F['_constraints']>;
|
|
1110
|
-
siteUrl: (url: string) => GSCQueryBuilder<D, C>;
|
|
1111
|
-
limit: (n: number) => GSCQueryBuilder<D, C>;
|
|
1112
|
-
offset: (n: number) => GSCQueryBuilder<D, C>;
|
|
1113
|
-
execute: (client: GoogleSearchConsoleClient) => Promise<GSCResult<D, C>>;
|
|
1114
|
-
toBody: () => SearchAnalyticsQuery;
|
|
1115
|
-
/** Expose internal state for analysis functions to merge with */
|
|
1116
|
-
getState: () => BuilderState;
|
|
1117
|
-
}
|
|
1118
|
-
declare const gsc: GSCQueryBuilder<[], object>;
|
|
1119
|
-
//#endregion
|
|
1120
|
-
//#region src/query/columns.d.ts
|
|
1121
|
-
declare const page: Column<"page">;
|
|
1122
|
-
declare const query: Column<"query">;
|
|
1123
|
-
declare const device: Column<"device">;
|
|
1124
|
-
declare const country: Column<"country">;
|
|
1125
|
-
declare const searchAppearance: Column<"searchAppearance">;
|
|
1126
|
-
declare const date: Column<"date">;
|
|
1127
|
-
//#endregion
|
|
1128
|
-
//#region src/query/operators.d.ts
|
|
1129
|
-
declare function eq<D extends Dimension, V extends DimensionValueMap[D]>(column: Column<D>, value: V): Filter<Record<D, V>>;
|
|
1130
|
-
declare function ne<D extends Dimension>(column: Column<D>, value: DimensionValueMap[D]): Filter<object>;
|
|
1131
|
-
declare function inArray<D extends Dimension, V extends DimensionValueMap[D]>(column: Column<D>, values: readonly V[]): Filter<Record<D, V>>;
|
|
1132
|
-
declare function contains<D extends Dimension>(column: Column<D>, pattern: string): Filter<object>;
|
|
1133
|
-
declare function like<D extends Dimension>(column: Column<D>, pattern: string): Filter<object>;
|
|
1134
|
-
declare function regex<D extends Dimension>(column: Column<D>, pattern: RegExp | string): Filter<object>;
|
|
1135
|
-
declare function notRegex<D extends Dimension>(column: Column<D>, pattern: RegExp | string): Filter<object>;
|
|
1136
|
-
declare function and<F extends Filter<any>[]>(...filters: F): Filter<MergeConstraints<F>>;
|
|
1137
|
-
declare function or<F extends Filter<any>[]>(...filters: F): Filter<object>;
|
|
1138
|
-
declare function not<F extends Filter<any>>(filter: F): Filter<object>;
|
|
1139
|
-
declare function gte<D extends Dimension>(column: Column<D>, value: DimensionValueMap[D]): Filter<object>;
|
|
1140
|
-
declare function gt<D extends Dimension>(column: Column<D>, value: DimensionValueMap[D]): Filter<object>;
|
|
1141
|
-
declare function lte<D extends Dimension>(column: Column<D>, value: DimensionValueMap[D]): Filter<object>;
|
|
1142
|
-
declare function lt<D extends Dimension>(column: Column<D>, value: DimensionValueMap[D]): Filter<object>;
|
|
1143
|
-
declare function between<D extends Dimension>(column: Column<D>, start: DimensionValueMap[D], end: DimensionValueMap[D]): Filter<object>;
|
|
1144
|
-
//#endregion
|
|
1145
|
-
//#region src/query/resolver.d.ts
|
|
1146
|
-
/**
|
|
1147
|
-
* Extract date range from filters. Used by analysis functions to get the period.
|
|
1148
|
-
*/
|
|
1149
|
-
declare function extractDateRange(filters: Filter<any>[]): {
|
|
1150
|
-
startDate?: string;
|
|
1151
|
-
endDate?: string;
|
|
1152
|
-
};
|
|
1153
|
-
//#endregion
|
|
1154
|
-
//#region src/query/index.d.ts
|
|
1155
|
-
declare function today(): string;
|
|
1156
|
-
declare function daysAgo(n: number): string;
|
|
1157
|
-
//#endregion
|
|
1158
|
-
//#region src/utils/dayjs.d.ts
|
|
1159
|
-
declare function dayjs(date?: _dayjs.ConfigType): Dayjs;
|
|
1160
|
-
declare function currentPstDate(): string;
|
|
1161
|
-
declare function dayjsPst(): Dayjs;
|
|
1162
|
-
//#endregion
|
|
1163
|
-
//#region src/utils/format.d.ts
|
|
1164
|
-
/**
|
|
1165
|
-
* Formats a date for GSC API queries (YYYY-MM-DD format).
|
|
1166
|
-
* @param d - Date object, date string, or null/undefined
|
|
1167
|
-
* @returns Formatted date string or null/undefined if input is falsy
|
|
1168
|
-
*/
|
|
1169
|
-
declare function formatDateGsc(d?: Date | string | null): string | null | undefined;
|
|
1170
|
-
/**
|
|
1171
|
-
* Calculates the percentage difference between two values.
|
|
1172
|
-
* Returns 0 if either value is null, undefined, or 0 (no meaningful comparison).
|
|
1173
|
-
* @param a - Current value
|
|
1174
|
-
* @param b - Previous/comparison value
|
|
1175
|
-
* @returns Percentage difference (positive = increase, negative = decrease), or 0 if either value is falsy
|
|
1176
|
-
*/
|
|
1177
|
-
declare function percentDifference(a?: number | null, b?: number | null): number;
|
|
1178
|
-
//#endregion
|
|
1179
|
-
export { AggregationType, AnalyticsData, ApiSite, ApiSitemap, ApiSitemapContent, Auth, AuthClient, AuthOptions, BaseMetrics, BrandSegmentationOptions, BrandSegmentationResult, BrandSummary, type BuilderState, CannibalizationOptions, CannibalizationPage, CannibalizationResult, CannibalizationSortMetric, ClusterType, ClusteringOptions, ClusteringResult, type Column, ComparisonResult, ConcentrationInput, ConcentrationItem, ConcentrationOptions, ConcentrationResult, ConcentrationRiskLevel, Country, type Country as CountryType, CountryData, DataRow, DataState, DataType, DateData, DateMetrics, DateRow, DatesComparisonResult, DecayInput, DecayOptions, DecayResult, DecaySortMetric, Device, type Device as DeviceType, DeviceData, type Dimension, DimensionFilter, DimensionFilterGroup, DimensionKey, type DimensionValueMap, ErrorInfo, FetchKeywordOptions, FetchKeywordResult, FetchPageOptions, FetchPageResult, type Filter, type GSCQueryBuilder, type GSCResult, type GSCRow, GSC_QUOTAS, GoogleSearchConsoleClient, GoogleSearchConsoleClientOptions, IndexStatusResult, IndexingMetadata, IndexingNotificationType, IndexingResult, InspectUrlIndexResponse, InspectUrlResult, KeywordCluster, KeywordData, KeywordRow, MobileUsabilityResult, MonthlyData, MoverData, MoversInput, MoversOptions, MoversResult, MoversSortMetric, OpportunityFactors, OpportunityOptions, OpportunityResult, OpportunitySortMetric, OpportunityWeights, Page, PageData, PageRow, Period, PublishUrlNotificationResponse, QueryOptions, QueryPageRow, QueryResultRow, RequiredNonNullable, ResolvedAnalyticsRange, RichResultsResult, SearchAnalyticsQuery, SearchAnalyticsResponse, SearchAppearanceData, SeasonalityMetric, SeasonalityOptions, SeasonalityResult, Site, SiteAnalytics, SortOrder, StreamRow, StrikingDistanceOptions, StrikingDistanceResult, StrikingDistanceSortMetric, UrlInspectionResult, UrlNotificationMetadata, YoYComparisonOptions, YoYComparisonResult, YoYMetrics, ZeroClickOptions, ZeroClickResult, analyzeBrandSegmentation, analyzeCannibalization, analyzeClustering, analyzeConcentration, analyzeDecay, analyzeError, analyzeKeywordConcentration, analyzeMovers, analyzeOpportunity, analyzePageConcentration, analyzeSeasonality, analyzeStrikingDistance, analyzeZeroClick, and, batchInspectUrls, batchRequestIndexing, between, collectStream, contains, _default as countries, country, createAuth, createFetch, createQueryBody, createSorter, currentPstDate, date, dayjs, dayjsPst, daysAgo, deleteSitemap, device, eq, extractDateRange, fetchAnalyticsWithComparison, fetchCountries, fetchCountriesWithComparison, fetchDates, fetchDatesWithComparison, fetchDevices, fetchDevicesWithComparison, fetchKeyword, fetchKeywords, fetchKeywordsWithComparison, fetchPage, fetchPages, fetchPagesWithComparison, fetchSearchAppearance, fetchSearchAppearanceWithComparison, fetchSitemap, fetchSitemaps, fetchSites, fetchSitesWithSitemaps, fetchYoYComparison, formatDateGsc, formatErrorForCli, getErrorCode, getErrorMessage, getIndexingMetadata, getRetryAfter, googleSearchConsole, gsc, gt, gte, inArray, inspectUrl, isAuthError, isQuotaError, isRateLimitError, like, lt, lte, ne, not, notRegex, num, or, page, percentDifference, query, queryRecursive, queryRecursiveStream, regex, requestIndexing, searchAppearance, submitSitemap, today, withDataType, withFinalData, withFreshData, withPropertyAggregation, withSearchAppearance };
|
|
397
|
+
export { ApiSite, ApiSitemap, ApiSitemapContent, Auth, AuthClient, AuthOptions, DataRow, DimensionFilter, DimensionFilterGroup, ErrorInfo, GSC_QUOTAS, GoogleSearchConsoleClient, GoogleSearchConsoleClientOptions, GscdumpApiOptions, IndexStatusResult, IndexingMetadata, IndexingNotificationType, IndexingResult, InspectUrlIndexResponse, InspectUrlResult, MobileUsabilityResult, Period, PublishUrlNotificationResponse, RequiredNonNullable, ResolvedAnalyticsRange, RichResultsResult, SearchAnalyticsQuery, SearchAnalyticsResponse, Site, SiteAnalytics, UrlInspectionResult, UrlNotificationMetadata, analyzeError, batchInspectUrls, batchRequestIndexing, createAuth, createFetch, deleteSitemap, fetchSitemap, fetchSitemaps, fetchSites, fetchSitesWithSitemaps, formatErrorForCli, getErrorCode, getErrorMessage, getIndexingMetadata, getRetryAfter, googleSearchConsole, gscdumpApi, inspectUrl, isAuthError, isQuotaError, isRateLimitError, requestIndexing, submitSitemap };
|