gscdump 0.1.2 → 0.2.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 +7 -13
- package/dist/analysis/index.d.mts +487 -0
- package/dist/analysis/index.mjs +810 -0
- package/dist/index.d.mts +81 -908
- package/dist/index.mjs +199 -3450
- package/dist/query/index.d.mts +39 -52
- package/dist/query/index.mjs +121 -89
- 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,83 @@ 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;
|
|
225
101
|
page: string;
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
102
|
+
country: Country;
|
|
103
|
+
device: Device;
|
|
104
|
+
searchAppearance: string;
|
|
229
105
|
date: string;
|
|
230
106
|
}
|
|
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[];
|
|
432
|
-
}
|
|
433
|
-
/**
|
|
434
|
-
* Identifies movers and shakers - keywords with significant recent changes.
|
|
435
|
-
* Compares recent period against baseline period.
|
|
436
|
-
*
|
|
437
|
-
* @param input Current and previous keyword data
|
|
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;
|
|
448
|
-
}
|
|
449
|
-
interface OpportunityOptions {
|
|
450
|
-
/** Minimum impressions to consider. Default: 100 */
|
|
451
|
-
minImpressions?: number;
|
|
452
|
-
/** Custom weights for score factors. Default: all 1 */
|
|
453
|
-
weights?: OpportunityWeights;
|
|
454
|
-
/** Sort metric. Default: opportunityScore */
|
|
455
|
-
sortBy?: OpportunitySortMetric;
|
|
456
|
-
}
|
|
457
|
-
interface OpportunityFactors {
|
|
458
|
-
positionScore: number;
|
|
459
|
-
impressionScore: number;
|
|
460
|
-
ctrGapScore: number;
|
|
461
|
-
}
|
|
462
|
-
interface OpportunityResult {
|
|
463
|
-
keyword: string;
|
|
464
|
-
page: string | null;
|
|
465
|
-
clicks: number;
|
|
466
|
-
impressions: number;
|
|
467
|
-
ctr: number;
|
|
468
|
-
position: number;
|
|
469
|
-
opportunityScore: number;
|
|
470
|
-
potentialClicks: number;
|
|
471
|
-
factors: OpportunityFactors;
|
|
472
|
-
}
|
|
473
|
-
/**
|
|
474
|
-
* Scores keywords by optimization opportunity.
|
|
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;
|
|
107
|
+
type Dimension = keyof DimensionValueMap;
|
|
108
|
+
interface QueryParamValueMap {
|
|
109
|
+
searchType: SearchType;
|
|
491
110
|
}
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
111
|
+
type QueryParamName = keyof QueryParamValueMap;
|
|
112
|
+
type FilterOperator = 'equals' | 'notEquals' | 'contains' | 'notContains' | 'includingRegex' | 'excludingRegex';
|
|
113
|
+
type DateOperator = 'gte' | 'gt' | 'lte' | 'lt' | 'between';
|
|
114
|
+
interface InternalFilter {
|
|
115
|
+
dimension: Dimension | QueryParamName;
|
|
116
|
+
operator: FilterOperator | DateOperator;
|
|
117
|
+
expression: string;
|
|
118
|
+
expression2?: string;
|
|
500
119
|
}
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
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;
|
|
120
|
+
declare const FilterBrand: unique symbol;
|
|
121
|
+
interface Filter<C = object> {
|
|
122
|
+
readonly [FilterBrand]: true;
|
|
123
|
+
readonly _constraints: C;
|
|
124
|
+
readonly _filters: InternalFilter[];
|
|
125
|
+
readonly _nestedGroups?: Filter<any>[];
|
|
126
|
+
readonly _groupType?: 'and' | 'or';
|
|
525
127
|
}
|
|
526
|
-
|
|
527
|
-
keyword: string;
|
|
528
|
-
page: string | null;
|
|
128
|
+
type GSCRow<D extends Dimension[], C> = { [K in D[number]]: K extends keyof C ? C[K] : DimensionValueMap[K] } & {
|
|
529
129
|
clicks: number;
|
|
530
130
|
impressions: number;
|
|
531
131
|
ctr: number;
|
|
532
132
|
position: number;
|
|
533
|
-
|
|
534
|
-
|
|
133
|
+
};
|
|
134
|
+
interface BuilderState {
|
|
135
|
+
dimensions: Dimension[];
|
|
136
|
+
filter?: Filter<any>;
|
|
137
|
+
rowLimit?: number;
|
|
138
|
+
startRow?: number;
|
|
535
139
|
}
|
|
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
140
|
//#endregion
|
|
542
|
-
//#region src/
|
|
543
|
-
interface
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
}
|
|
551
|
-
interface ZeroClickResult {
|
|
552
|
-
query: string;
|
|
553
|
-
page: string;
|
|
554
|
-
clicks: number;
|
|
555
|
-
impressions: number;
|
|
556
|
-
ctr: number;
|
|
557
|
-
position: number;
|
|
141
|
+
//#region src/query/builder.d.ts
|
|
142
|
+
interface GSCQueryBuilder<D extends Dimension[] = [], C = object> {
|
|
143
|
+
select: <T extends Dimension[]>(...dims: T) => GSCQueryBuilder<T, C>;
|
|
144
|
+
where: <F extends Filter<any>>(filter: F) => GSCQueryBuilder<D, C & F['_constraints']>;
|
|
145
|
+
limit: (n: number) => GSCQueryBuilder<D, C>;
|
|
146
|
+
offset: (n: number) => GSCQueryBuilder<D, C>;
|
|
147
|
+
toBody: () => SearchAnalyticsQuery;
|
|
148
|
+
getState: () => BuilderState;
|
|
558
149
|
}
|
|
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
150
|
//#endregion
|
|
569
151
|
//#region src/core/client.d.ts
|
|
570
152
|
/**
|
|
@@ -592,29 +174,26 @@ type Auth = string | {
|
|
|
592
174
|
} | AuthClient | AuthOptions;
|
|
593
175
|
declare function createFetch(auth: Auth, options?: FetchOptions): $Fetch;
|
|
594
176
|
interface GoogleSearchConsoleClient {
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
177
|
+
/** Query search analytics with builder, returns async generator yielding typed row batches */
|
|
178
|
+
query: <D extends Dimension[], C>(siteUrl: string, builder: GSCQueryBuilder<D, C>) => AsyncGenerator<GSCRow<D, C>[]>;
|
|
179
|
+
/** List all sites */
|
|
180
|
+
sites: () => Promise<ApiSite[]>;
|
|
181
|
+
/** Inspect a URL */
|
|
182
|
+
inspect: (siteUrl: string, url: string) => Promise<InspectUrlIndexResponse>;
|
|
183
|
+
/** Sitemap operations */
|
|
600
184
|
sitemaps: {
|
|
601
|
-
list: (siteUrl: string) => Promise<
|
|
602
|
-
sitemap?: ApiSitemap[];
|
|
603
|
-
}>;
|
|
185
|
+
list: (siteUrl: string) => Promise<ApiSitemap[]>;
|
|
604
186
|
get: (siteUrl: string, feedpath: string) => Promise<ApiSitemap>;
|
|
605
187
|
submit: (siteUrl: string, feedpath: string) => Promise<void>;
|
|
606
188
|
delete: (siteUrl: string, feedpath: string) => Promise<void>;
|
|
607
189
|
};
|
|
608
|
-
|
|
609
|
-
query: (siteUrl: string, body: SearchAnalyticsQuery) => Promise<SearchAnalyticsResponse>;
|
|
610
|
-
};
|
|
611
|
-
urlInspection: {
|
|
612
|
-
inspect: (siteUrl: string, inspectionUrl: string) => Promise<InspectUrlIndexResponse>;
|
|
613
|
-
};
|
|
190
|
+
/** Indexing API operations */
|
|
614
191
|
indexing: {
|
|
615
192
|
publish: (url: string, type: 'URL_UPDATED' | 'URL_DELETED') => Promise<PublishUrlNotificationResponse>;
|
|
616
193
|
getMetadata: (url: string) => Promise<UrlNotificationMetadata>;
|
|
617
194
|
};
|
|
195
|
+
/** @internal */
|
|
196
|
+
_rawQuery: (siteUrl: string, body: SearchAnalyticsQuery) => Promise<SearchAnalyticsResponse>;
|
|
618
197
|
}
|
|
619
198
|
interface GoogleSearchConsoleClientOptions {
|
|
620
199
|
fetchOptions?: FetchOptions;
|
|
@@ -682,287 +261,23 @@ declare function batchInspectUrls(client: GoogleSearchConsoleClient, siteUrl: st
|
|
|
682
261
|
onProgress?: (result: InspectUrlResult, index: number, total: number) => void;
|
|
683
262
|
}): Promise<InspectUrlResult[]>;
|
|
684
263
|
//#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
264
|
//#region src/api/sites.d.ts
|
|
956
265
|
/**
|
|
957
266
|
* Fetches all sites the authenticated user has access to in Google Search Console.
|
|
958
267
|
*/
|
|
959
268
|
declare function fetchSites(client: GoogleSearchConsoleClient): Promise<ApiSite[]>;
|
|
960
269
|
/**
|
|
961
|
-
* Fetches sitemaps
|
|
270
|
+
* Fetches all verified sites with their sitemaps from Google Search Console.
|
|
271
|
+
*/
|
|
272
|
+
declare function fetchSitesWithSitemaps(client: GoogleSearchConsoleClient): Promise<(Site & {
|
|
273
|
+
sitemaps: RequiredNonNullable<ApiSitemap>[];
|
|
274
|
+
})[]>;
|
|
275
|
+
/**
|
|
276
|
+
* Fetches all sitemaps for a site.
|
|
962
277
|
*/
|
|
963
278
|
declare function fetchSitemaps(client: GoogleSearchConsoleClient, siteUrl: string): Promise<ApiSitemap[]>;
|
|
964
279
|
/**
|
|
965
|
-
*
|
|
280
|
+
* Fetches a specific sitemap.
|
|
966
281
|
*/
|
|
967
282
|
declare function fetchSitemap(client: GoogleSearchConsoleClient, siteUrl: string, feedpath: string): Promise<ApiSitemap>;
|
|
968
283
|
/**
|
|
@@ -973,12 +288,6 @@ declare function submitSitemap(client: GoogleSearchConsoleClient, siteUrl: strin
|
|
|
973
288
|
* Deletes a sitemap from Google Search Console.
|
|
974
289
|
*/
|
|
975
290
|
declare function deleteSitemap(client: GoogleSearchConsoleClient, siteUrl: string, feedpath: string): Promise<void>;
|
|
976
|
-
/**
|
|
977
|
-
* Fetches all verified sites with their sitemaps from Google Search Console.
|
|
978
|
-
*/
|
|
979
|
-
declare function fetchSitesWithSitemaps(client: GoogleSearchConsoleClient): Promise<(Site & {
|
|
980
|
-
sitemaps: RequiredNonNullable<ApiSitemap>[];
|
|
981
|
-
})[]>;
|
|
982
291
|
//#endregion
|
|
983
292
|
//#region src/core/errors.d.ts
|
|
984
293
|
/**
|
|
@@ -1036,140 +345,4 @@ declare function analyzeError(error: unknown): ErrorInfo;
|
|
|
1036
345
|
*/
|
|
1037
346
|
declare function formatErrorForCli(error: unknown): string;
|
|
1038
347
|
//#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/utils/dayjs.d.ts
|
|
1155
|
-
declare function dayjs(date?: _dayjs.ConfigType): Dayjs;
|
|
1156
|
-
declare function currentPstDate(): string;
|
|
1157
|
-
declare function dayjsPst(): Dayjs;
|
|
1158
|
-
//#endregion
|
|
1159
|
-
//#region src/utils/format.d.ts
|
|
1160
|
-
/**
|
|
1161
|
-
* Formats a date for GSC API queries (YYYY-MM-DD format).
|
|
1162
|
-
* @param d - Date object, date string, or null/undefined
|
|
1163
|
-
* @returns Formatted date string or null/undefined if input is falsy
|
|
1164
|
-
*/
|
|
1165
|
-
declare function formatDateGsc(d?: Date | string | null): string | null | undefined;
|
|
1166
|
-
/**
|
|
1167
|
-
* Calculates the percentage difference between two values.
|
|
1168
|
-
* Returns 0 if either value is null, undefined, or 0 (no meaningful comparison).
|
|
1169
|
-
* @param a - Current value
|
|
1170
|
-
* @param b - Previous/comparison value
|
|
1171
|
-
* @returns Percentage difference (positive = increase, negative = decrease), or 0 if either value is falsy
|
|
1172
|
-
*/
|
|
1173
|
-
declare function percentDifference(a?: number | null, b?: number | null): number;
|
|
1174
|
-
//#endregion
|
|
1175
|
-
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, 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, withDataType, withFinalData, withFreshData, withPropertyAggregation, withSearchAppearance };
|
|
348
|
+
export { ApiSite, ApiSitemap, ApiSitemapContent, Auth, AuthClient, AuthOptions, DataRow, DimensionFilter, DimensionFilterGroup, ErrorInfo, GSC_QUOTAS, GoogleSearchConsoleClient, GoogleSearchConsoleClientOptions, 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, inspectUrl, isAuthError, isQuotaError, isRateLimitError, requestIndexing, submitSitemap };
|