gscdump 0.11.5 → 0.13.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/dist/contracts.d.mts +51 -2
- package/dist/index.d.mts +23 -1
- package/dist/query/index.d.mts +25 -1
- package/dist/query/index.mjs +13 -0
- package/dist/query/plan.d.mts +3 -1
- package/dist/query/plan.mjs +7 -0
- package/package.json +2 -2
package/dist/contracts.d.mts
CHANGED
|
@@ -1,2 +1,51 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
type TableName = 'pages' | 'keywords' | 'countries' | 'devices' | 'page_keywords' | 'search_appearance';
|
|
2
|
+
type Row = Record<string, unknown>;
|
|
3
|
+
type ColumnType = 'DATE' | 'VARCHAR' | 'INTEGER' | 'BIGINT' | 'DOUBLE';
|
|
4
|
+
interface ColumnDef {
|
|
5
|
+
name: string;
|
|
6
|
+
type: ColumnType;
|
|
7
|
+
nullable: boolean;
|
|
8
|
+
}
|
|
9
|
+
interface TableSchema {
|
|
10
|
+
name: TableName;
|
|
11
|
+
columns: ColumnDef[];
|
|
12
|
+
sortKey: string[];
|
|
13
|
+
version: number;
|
|
14
|
+
}
|
|
15
|
+
interface TenantCtx {
|
|
16
|
+
userId: string;
|
|
17
|
+
siteId?: string;
|
|
18
|
+
}
|
|
19
|
+
type GscSearchAnalyticsDimension = 'page' | 'query' | 'country' | 'device' | 'date' | 'searchAppearance';
|
|
20
|
+
type GscSearchAnalyticsFilterOperator = 'equals' | 'notEquals' | 'contains' | 'notContains' | 'includingRegex' | 'excludingRegex';
|
|
21
|
+
interface GscSearchAnalyticsFilter {
|
|
22
|
+
dimension: GscSearchAnalyticsDimension;
|
|
23
|
+
expression: string;
|
|
24
|
+
operator?: GscSearchAnalyticsFilterOperator;
|
|
25
|
+
}
|
|
26
|
+
interface GscSearchAnalyticsFilterGroup {
|
|
27
|
+
groupType?: 'and' | 'or';
|
|
28
|
+
filters: GscSearchAnalyticsFilter[];
|
|
29
|
+
}
|
|
30
|
+
type GscSearchType = 'web' | 'image' | 'video' | 'news' | 'discover' | 'googleNews';
|
|
31
|
+
interface GscSearchAnalyticsRequest {
|
|
32
|
+
startDate: string;
|
|
33
|
+
endDate: string;
|
|
34
|
+
dimensions?: GscSearchAnalyticsDimension[];
|
|
35
|
+
dimensionFilterGroups?: GscSearchAnalyticsFilterGroup[];
|
|
36
|
+
rowLimit?: number;
|
|
37
|
+
startRow?: number;
|
|
38
|
+
searchType?: GscSearchType;
|
|
39
|
+
}
|
|
40
|
+
interface GscSearchAnalyticsRow {
|
|
41
|
+
keys: string[];
|
|
42
|
+
clicks: number;
|
|
43
|
+
impressions: number;
|
|
44
|
+
ctr: number;
|
|
45
|
+
position: number;
|
|
46
|
+
}
|
|
47
|
+
interface GscSearchAnalyticsResponse {
|
|
48
|
+
rows?: GscSearchAnalyticsRow[];
|
|
49
|
+
responseAggregationType?: string;
|
|
50
|
+
}
|
|
51
|
+
export { ColumnDef, ColumnType, GscSearchAnalyticsDimension, GscSearchAnalyticsFilter, GscSearchAnalyticsFilterGroup, GscSearchAnalyticsFilterOperator, GscSearchAnalyticsRequest, GscSearchAnalyticsResponse, GscSearchAnalyticsRow, GscSearchType, Row, TableName, TableSchema, TenantCtx };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { $Fetch, FetchOptions } from "ofetch";
|
|
2
2
|
import { indexing_v3 } from "@googleapis/indexing/build/v3";
|
|
3
|
-
import { GscSearchAnalyticsRequest } from "@gscdump/contracts";
|
|
4
3
|
import { searchconsole_v1 } from "@googleapis/searchconsole/build/v1";
|
|
5
4
|
/**
|
|
6
5
|
* Batch runner with optional concurrency, inter-call delay, and progress.
|
|
@@ -13,6 +12,27 @@ declare function runSequentialBatch<I, R>(items: I[], operation: (item: I, index
|
|
|
13
12
|
concurrency?: number;
|
|
14
13
|
onProgress?: (result: R, index: number, total: number) => void;
|
|
15
14
|
}): Promise<R[]>;
|
|
15
|
+
type GscSearchAnalyticsDimension = 'page' | 'query' | 'country' | 'device' | 'date' | 'searchAppearance';
|
|
16
|
+
type GscSearchAnalyticsFilterOperator = 'equals' | 'notEquals' | 'contains' | 'notContains' | 'includingRegex' | 'excludingRegex';
|
|
17
|
+
interface GscSearchAnalyticsFilter {
|
|
18
|
+
dimension: GscSearchAnalyticsDimension;
|
|
19
|
+
expression: string;
|
|
20
|
+
operator?: GscSearchAnalyticsFilterOperator;
|
|
21
|
+
}
|
|
22
|
+
interface GscSearchAnalyticsFilterGroup {
|
|
23
|
+
groupType?: 'and' | 'or';
|
|
24
|
+
filters: GscSearchAnalyticsFilter[];
|
|
25
|
+
}
|
|
26
|
+
type GscSearchType = 'web' | 'image' | 'video' | 'news' | 'discover' | 'googleNews';
|
|
27
|
+
interface GscSearchAnalyticsRequest {
|
|
28
|
+
startDate: string;
|
|
29
|
+
endDate: string;
|
|
30
|
+
dimensions?: GscSearchAnalyticsDimension[];
|
|
31
|
+
dimensionFilterGroups?: GscSearchAnalyticsFilterGroup[];
|
|
32
|
+
rowLimit?: number;
|
|
33
|
+
startRow?: number;
|
|
34
|
+
searchType?: GscSearchType;
|
|
35
|
+
}
|
|
16
36
|
declare const _default: {
|
|
17
37
|
name: string;
|
|
18
38
|
'alpha-2': string;
|
|
@@ -86,6 +106,7 @@ interface BuilderState {
|
|
|
86
106
|
dimensions: Dimension[];
|
|
87
107
|
metrics?: Metric[];
|
|
88
108
|
filter?: Filter<any>;
|
|
109
|
+
prefilter?: Filter<any>;
|
|
89
110
|
orderBy?: {
|
|
90
111
|
column: Metric | 'date';
|
|
91
112
|
dir: 'asc' | 'desc';
|
|
@@ -102,6 +123,7 @@ interface GSCQueryBuilder<D extends Dimension[] = [], C = object> {
|
|
|
102
123
|
<T extends SelectableColumn[]>(...cols: T): GSCQueryBuilder<ExtractDimensions<T> & Dimension[], C>;
|
|
103
124
|
};
|
|
104
125
|
where: <F extends Filter<any>>(filter: F) => GSCQueryBuilder<D, C & F['_constraints']>;
|
|
126
|
+
prefilter: <F extends Filter<any>>(filter: F) => GSCQueryBuilder<D, C>;
|
|
105
127
|
orderBy: (col: OrderableColumn, dir: 'asc' | 'desc') => GSCQueryBuilder<D, C>;
|
|
106
128
|
limit: (n: number) => GSCQueryBuilder<D, C>;
|
|
107
129
|
offset: (n: number) => GSCQueryBuilder<D, C>;
|
package/dist/query/index.d.mts
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
import _dayjs, { Dayjs } from "dayjs";
|
|
2
|
-
|
|
2
|
+
type TableName = 'pages' | 'keywords' | 'countries' | 'devices' | 'page_keywords' | 'search_appearance';
|
|
3
|
+
type GscSearchAnalyticsDimension = 'page' | 'query' | 'country' | 'device' | 'date' | 'searchAppearance';
|
|
4
|
+
type GscSearchAnalyticsFilterOperator = 'equals' | 'notEquals' | 'contains' | 'notContains' | 'includingRegex' | 'excludingRegex';
|
|
5
|
+
interface GscSearchAnalyticsFilter {
|
|
6
|
+
dimension: GscSearchAnalyticsDimension;
|
|
7
|
+
expression: string;
|
|
8
|
+
operator?: GscSearchAnalyticsFilterOperator;
|
|
9
|
+
}
|
|
10
|
+
interface GscSearchAnalyticsFilterGroup {
|
|
11
|
+
groupType?: 'and' | 'or';
|
|
12
|
+
filters: GscSearchAnalyticsFilter[];
|
|
13
|
+
}
|
|
14
|
+
type GscSearchType = 'web' | 'image' | 'video' | 'news' | 'discover' | 'googleNews';
|
|
15
|
+
interface GscSearchAnalyticsRequest {
|
|
16
|
+
startDate: string;
|
|
17
|
+
endDate: string;
|
|
18
|
+
dimensions?: GscSearchAnalyticsDimension[];
|
|
19
|
+
dimensionFilterGroups?: GscSearchAnalyticsFilterGroup[];
|
|
20
|
+
rowLimit?: number;
|
|
21
|
+
startRow?: number;
|
|
22
|
+
searchType?: GscSearchType;
|
|
23
|
+
}
|
|
3
24
|
declare const _default: {
|
|
4
25
|
name: string;
|
|
5
26
|
'alpha-2': string;
|
|
@@ -82,6 +103,7 @@ interface BuilderState {
|
|
|
82
103
|
dimensions: Dimension[];
|
|
83
104
|
metrics?: Metric[];
|
|
84
105
|
filter?: Filter<any>;
|
|
106
|
+
prefilter?: Filter<any>;
|
|
85
107
|
orderBy?: {
|
|
86
108
|
column: Metric | 'date';
|
|
87
109
|
dir: 'asc' | 'desc';
|
|
@@ -110,6 +132,7 @@ interface GSCQueryBuilder<D extends Dimension[] = [], C = object> {
|
|
|
110
132
|
<T extends SelectableColumn[]>(...cols: T): GSCQueryBuilder<ExtractDimensions<T> & Dimension[], C>;
|
|
111
133
|
};
|
|
112
134
|
where: <F extends Filter<any>>(filter: F) => GSCQueryBuilder<D, C & F['_constraints']>;
|
|
135
|
+
prefilter: <F extends Filter<any>>(filter: F) => GSCQueryBuilder<D, C>;
|
|
113
136
|
orderBy: (col: OrderableColumn, dir: 'asc' | 'desc') => GSCQueryBuilder<D, C>;
|
|
114
137
|
limit: (n: number) => GSCQueryBuilder<D, C>;
|
|
115
138
|
offset: (n: number) => GSCQueryBuilder<D, C>;
|
|
@@ -194,6 +217,7 @@ interface LogicalQueryPlan {
|
|
|
194
217
|
dimensionFilters: LogicalDimensionFilter[];
|
|
195
218
|
dimensionFilterTree?: LogicalFilterNode;
|
|
196
219
|
metricFilters: LogicalMetricFilter[];
|
|
220
|
+
prefilters: LogicalMetricFilter[];
|
|
197
221
|
specialFilters: {
|
|
198
222
|
topLevel: boolean;
|
|
199
223
|
};
|
package/dist/query/index.mjs
CHANGED
|
@@ -258,6 +258,12 @@ function createBuilder(state) {
|
|
|
258
258
|
filter
|
|
259
259
|
});
|
|
260
260
|
},
|
|
261
|
+
prefilter(filter) {
|
|
262
|
+
return createBuilder({
|
|
263
|
+
...state,
|
|
264
|
+
prefilter: filter
|
|
265
|
+
});
|
|
266
|
+
},
|
|
261
267
|
orderBy(col, dir) {
|
|
262
268
|
const column = isMetricColumn(col) ? col.metric : col.dimension;
|
|
263
269
|
return createBuilder({
|
|
@@ -1995,6 +2001,7 @@ function buildLogicalPlan(state, capabilities = {}) {
|
|
|
1995
2001
|
const allFilters = collectInternalFilters(normalizedFilter);
|
|
1996
2002
|
const metricFilters = extractMetricFilters(normalizedFilter);
|
|
1997
2003
|
const specialFilters = extractSpecialOperatorFilters(normalizedFilter);
|
|
2004
|
+
const prefilters = extractMetricFilters(normalizeFilter(state.prefilter));
|
|
1998
2005
|
const queryParams = {};
|
|
1999
2006
|
const dimensionFilters = [];
|
|
2000
2007
|
for (const filter of allFilters) {
|
|
@@ -2039,6 +2046,12 @@ function buildLogicalPlan(state, capabilities = {}) {
|
|
|
2039
2046
|
expression: Number(filter.expression),
|
|
2040
2047
|
expression2: filter.expression2 == null ? void 0 : Number(filter.expression2)
|
|
2041
2048
|
})),
|
|
2049
|
+
prefilters: prefilters.map((filter) => ({
|
|
2050
|
+
metric: filter.dimension,
|
|
2051
|
+
operator: filter.operator,
|
|
2052
|
+
expression: Number(filter.expression),
|
|
2053
|
+
expression2: filter.expression2 == null ? void 0 : Number(filter.expression2)
|
|
2054
|
+
})),
|
|
2042
2055
|
specialFilters: { topLevel: specialFilters.some((filter) => filter.operator === "topLevel") },
|
|
2043
2056
|
queryParams,
|
|
2044
2057
|
orderBy: state.orderBy,
|
package/dist/query/plan.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
type TableName = 'pages' | 'keywords' | 'countries' | 'devices' | 'page_keywords' | 'search_appearance';
|
|
2
2
|
declare const _default: {
|
|
3
3
|
name: string;
|
|
4
4
|
'alpha-2': string;
|
|
@@ -58,6 +58,7 @@ interface BuilderState {
|
|
|
58
58
|
dimensions: Dimension[];
|
|
59
59
|
metrics?: Metric[];
|
|
60
60
|
filter?: Filter<any>;
|
|
61
|
+
prefilter?: Filter<any>;
|
|
61
62
|
orderBy?: {
|
|
62
63
|
column: Metric | 'date';
|
|
63
64
|
dir: 'asc' | 'desc';
|
|
@@ -108,6 +109,7 @@ interface LogicalQueryPlan {
|
|
|
108
109
|
dimensionFilters: LogicalDimensionFilter[];
|
|
109
110
|
dimensionFilterTree?: LogicalFilterNode;
|
|
110
111
|
metricFilters: LogicalMetricFilter[];
|
|
112
|
+
prefilters: LogicalMetricFilter[];
|
|
111
113
|
specialFilters: {
|
|
112
114
|
topLevel: boolean;
|
|
113
115
|
};
|
package/dist/query/plan.mjs
CHANGED
|
@@ -231,6 +231,7 @@ function buildLogicalPlan(state, capabilities = {}) {
|
|
|
231
231
|
const allFilters = collectInternalFilters(normalizedFilter);
|
|
232
232
|
const metricFilters = extractMetricFilters(normalizedFilter);
|
|
233
233
|
const specialFilters = extractSpecialOperatorFilters(normalizedFilter);
|
|
234
|
+
const prefilters = extractMetricFilters(normalizeFilter(state.prefilter));
|
|
234
235
|
const queryParams = {};
|
|
235
236
|
const dimensionFilters = [];
|
|
236
237
|
for (const filter of allFilters) {
|
|
@@ -275,6 +276,12 @@ function buildLogicalPlan(state, capabilities = {}) {
|
|
|
275
276
|
expression: Number(filter.expression),
|
|
276
277
|
expression2: filter.expression2 == null ? void 0 : Number(filter.expression2)
|
|
277
278
|
})),
|
|
279
|
+
prefilters: prefilters.map((filter) => ({
|
|
280
|
+
metric: filter.dimension,
|
|
281
|
+
operator: filter.operator,
|
|
282
|
+
expression: Number(filter.expression),
|
|
283
|
+
expression2: filter.expression2 == null ? void 0 : Number(filter.expression2)
|
|
284
|
+
})),
|
|
278
285
|
specialFilters: { topLevel: specialFilters.some((filter) => filter.operator === "topLevel") },
|
|
279
286
|
queryParams,
|
|
280
287
|
orderBy: state.orderBy,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gscdump",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.13.0",
|
|
5
5
|
"description": "Google Search Console API wrapper with typed query builder, streaming pagination, and SEO analysis functions",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Harlan Wilton",
|
|
@@ -108,7 +108,7 @@
|
|
|
108
108
|
"defu": "^6.1.7",
|
|
109
109
|
"ofetch": "^1.5.1",
|
|
110
110
|
"ufo": "^1.6.4",
|
|
111
|
-
"@gscdump/contracts": "0.
|
|
111
|
+
"@gscdump/contracts": "0.13.0"
|
|
112
112
|
},
|
|
113
113
|
"devDependencies": {
|
|
114
114
|
"@googleapis/indexing": "^6.0.1",
|