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/query/index.d.mts
CHANGED
|
@@ -1,45 +1,11 @@
|
|
|
1
|
-
import "
|
|
2
|
-
import { indexing_v3 } from "@googleapis/indexing/v3";
|
|
1
|
+
import _dayjs, { Dayjs } from "dayjs";
|
|
3
2
|
import { searchconsole_v1 } from "@googleapis/searchconsole/v1";
|
|
4
3
|
|
|
5
4
|
//#region src/core/types.d.ts
|
|
6
|
-
type ApiSite = searchconsole_v1.Schema$WmxSite;
|
|
7
|
-
type ApiSitemap = searchconsole_v1.Schema$WmxSitemap;
|
|
8
|
-
type SearchAnalyticsQuery = searchconsole_v1.Schema$SearchAnalyticsQueryRequest;
|
|
9
|
-
type SearchAnalyticsResponse = searchconsole_v1.Schema$SearchAnalyticsQueryResponse;
|
|
10
|
-
type InspectUrlIndexResponse = searchconsole_v1.Schema$InspectUrlIndexResponse;
|
|
11
|
-
type UrlNotificationMetadata = indexing_v3.Schema$UrlNotificationMetadata;
|
|
12
|
-
type PublishUrlNotificationResponse = indexing_v3.Schema$PublishUrlNotificationResponse;
|
|
13
|
-
//#endregion
|
|
14
|
-
//#region src/core/client.d.ts
|
|
15
5
|
|
|
16
|
-
|
|
17
|
-
sites: {
|
|
18
|
-
list: () => Promise<{
|
|
19
|
-
siteEntry?: ApiSite[];
|
|
20
|
-
}>;
|
|
21
|
-
};
|
|
22
|
-
sitemaps: {
|
|
23
|
-
list: (siteUrl: string) => Promise<{
|
|
24
|
-
sitemap?: ApiSitemap[];
|
|
25
|
-
}>;
|
|
26
|
-
get: (siteUrl: string, feedpath: string) => Promise<ApiSitemap>;
|
|
27
|
-
submit: (siteUrl: string, feedpath: string) => Promise<void>;
|
|
28
|
-
delete: (siteUrl: string, feedpath: string) => Promise<void>;
|
|
29
|
-
};
|
|
30
|
-
searchAnalytics: {
|
|
31
|
-
query: (siteUrl: string, body: SearchAnalyticsQuery) => Promise<SearchAnalyticsResponse>;
|
|
32
|
-
};
|
|
33
|
-
urlInspection: {
|
|
34
|
-
inspect: (siteUrl: string, inspectionUrl: string) => Promise<InspectUrlIndexResponse>;
|
|
35
|
-
};
|
|
36
|
-
indexing: {
|
|
37
|
-
publish: (url: string, type: 'URL_UPDATED' | 'URL_DELETED') => Promise<PublishUrlNotificationResponse>;
|
|
38
|
-
getMetadata: (url: string) => Promise<UrlNotificationMetadata>;
|
|
39
|
-
};
|
|
40
|
-
}
|
|
6
|
+
type SearchAnalyticsQuery = searchconsole_v1.Schema$SearchAnalyticsQueryRequest;
|
|
41
7
|
//#endregion
|
|
42
|
-
//#region src/utils/countries.d.ts
|
|
8
|
+
//#region src/query/utils/countries.d.ts
|
|
43
9
|
declare const _default: {
|
|
44
10
|
name: string;
|
|
45
11
|
'alpha-2': string;
|
|
@@ -48,14 +14,21 @@ declare const _default: {
|
|
|
48
14
|
}[];
|
|
49
15
|
//#endregion
|
|
50
16
|
//#region src/query/constants.d.ts
|
|
51
|
-
declare const
|
|
17
|
+
declare const Devices: {
|
|
52
18
|
readonly MOBILE: "MOBILE";
|
|
53
19
|
readonly DESKTOP: "DESKTOP";
|
|
54
20
|
readonly TABLET: "TABLET";
|
|
55
21
|
};
|
|
56
|
-
type Device = typeof
|
|
57
|
-
declare const
|
|
58
|
-
|
|
22
|
+
type Device = typeof Devices[keyof typeof Devices];
|
|
23
|
+
declare const SearchTypes: {
|
|
24
|
+
readonly WEB: "web";
|
|
25
|
+
readonly IMAGE: "image";
|
|
26
|
+
readonly VIDEO: "video";
|
|
27
|
+
readonly NEWS: "news";
|
|
28
|
+
};
|
|
29
|
+
type SearchType = typeof SearchTypes[keyof typeof SearchTypes];
|
|
30
|
+
declare const Countries: { [K in (typeof _default)[number]["alpha-3"]]: Lowercase<K> };
|
|
31
|
+
type Country = typeof Countries[keyof typeof Countries];
|
|
59
32
|
//#endregion
|
|
60
33
|
//#region src/query/types.d.ts
|
|
61
34
|
interface DimensionValueMap {
|
|
@@ -67,15 +40,24 @@ interface DimensionValueMap {
|
|
|
67
40
|
date: string;
|
|
68
41
|
}
|
|
69
42
|
type Dimension = keyof DimensionValueMap;
|
|
43
|
+
interface QueryParamValueMap {
|
|
44
|
+
searchType: SearchType;
|
|
45
|
+
}
|
|
46
|
+
type QueryParamName = keyof QueryParamValueMap;
|
|
70
47
|
declare const ColumnBrand: unique symbol;
|
|
71
48
|
interface Column<D extends Dimension> {
|
|
72
49
|
readonly [ColumnBrand]: D;
|
|
73
50
|
readonly dimension: D;
|
|
74
51
|
}
|
|
52
|
+
declare const QueryParamBrand: unique symbol;
|
|
53
|
+
interface QueryParam<P extends QueryParamName> {
|
|
54
|
+
readonly [QueryParamBrand]: P;
|
|
55
|
+
readonly param: P;
|
|
56
|
+
}
|
|
75
57
|
type FilterOperator = 'equals' | 'notEquals' | 'contains' | 'notContains' | 'includingRegex' | 'excludingRegex';
|
|
76
58
|
type DateOperator = 'gte' | 'gt' | 'lte' | 'lt' | 'between';
|
|
77
59
|
interface InternalFilter {
|
|
78
|
-
dimension: Dimension;
|
|
60
|
+
dimension: Dimension | QueryParamName;
|
|
79
61
|
operator: FilterOperator | DateOperator;
|
|
80
62
|
expression: string;
|
|
81
63
|
expression2?: string;
|
|
@@ -85,6 +67,7 @@ interface Filter<C = object> {
|
|
|
85
67
|
readonly [FilterBrand]: true;
|
|
86
68
|
readonly _constraints: C;
|
|
87
69
|
readonly _filters: InternalFilter[];
|
|
70
|
+
readonly _nestedGroups?: Filter<any>[];
|
|
88
71
|
readonly _groupType?: 'and' | 'or';
|
|
89
72
|
}
|
|
90
73
|
type MergeConstraints<F extends Filter<any>[]> = UnionToIntersection<F[number]['_constraints']>;
|
|
@@ -100,8 +83,7 @@ type GSCRow<D extends Dimension[], C> = { [K in D[number]]: K extends keyof C ?
|
|
|
100
83
|
};
|
|
101
84
|
interface BuilderState {
|
|
102
85
|
dimensions: Dimension[];
|
|
103
|
-
|
|
104
|
-
siteUrl?: string;
|
|
86
|
+
filter?: Filter<any>;
|
|
105
87
|
rowLimit?: number;
|
|
106
88
|
startRow?: number;
|
|
107
89
|
}
|
|
@@ -110,12 +92,9 @@ interface BuilderState {
|
|
|
110
92
|
interface GSCQueryBuilder<D extends Dimension[] = [], C = object> {
|
|
111
93
|
select: <T extends Dimension[]>(...dims: T) => GSCQueryBuilder<T, C>;
|
|
112
94
|
where: <F extends Filter<any>>(filter: F) => GSCQueryBuilder<D, C & F['_constraints']>;
|
|
113
|
-
siteUrl: (url: string) => GSCQueryBuilder<D, C>;
|
|
114
95
|
limit: (n: number) => GSCQueryBuilder<D, C>;
|
|
115
96
|
offset: (n: number) => GSCQueryBuilder<D, C>;
|
|
116
|
-
execute: (client: GoogleSearchConsoleClient) => Promise<GSCResult<D, C>>;
|
|
117
97
|
toBody: () => SearchAnalyticsQuery;
|
|
118
|
-
/** Expose internal state for analysis functions to merge with */
|
|
119
98
|
getState: () => BuilderState;
|
|
120
99
|
}
|
|
121
100
|
declare const gsc: GSCQueryBuilder<[], object>;
|
|
@@ -127,9 +106,11 @@ declare const device: Column<"device">;
|
|
|
127
106
|
declare const country: Column<"country">;
|
|
128
107
|
declare const searchAppearance: Column<"searchAppearance">;
|
|
129
108
|
declare const date: Column<"date">;
|
|
109
|
+
declare const searchType: QueryParam<"searchType">;
|
|
130
110
|
//#endregion
|
|
131
111
|
//#region src/query/operators.d.ts
|
|
132
112
|
declare function eq<D extends Dimension, V extends DimensionValueMap[D]>(column: Column<D>, value: V): Filter<Record<D, V>>;
|
|
113
|
+
declare function eq<P extends QueryParamName, V extends QueryParamValueMap[P]>(param: QueryParam<P>, value: V): Filter<Record<P, V>>;
|
|
133
114
|
declare function ne<D extends Dimension>(column: Column<D>, value: DimensionValueMap[D]): Filter<object>;
|
|
134
115
|
declare function inArray<D extends Dimension, V extends DimensionValueMap[D]>(column: Column<D>, values: readonly V[]): Filter<Record<D, V>>;
|
|
135
116
|
declare function contains<D extends Dimension>(column: Column<D>, pattern: string): Filter<object>;
|
|
@@ -146,12 +127,18 @@ declare function lt<D extends Dimension>(column: Column<D>, value: DimensionValu
|
|
|
146
127
|
declare function between<D extends Dimension>(column: Column<D>, start: DimensionValueMap[D], end: DimensionValueMap[D]): Filter<object>;
|
|
147
128
|
//#endregion
|
|
148
129
|
//#region src/query/resolver.d.ts
|
|
149
|
-
|
|
150
|
-
* Extract date range from filters. Used by analysis functions to get the period.
|
|
151
|
-
*/
|
|
152
|
-
declare function extractDateRange(filters: Filter<any>[]): {
|
|
130
|
+
declare function extractDateRange(filter?: Filter<any>): {
|
|
153
131
|
startDate?: string;
|
|
154
132
|
endDate?: string;
|
|
155
133
|
};
|
|
156
134
|
//#endregion
|
|
157
|
-
|
|
135
|
+
//#region src/query/utils/dayjs.d.ts
|
|
136
|
+
declare function dayjs(date?: _dayjs.ConfigType): Dayjs;
|
|
137
|
+
declare function currentPstDate(): string;
|
|
138
|
+
declare function dayjsPst(): Dayjs;
|
|
139
|
+
//#endregion
|
|
140
|
+
//#region src/query/index.d.ts
|
|
141
|
+
declare function today(): string;
|
|
142
|
+
declare function daysAgo(n: number): string;
|
|
143
|
+
//#endregion
|
|
144
|
+
export { type BuilderState, type Column, Countries, type Country, type Device, Devices, type Dimension, type DimensionValueMap, type Filter, type GSCQueryBuilder, type GSCResult, type GSCRow, type QueryParam, type QueryParamName, type QueryParamValueMap, type SearchType, SearchTypes, and, between, contains, country, currentPstDate, date, dayjs, dayjsPst, daysAgo, device, eq, extractDateRange, gsc, gt, gte, inArray, like, lt, lte, ne, not, notRegex, or, page, query, regex, searchAppearance, searchType, today };
|
package/dist/query/index.mjs
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
+
import _dayjs from "dayjs";
|
|
2
|
+
import timezone from "dayjs/plugin/timezone.js";
|
|
3
|
+
import utc from "dayjs/plugin/utc.js";
|
|
4
|
+
|
|
5
|
+
//#region src/query/utils/dayjs.ts
|
|
6
|
+
_dayjs.extend(utc);
|
|
7
|
+
_dayjs.extend(timezone);
|
|
8
|
+
function dayjs(date$1) {
|
|
9
|
+
return _dayjs(date$1);
|
|
10
|
+
}
|
|
11
|
+
function currentPstDate() {
|
|
12
|
+
return dayjs().tz("America/Los_Angeles").hour(12).minute(0).second(0).format("YYYY-MM-DD");
|
|
13
|
+
}
|
|
14
|
+
function dayjsPst() {
|
|
15
|
+
return dayjs().tz("America/Los_Angeles").hour(12).minute(0).second(0);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
//#endregion
|
|
1
19
|
//#region src/query/resolver.ts
|
|
2
20
|
const DATE_OPERATORS = [
|
|
3
21
|
"gte",
|
|
@@ -6,110 +24,110 @@ const DATE_OPERATORS = [
|
|
|
6
24
|
"lt",
|
|
7
25
|
"between"
|
|
8
26
|
];
|
|
27
|
+
const QUERY_PARAMS = ["searchType"];
|
|
9
28
|
function isDateOperator(op) {
|
|
10
29
|
return DATE_OPERATORS.includes(op);
|
|
11
30
|
}
|
|
31
|
+
function isQueryParam(dim) {
|
|
32
|
+
return QUERY_PARAMS.includes(dim);
|
|
33
|
+
}
|
|
12
34
|
function addDays(dateStr, days) {
|
|
13
35
|
const d = new Date(dateStr);
|
|
14
36
|
d.setDate(d.getDate() + days);
|
|
15
37
|
return d.toISOString().split("T")[0];
|
|
16
38
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
*/
|
|
20
|
-
function extractDateRange(filters) {
|
|
21
|
-
const { startDate, endDate } = extractDateFilters(filters);
|
|
22
|
-
return {
|
|
23
|
-
startDate,
|
|
24
|
-
endDate
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
function extractDateFilters(filters) {
|
|
39
|
+
function extractSpecialFilters(filter) {
|
|
40
|
+
if (!filter) return {};
|
|
28
41
|
let startDate;
|
|
29
42
|
let endDate;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
43
|
+
let searchType$1;
|
|
44
|
+
const otherFilters = [];
|
|
45
|
+
const cleanedNestedGroups = [];
|
|
46
|
+
for (const f of filter._filters) if (f.dimension === "date" && isDateOperator(f.operator)) switch (f.operator) {
|
|
47
|
+
case "gte":
|
|
48
|
+
startDate = f.expression;
|
|
49
|
+
break;
|
|
50
|
+
case "gt":
|
|
51
|
+
startDate = addDays(f.expression, 1);
|
|
52
|
+
break;
|
|
53
|
+
case "lte":
|
|
54
|
+
endDate = f.expression;
|
|
55
|
+
break;
|
|
56
|
+
case "lt":
|
|
57
|
+
endDate = addDays(f.expression, -1);
|
|
58
|
+
break;
|
|
59
|
+
case "between":
|
|
60
|
+
startDate = f.expression;
|
|
61
|
+
endDate = f.expression2;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
else if (isQueryParam(f.dimension)) {
|
|
65
|
+
if (f.dimension === "searchType") searchType$1 = f.expression;
|
|
66
|
+
} else otherFilters.push(f);
|
|
67
|
+
if (filter._nestedGroups) for (const nested of filter._nestedGroups) {
|
|
68
|
+
const extracted = extractSpecialFilters(nested);
|
|
69
|
+
if (extracted.startDate) startDate = extracted.startDate;
|
|
70
|
+
if (extracted.endDate) endDate = extracted.endDate;
|
|
71
|
+
if (extracted.searchType) searchType$1 = extracted.searchType;
|
|
72
|
+
if (extracted.dimensionFilter) cleanedNestedGroups.push(extracted.dimensionFilter);
|
|
58
73
|
}
|
|
74
|
+
const dimensionFilter = otherFilters.length > 0 || cleanedNestedGroups.length > 0 ? {
|
|
75
|
+
...filter,
|
|
76
|
+
_filters: otherFilters,
|
|
77
|
+
_nestedGroups: cleanedNestedGroups.length > 0 ? cleanedNestedGroups : void 0
|
|
78
|
+
} : void 0;
|
|
59
79
|
return {
|
|
60
80
|
startDate,
|
|
61
81
|
endDate,
|
|
62
|
-
|
|
82
|
+
searchType: searchType$1,
|
|
83
|
+
dimensionFilter
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function extractDateRange(filter) {
|
|
87
|
+
const { startDate, endDate } = extractSpecialFilters(filter);
|
|
88
|
+
return {
|
|
89
|
+
startDate,
|
|
90
|
+
endDate
|
|
63
91
|
};
|
|
64
92
|
}
|
|
65
93
|
function resolveToBody(state) {
|
|
66
|
-
const { startDate, endDate,
|
|
67
|
-
if (!startDate || !endDate) throw new Error("Date range required: use .where(between(date, start, end)) or .where(gte(date, start)
|
|
94
|
+
const { startDate, endDate, searchType: searchType$1, dimensionFilter } = extractSpecialFilters(state.filter);
|
|
95
|
+
if (!startDate || !endDate) throw new Error("Date range required: use .where(between(date, start, end)) or .where(and(gte(date, start), lte(date, end)))");
|
|
68
96
|
const body = {
|
|
69
97
|
dimensions: state.dimensions,
|
|
70
98
|
startDate,
|
|
71
99
|
endDate
|
|
72
100
|
};
|
|
101
|
+
if (searchType$1) body.searchType = searchType$1;
|
|
73
102
|
if (state.rowLimit) body.rowLimit = state.rowLimit;
|
|
74
103
|
if (state.startRow) body.startRow = state.startRow;
|
|
75
|
-
const filterGroups =
|
|
104
|
+
const filterGroups = resolveFilter(dimensionFilter);
|
|
76
105
|
if (filterGroups.length > 0) body.dimensionFilterGroups = filterGroups;
|
|
77
106
|
return body;
|
|
78
107
|
}
|
|
79
|
-
function
|
|
108
|
+
function resolveFilter(filter) {
|
|
109
|
+
if (!filter) return [];
|
|
80
110
|
const groups = [];
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
111
|
+
if ((filter._groupType ?? "and") === "or") {
|
|
112
|
+
if (filter._filters.length > 0) groups.push({
|
|
113
|
+
groupType: "or",
|
|
114
|
+
filters: filter._filters.map((f) => ({
|
|
115
|
+
dimension: f.dimension,
|
|
116
|
+
operator: f.operator,
|
|
117
|
+
expression: f.expression
|
|
118
|
+
}))
|
|
119
|
+
});
|
|
120
|
+
} else if (filter._filters.length > 0) groups.push({ filters: filter._filters.map((f) => ({
|
|
90
121
|
dimension: f.dimension,
|
|
91
122
|
operator: f.operator,
|
|
92
123
|
expression: f.expression
|
|
93
124
|
})) });
|
|
125
|
+
if (filter._nestedGroups) for (const nested of filter._nestedGroups) groups.push(...resolveFilter(nested));
|
|
94
126
|
return groups;
|
|
95
127
|
}
|
|
96
128
|
|
|
97
129
|
//#endregion
|
|
98
130
|
//#region src/query/builder.ts
|
|
99
|
-
function transformResponse(response, dimensions) {
|
|
100
|
-
return { rows: (response.rows ?? []).map((row) => {
|
|
101
|
-
const result = {
|
|
102
|
-
clicks: row.clicks,
|
|
103
|
-
impressions: row.impressions,
|
|
104
|
-
ctr: row.ctr,
|
|
105
|
-
position: row.position
|
|
106
|
-
};
|
|
107
|
-
dimensions.forEach((dim, i) => {
|
|
108
|
-
result[dim] = row.keys?.[i];
|
|
109
|
-
});
|
|
110
|
-
return result;
|
|
111
|
-
}) };
|
|
112
|
-
}
|
|
113
131
|
function createBuilder(state) {
|
|
114
132
|
return {
|
|
115
133
|
select(...dims) {
|
|
@@ -121,13 +139,7 @@ function createBuilder(state) {
|
|
|
121
139
|
where(filter) {
|
|
122
140
|
return createBuilder({
|
|
123
141
|
...state,
|
|
124
|
-
|
|
125
|
-
});
|
|
126
|
-
},
|
|
127
|
-
siteUrl(url) {
|
|
128
|
-
return createBuilder({
|
|
129
|
-
...state,
|
|
130
|
-
siteUrl: url
|
|
142
|
+
filter
|
|
131
143
|
});
|
|
132
144
|
},
|
|
133
145
|
limit(n) {
|
|
@@ -142,10 +154,6 @@ function createBuilder(state) {
|
|
|
142
154
|
startRow: n
|
|
143
155
|
});
|
|
144
156
|
},
|
|
145
|
-
async execute(client) {
|
|
146
|
-
const body = resolveToBody(state);
|
|
147
|
-
return transformResponse(await client.searchAnalytics.query(state.siteUrl, body), state.dimensions);
|
|
148
|
-
},
|
|
149
157
|
toBody() {
|
|
150
158
|
return resolveToBody(state);
|
|
151
159
|
},
|
|
@@ -154,25 +162,26 @@ function createBuilder(state) {
|
|
|
154
162
|
}
|
|
155
163
|
};
|
|
156
164
|
}
|
|
157
|
-
const gsc = createBuilder({
|
|
158
|
-
dimensions: [],
|
|
159
|
-
filters: []
|
|
160
|
-
});
|
|
165
|
+
const gsc = createBuilder({ dimensions: [] });
|
|
161
166
|
|
|
162
167
|
//#endregion
|
|
163
168
|
//#region src/query/columns.ts
|
|
164
169
|
function createColumn(dimension) {
|
|
165
170
|
return { dimension };
|
|
166
171
|
}
|
|
172
|
+
function createQueryParam(param) {
|
|
173
|
+
return { param };
|
|
174
|
+
}
|
|
167
175
|
const page = createColumn("page");
|
|
168
176
|
const query = createColumn("query");
|
|
169
177
|
const device = createColumn("device");
|
|
170
178
|
const country = createColumn("country");
|
|
171
179
|
const searchAppearance = createColumn("searchAppearance");
|
|
172
180
|
const date = createColumn("date");
|
|
181
|
+
const searchType = createQueryParam("searchType");
|
|
173
182
|
|
|
174
183
|
//#endregion
|
|
175
|
-
//#region src/utils/countries.ts
|
|
184
|
+
//#region src/query/utils/countries.ts
|
|
176
185
|
var countries_default = [
|
|
177
186
|
{
|
|
178
187
|
"name": "Afghanistan",
|
|
@@ -1672,20 +1681,26 @@ var countries_default = [
|
|
|
1672
1681
|
|
|
1673
1682
|
//#endregion
|
|
1674
1683
|
//#region src/query/constants.ts
|
|
1675
|
-
const
|
|
1684
|
+
const Devices = {
|
|
1676
1685
|
MOBILE: "MOBILE",
|
|
1677
1686
|
DESKTOP: "DESKTOP",
|
|
1678
1687
|
TABLET: "TABLET"
|
|
1679
1688
|
};
|
|
1680
|
-
const
|
|
1689
|
+
const SearchTypes = {
|
|
1690
|
+
WEB: "web",
|
|
1691
|
+
IMAGE: "image",
|
|
1692
|
+
VIDEO: "video",
|
|
1693
|
+
NEWS: "news"
|
|
1694
|
+
};
|
|
1695
|
+
const Countries = Object.fromEntries(countries_default.map((c) => [c["alpha-3"], c["alpha-3"].toLowerCase()]));
|
|
1681
1696
|
|
|
1682
1697
|
//#endregion
|
|
1683
1698
|
//#region src/query/operators.ts
|
|
1684
|
-
function eq(
|
|
1699
|
+
function eq(columnOrParam, value) {
|
|
1685
1700
|
return {
|
|
1686
1701
|
_constraints: {},
|
|
1687
1702
|
_filters: [{
|
|
1688
|
-
dimension:
|
|
1703
|
+
dimension: "dimension" in columnOrParam ? columnOrParam.dimension : columnOrParam.param,
|
|
1689
1704
|
operator: "equals",
|
|
1690
1705
|
expression: String(value)
|
|
1691
1706
|
}]
|
|
@@ -1753,9 +1768,17 @@ function notRegex(column, pattern) {
|
|
|
1753
1768
|
};
|
|
1754
1769
|
}
|
|
1755
1770
|
function and(...filters) {
|
|
1771
|
+
const flatFilters = [];
|
|
1772
|
+
const nestedGroups = [];
|
|
1773
|
+
for (const f of filters) if (f._groupType === "or") nestedGroups.push(f);
|
|
1774
|
+
else {
|
|
1775
|
+
flatFilters.push(...f._filters);
|
|
1776
|
+
if (f._nestedGroups) nestedGroups.push(...f._nestedGroups);
|
|
1777
|
+
}
|
|
1756
1778
|
return {
|
|
1757
1779
|
_constraints: {},
|
|
1758
|
-
_filters:
|
|
1780
|
+
_filters: flatFilters,
|
|
1781
|
+
_nestedGroups: nestedGroups.length > 0 ? nestedGroups : void 0,
|
|
1759
1782
|
_groupType: "and"
|
|
1760
1783
|
};
|
|
1761
1784
|
}
|
|
@@ -1845,4 +1868,13 @@ function between(column, start, end) {
|
|
|
1845
1868
|
}
|
|
1846
1869
|
|
|
1847
1870
|
//#endregion
|
|
1848
|
-
|
|
1871
|
+
//#region src/query/index.ts
|
|
1872
|
+
function today() {
|
|
1873
|
+
return currentPstDate();
|
|
1874
|
+
}
|
|
1875
|
+
function daysAgo(n) {
|
|
1876
|
+
return dayjsPst().subtract(n, "day").format("YYYY-MM-DD");
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
//#endregion
|
|
1880
|
+
export { Countries, Devices, SearchTypes, and, between, contains, country, currentPstDate, date, dayjs, dayjsPst, daysAgo, device, eq, extractDateRange, gsc, gt, gte, inArray, like, lt, lte, ne, not, notRegex, or, page, query, regex, searchAppearance, searchType, today };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gscdump",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.2.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",
|
|
@@ -39,6 +39,10 @@
|
|
|
39
39
|
"./query": {
|
|
40
40
|
"types": "./dist/query/index.d.mts",
|
|
41
41
|
"import": "./dist/query/index.mjs"
|
|
42
|
+
},
|
|
43
|
+
"./analysis": {
|
|
44
|
+
"types": "./dist/analysis/index.d.mts",
|
|
45
|
+
"import": "./dist/analysis/index.mjs"
|
|
42
46
|
}
|
|
43
47
|
},
|
|
44
48
|
"main": "./dist/index.mjs",
|