@gscdump/engine-gsc-api 0.17.5 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +19 -1
- package/dist/index.mjs +16 -8
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -2,6 +2,7 @@ import { GoogleSearchConsoleClient } from "gscdump";
|
|
|
2
2
|
import { BuilderState, Column, Dimension } from "gscdump/query";
|
|
3
3
|
import { SearchType } from "@gscdump/engine";
|
|
4
4
|
import { AnalysisQuerySource } from "@gscdump/engine/source";
|
|
5
|
+
import { GscDataState, GscSearchAnalyticsMetadata } from "gscdump/contracts";
|
|
5
6
|
declare function canProxyToGsc(state: BuilderState): boolean;
|
|
6
7
|
interface CreateLiveGscSourceOptions {
|
|
7
8
|
/** GSC property URL (e.g. `sc-domain:example.com` or `https://example.com/`). */
|
|
@@ -82,10 +83,21 @@ interface RunGscSyncSliceOptions {
|
|
|
82
83
|
client: GoogleSearchConsoleClient;
|
|
83
84
|
siteUrl: string;
|
|
84
85
|
/** One of the engine sync-fan tables. Drives the dimension list. */
|
|
85
|
-
table: 'pages' | 'keywords' | 'countries' | 'devices' | 'page_keywords';
|
|
86
|
+
table: 'pages' | 'keywords' | 'countries' | 'devices' | 'page_keywords' | 'hourly_pages';
|
|
86
87
|
startDate: string;
|
|
87
88
|
endDate: string;
|
|
88
89
|
domainFilter?: SyncSliceDomainFilter | null;
|
|
90
|
+
/**
|
|
91
|
+
* Override the dimension list for this slice. Defaults to
|
|
92
|
+
* `DIMENSIONS_BY_TABLE[table]`. Hosts that need bespoke groupings (e.g.
|
|
93
|
+
* hourly Discover variants) supply this directly.
|
|
94
|
+
*/
|
|
95
|
+
dimensions?: string[];
|
|
96
|
+
/**
|
|
97
|
+
* GSC `dataState` for the query. Defaults to `'all'`. Use `'hourly_all'`
|
|
98
|
+
* for hourly Discover slices.
|
|
99
|
+
*/
|
|
100
|
+
dataState?: GscDataState;
|
|
89
101
|
/**
|
|
90
102
|
* Invoked per GSC API page with the rows fetched. Return a promise; the
|
|
91
103
|
* loop awaits it before paging further. Throw inside to abort; AbortError /
|
|
@@ -116,6 +128,12 @@ interface RunGscSyncSliceResult {
|
|
|
116
128
|
totalRows: number;
|
|
117
129
|
hasMore: boolean;
|
|
118
130
|
nextStartRow: number;
|
|
131
|
+
/**
|
|
132
|
+
* Metadata from the LAST GSC API page seen during this slice run. When
|
|
133
|
+
* `dataState='hourly_all'` and grouped by `hour`, this surfaces
|
|
134
|
+
* `first_incomplete_hour` so hosts can watermark hourly progress.
|
|
135
|
+
*/
|
|
136
|
+
metadata?: GscSearchAnalyticsMetadata;
|
|
119
137
|
}
|
|
120
138
|
declare function runGscSyncSlice(opts: RunGscSyncSliceOptions): Promise<RunGscSyncSliceResult>;
|
|
121
139
|
export { type CreateLiveGscSourceOptions, type FetchTopNOptions, type GscApiQuerySourceOptions, type GscApiRow, type GscDailyRow, type GscRange, type GscTopNRow, type RunGscSyncSliceOptions, type RunGscSyncSliceResult, type SyncSliceDomainFilter, canProxyToGsc, createGscApiQuerySource, createLiveGscSource, fetchGscDaily, fetchGscTopN, runGscSyncSlice };
|
package/dist/index.mjs
CHANGED
|
@@ -168,7 +168,8 @@ const DIMENSIONS_BY_TABLE = {
|
|
|
168
168
|
"page",
|
|
169
169
|
"query",
|
|
170
170
|
"date"
|
|
171
|
-
]
|
|
171
|
+
],
|
|
172
|
+
hourly_pages: ["hour", "page"]
|
|
172
173
|
};
|
|
173
174
|
function isTimeoutLike(err) {
|
|
174
175
|
if (!(err instanceof Error)) return false;
|
|
@@ -187,22 +188,26 @@ async function runGscSyncSlice(opts) {
|
|
|
187
188
|
const cpuBudgetMs = opts.cpuBudgetMs ?? 2e4;
|
|
188
189
|
const maxPages = opts.maxPages ?? Infinity;
|
|
189
190
|
const searchType = opts.searchType ?? "web";
|
|
190
|
-
const dimensions = [...DIMENSIONS_BY_TABLE[opts.table]];
|
|
191
|
+
const dimensions = opts.dimensions ? [...opts.dimensions] : [...DIMENSIONS_BY_TABLE[opts.table]];
|
|
192
|
+
const dataState = opts.dataState ?? "all";
|
|
191
193
|
const dimensionFilterGroups = buildDomainFilterGroups(opts.domainFilter);
|
|
192
194
|
const loopStart = Date.now();
|
|
193
195
|
let startRow = opts.initialStartRow ?? 0;
|
|
194
196
|
let totalRows = 0;
|
|
195
197
|
let pageCount = 0;
|
|
198
|
+
let metadata;
|
|
196
199
|
while (true) {
|
|
197
200
|
if (pageCount >= maxPages) return {
|
|
198
201
|
totalRows,
|
|
199
202
|
hasMore: true,
|
|
200
|
-
nextStartRow: startRow
|
|
203
|
+
nextStartRow: startRow,
|
|
204
|
+
metadata
|
|
201
205
|
};
|
|
202
206
|
if (Date.now() - loopStart >= cpuBudgetMs) return {
|
|
203
207
|
totalRows,
|
|
204
208
|
hasMore: true,
|
|
205
|
-
nextStartRow: startRow
|
|
209
|
+
nextStartRow: startRow,
|
|
210
|
+
metadata
|
|
206
211
|
};
|
|
207
212
|
const query = {
|
|
208
213
|
startDate: opts.startDate,
|
|
@@ -210,8 +215,8 @@ async function runGscSyncSlice(opts) {
|
|
|
210
215
|
dimensions,
|
|
211
216
|
rowLimit,
|
|
212
217
|
startRow,
|
|
213
|
-
dataState
|
|
214
|
-
searchType,
|
|
218
|
+
dataState,
|
|
219
|
+
type: searchType,
|
|
215
220
|
...dimensionFilterGroups ? { dimensionFilterGroups } : {}
|
|
216
221
|
};
|
|
217
222
|
const response = await opts.client._rawQuery(opts.siteUrl, query).catch((err) => {
|
|
@@ -221,11 +226,13 @@ async function runGscSyncSlice(opts) {
|
|
|
221
226
|
if (!response) return {
|
|
222
227
|
totalRows,
|
|
223
228
|
hasMore: true,
|
|
224
|
-
nextStartRow: startRow
|
|
229
|
+
nextStartRow: startRow,
|
|
230
|
+
metadata
|
|
225
231
|
};
|
|
226
232
|
const rows = response.rows ?? [];
|
|
227
233
|
totalRows += rows.length;
|
|
228
234
|
pageCount++;
|
|
235
|
+
if (response.metadata) metadata = response.metadata;
|
|
229
236
|
opts.onPage?.({
|
|
230
237
|
searchType,
|
|
231
238
|
rowsThisPage: rows.length
|
|
@@ -240,7 +247,8 @@ async function runGscSyncSlice(opts) {
|
|
|
240
247
|
return {
|
|
241
248
|
totalRows,
|
|
242
249
|
hasMore: false,
|
|
243
|
-
nextStartRow: startRow
|
|
250
|
+
nextStartRow: startRow,
|
|
251
|
+
metadata
|
|
244
252
|
};
|
|
245
253
|
}
|
|
246
254
|
export { canProxyToGsc, createGscApiQuerySource, createLiveGscSource, fetchGscDaily, fetchGscTopN, runGscSyncSlice };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gscdump/engine-gsc-api",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.18.1",
|
|
5
5
|
"description": "GSC live-API engine adapter — wraps the Search Analytics REST API as an AnalysisQuerySource for typed analyzer dispatch.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Harlan Wilton",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"node": ">=18"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@gscdump/engine": "0.
|
|
40
|
-
"gscdump": "0.
|
|
39
|
+
"@gscdump/engine": "0.18.1",
|
|
40
|
+
"gscdump": "0.18.1"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"vitest": "^4.1.6"
|