gscdump 0.4.0 → 0.6.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 -5
- package/dist/contracts.d.mts +136 -0
- package/dist/contracts.mjs +1 -0
- package/dist/driver.d.mts +78 -0
- package/dist/driver.mjs +1 -0
- package/dist/index.d.mts +158 -89
- package/dist/index.mjs +389 -257
- package/dist/normalize.d.mts +2 -0
- package/dist/normalize.mjs +16 -0
- package/dist/query/index.d.mts +73 -33
- package/dist/query/index.mjs +238 -190
- package/dist/query/plan.d.mts +130 -0
- package/dist/query/plan.mjs +296 -0
- package/dist/sitemap.d.mts +13 -0
- package/dist/sitemap.mjs +31 -0
- package/dist/tenant.d.mts +18 -0
- package/dist/tenant.mjs +18 -0
- package/dist/url.d.mts +9 -0
- package/dist/url.mjs +6 -0
- package/package.json +43 -9
- package/dist/analysis/index.d.mts +0 -513
- package/dist/analysis/index.mjs +0 -872
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const URL_PROTOCOL_RE = /^[a-z][a-z0-9+.-]*:\/\//i;
|
|
2
|
+
function normalizeUrl(input) {
|
|
3
|
+
if (!input) return input;
|
|
4
|
+
if (!URL_PROTOCOL_RE.test(input)) return input.startsWith("/") ? input : `/${input}`;
|
|
5
|
+
const parsed = safeParse(input);
|
|
6
|
+
if (!parsed) return input;
|
|
7
|
+
return `${parsed.pathname}${parsed.search}${parsed.hash}`;
|
|
8
|
+
}
|
|
9
|
+
function safeParse(input) {
|
|
10
|
+
try {
|
|
11
|
+
return new URL(input);
|
|
12
|
+
} catch {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export { normalizeUrl };
|
package/dist/query/index.d.mts
CHANGED
|
@@ -1,19 +1,12 @@
|
|
|
1
1
|
import _dayjs, { Dayjs } from "dayjs";
|
|
2
|
-
import { searchconsole_v1 } from "@googleapis/searchconsole/v1";
|
|
3
|
-
|
|
4
|
-
//#region src/core/types.d.ts
|
|
5
|
-
|
|
2
|
+
import { searchconsole_v1 } from "@googleapis/searchconsole/build/v1";
|
|
6
3
|
type SearchAnalyticsQuery = searchconsole_v1.Schema$SearchAnalyticsQueryRequest;
|
|
7
|
-
//#endregion
|
|
8
|
-
//#region src/query/utils/countries.d.ts
|
|
9
4
|
declare const _default: {
|
|
10
5
|
name: string;
|
|
11
6
|
'alpha-2': string;
|
|
12
7
|
'alpha-3': string;
|
|
13
8
|
'country-code': string;
|
|
14
9
|
}[];
|
|
15
|
-
//#endregion
|
|
16
|
-
//#region src/query/constants.d.ts
|
|
17
10
|
declare const Devices: {
|
|
18
11
|
readonly MOBILE: "MOBILE";
|
|
19
12
|
readonly DESKTOP: "DESKTOP";
|
|
@@ -25,12 +18,12 @@ declare const SearchTypes: {
|
|
|
25
18
|
readonly IMAGE: "image";
|
|
26
19
|
readonly VIDEO: "video";
|
|
27
20
|
readonly NEWS: "news";
|
|
21
|
+
readonly DISCOVER: "discover";
|
|
22
|
+
readonly GOOGLE_NEWS: "googleNews";
|
|
28
23
|
};
|
|
29
24
|
type SearchType = typeof SearchTypes[keyof typeof SearchTypes];
|
|
30
25
|
declare const Countries: { [K in (typeof _default)[number]["alpha-3"]]: Lowercase<K> };
|
|
31
26
|
type Country = typeof Countries[keyof typeof Countries];
|
|
32
|
-
//#endregion
|
|
33
|
-
//#region src/query/types.d.ts
|
|
34
27
|
interface DimensionValueMap {
|
|
35
28
|
query: string;
|
|
36
29
|
queryCanonical: string;
|
|
@@ -45,14 +38,12 @@ interface QueryParamValueMap {
|
|
|
45
38
|
searchType: SearchType;
|
|
46
39
|
}
|
|
47
40
|
type QueryParamName = keyof QueryParamValueMap;
|
|
48
|
-
declare const ColumnBrand: unique symbol;
|
|
49
41
|
interface Column<D extends Dimension> {
|
|
50
|
-
readonly
|
|
42
|
+
readonly __columnBrand: 'gscdump.Column';
|
|
51
43
|
readonly dimension: D;
|
|
52
44
|
}
|
|
53
|
-
declare const QueryParamBrand: unique symbol;
|
|
54
45
|
interface QueryParam<P extends QueryParamName> {
|
|
55
|
-
readonly
|
|
46
|
+
readonly __queryParamBrand: 'gscdump.QueryParam';
|
|
56
47
|
readonly param: P;
|
|
57
48
|
}
|
|
58
49
|
type FilterOperator = 'equals' | 'notEquals' | 'contains' | 'notContains' | 'includingRegex' | 'excludingRegex';
|
|
@@ -65,16 +56,15 @@ interface InternalFilter {
|
|
|
65
56
|
expression: string;
|
|
66
57
|
expression2?: string;
|
|
67
58
|
}
|
|
68
|
-
declare const FilterBrand: unique symbol;
|
|
69
59
|
interface Filter<C = object> {
|
|
70
|
-
readonly
|
|
60
|
+
readonly __filterBrand: 'gscdump.Filter';
|
|
71
61
|
readonly _constraints: C;
|
|
72
62
|
readonly _filters: InternalFilter[];
|
|
73
63
|
readonly _nestedGroups?: Filter<any>[];
|
|
74
64
|
readonly _groupType?: 'and' | 'or';
|
|
75
65
|
}
|
|
76
66
|
type MergeConstraints<F extends Filter<any>[]> = UnionToIntersection<F[number]['_constraints']>;
|
|
77
|
-
type UnionToIntersection<U
|
|
67
|
+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
|
|
78
68
|
interface GSCResult<D extends Dimension[], C> {
|
|
79
69
|
rows: Array<GSCRow<D, C>>;
|
|
80
70
|
}
|
|
@@ -85,9 +75,8 @@ type GSCRow<D extends Dimension[], C> = { [K in D[number]]: K extends keyof C ?
|
|
|
85
75
|
position: number;
|
|
86
76
|
};
|
|
87
77
|
type Metric = 'clicks' | 'impressions' | 'ctr' | 'position';
|
|
88
|
-
declare const MetricColumnBrand: unique symbol;
|
|
89
78
|
interface MetricColumn<M extends Metric> {
|
|
90
|
-
readonly
|
|
79
|
+
readonly __metricColumnBrand: 'gscdump.MetricColumn';
|
|
91
80
|
readonly metric: M;
|
|
92
81
|
}
|
|
93
82
|
interface BuilderState {
|
|
@@ -113,8 +102,6 @@ interface JsonFilter {
|
|
|
113
102
|
_groupType?: 'and' | 'or';
|
|
114
103
|
}
|
|
115
104
|
type FilterInput = Filter<any> | JsonFilter;
|
|
116
|
-
//#endregion
|
|
117
|
-
//#region src/query/builder.d.ts
|
|
118
105
|
type SelectableColumn = Column<Dimension> | MetricColumn<Metric>;
|
|
119
106
|
type OrderableColumn = MetricColumn<Metric> | Column<'date'>;
|
|
120
107
|
type ExtractDimensions<T extends SelectableColumn[]> = { [K in keyof T]: T[K] extends Column<infer D> ? D : never }[number] extends infer U ? Exclude<U, never>[] : never;
|
|
@@ -131,8 +118,6 @@ interface GSCQueryBuilder<D extends Dimension[] = [], C = object> {
|
|
|
131
118
|
getState: () => BuilderState;
|
|
132
119
|
}
|
|
133
120
|
declare const gsc: GSCQueryBuilder<[], object>;
|
|
134
|
-
//#endregion
|
|
135
|
-
//#region src/query/columns.d.ts
|
|
136
121
|
declare const page: Column<"page">;
|
|
137
122
|
declare const query: Column<"query">;
|
|
138
123
|
declare const queryCanonical: Column<"queryCanonical">;
|
|
@@ -145,8 +130,6 @@ declare const impressions: MetricColumn<"impressions">;
|
|
|
145
130
|
declare const ctr: MetricColumn<"ctr">;
|
|
146
131
|
declare const position: MetricColumn<"position">;
|
|
147
132
|
declare const searchType: QueryParam<"searchType">;
|
|
148
|
-
//#endregion
|
|
149
|
-
//#region src/query/operators.d.ts
|
|
150
133
|
declare function eq<D extends Dimension, V extends DimensionValueMap[D]>(column: Column<D>, value: V): Filter<Record<D, V>>;
|
|
151
134
|
declare function eq<P extends QueryParamName, V extends QueryParamValueMap[P]>(param: QueryParam<P>, value: V): Filter<Record<P, V>>;
|
|
152
135
|
declare function ne<D extends Dimension>(column: Column<D>, value: DimensionValueMap[D]): Filter<object>;
|
|
@@ -169,24 +152,81 @@ declare function lt<D extends Dimension>(column: Column<D>, value: DimensionValu
|
|
|
169
152
|
declare function between<M extends Metric>(column: MetricColumn<M>, start: number, end: number): Filter<object>;
|
|
170
153
|
declare function between<D extends Dimension>(column: Column<D>, start: DimensionValueMap[D], end: DimensionValueMap[D]): Filter<object>;
|
|
171
154
|
declare function topLevel(column: Column<'page'>): Filter<object>;
|
|
172
|
-
|
|
173
|
-
|
|
155
|
+
/** Logical table / dataset identifier. Canonical across query builder + storage engine. */
|
|
156
|
+
type TableName = 'pages' | 'keywords' | 'countries' | 'devices' | 'page_keywords' | 'search_appearance';
|
|
157
|
+
type LogicalDataset = TableName;
|
|
158
|
+
type ComparisonFilter = 'new' | 'lost' | 'improving' | 'declining';
|
|
159
|
+
interface PlannerCapabilities {
|
|
160
|
+
regex?: boolean;
|
|
161
|
+
multiDataset?: boolean;
|
|
162
|
+
comparisonJoin?: boolean;
|
|
163
|
+
windowTotals?: boolean;
|
|
164
|
+
}
|
|
165
|
+
interface LogicalDimensionFilter {
|
|
166
|
+
dimension: Dimension;
|
|
167
|
+
operator: FilterOperator;
|
|
168
|
+
expression: string;
|
|
169
|
+
expression2?: string;
|
|
170
|
+
}
|
|
171
|
+
interface LogicalMetricFilter {
|
|
172
|
+
metric: Metric;
|
|
173
|
+
operator: MetricOperator;
|
|
174
|
+
expression: number;
|
|
175
|
+
expression2?: number;
|
|
176
|
+
}
|
|
177
|
+
interface LogicalFilterLeaf {
|
|
178
|
+
kind: 'leaf';
|
|
179
|
+
filter: LogicalDimensionFilter;
|
|
180
|
+
}
|
|
181
|
+
interface LogicalFilterGroup {
|
|
182
|
+
kind: 'group';
|
|
183
|
+
groupType: 'and' | 'or';
|
|
184
|
+
children: LogicalFilterNode[];
|
|
185
|
+
}
|
|
186
|
+
type LogicalFilterNode = LogicalFilterLeaf | LogicalFilterGroup;
|
|
187
|
+
interface LogicalQueryPlan {
|
|
188
|
+
dataset: LogicalDataset;
|
|
189
|
+
dimensions: Dimension[];
|
|
190
|
+
groupByDimensions: Dimension[];
|
|
191
|
+
hasDate: boolean;
|
|
192
|
+
metrics: Metric[];
|
|
193
|
+
dateRange: {
|
|
194
|
+
startDate: string;
|
|
195
|
+
endDate: string;
|
|
196
|
+
};
|
|
197
|
+
dimensionFilters: LogicalDimensionFilter[];
|
|
198
|
+
dimensionFilterTree?: LogicalFilterNode;
|
|
199
|
+
metricFilters: LogicalMetricFilter[];
|
|
200
|
+
specialFilters: {
|
|
201
|
+
topLevel: boolean;
|
|
202
|
+
};
|
|
203
|
+
queryParams: Partial<Record<QueryParamName, string>>;
|
|
204
|
+
orderBy?: BuilderState['orderBy'];
|
|
205
|
+
rowLimit?: number;
|
|
206
|
+
startRow?: number;
|
|
207
|
+
}
|
|
208
|
+
interface LogicalComparisonPlan {
|
|
209
|
+
current: LogicalQueryPlan;
|
|
210
|
+
previous: LogicalQueryPlan;
|
|
211
|
+
comparisonFilter?: ComparisonFilter;
|
|
212
|
+
}
|
|
213
|
+
declare class UnsupportedLogicalCapabilityError extends Error {
|
|
214
|
+
constructor(capability: keyof PlannerCapabilities, context: string);
|
|
215
|
+
}
|
|
216
|
+
declare function buildLogicalPlan(state: BuilderState, capabilities?: PlannerCapabilities): LogicalQueryPlan;
|
|
217
|
+
declare function buildLogicalComparisonPlan(current: BuilderState, previous: BuilderState, capabilities?: PlannerCapabilities, comparisonFilter?: ComparisonFilter): LogicalComparisonPlan;
|
|
174
218
|
declare function isJsonFilter(value: unknown): value is JsonFilter;
|
|
175
219
|
declare function parseJsonFilter(json: JsonFilter): Filter<any>;
|
|
220
|
+
declare function normalizeFilter(input?: FilterInput): Filter<any> | undefined;
|
|
176
221
|
declare function extractDateRange(input?: FilterInput): {
|
|
177
222
|
startDate?: string;
|
|
178
223
|
endDate?: string;
|
|
179
224
|
};
|
|
180
225
|
declare function extractMetricFilters(input?: FilterInput): InternalFilter[];
|
|
181
226
|
declare function extractSpecialOperatorFilters(input?: FilterInput): InternalFilter[];
|
|
182
|
-
//#endregion
|
|
183
|
-
//#region src/query/utils/dayjs.d.ts
|
|
184
227
|
declare function dayjs(date?: _dayjs.ConfigType): Dayjs;
|
|
185
228
|
declare function currentPstDate(): string;
|
|
186
229
|
declare function dayjsPst(): Dayjs;
|
|
187
|
-
//#endregion
|
|
188
|
-
//#region src/query/index.d.ts
|
|
189
230
|
declare function today(): string;
|
|
190
231
|
declare function daysAgo(n: number): string;
|
|
191
|
-
|
|
192
|
-
export { type BuilderState, type Column, Countries, type Country, type Device, Devices, type Dimension, type DimensionValueMap, type Filter, type FilterInput, type GSCQueryBuilder, type GSCResult, type GSCRow, type InternalFilter, type JsonFilter, type JsonInternalFilter, type Metric, type MetricColumn, type QueryParam, type QueryParamName, type QueryParamValueMap, type SearchType, SearchTypes, and, between, clicks, contains, country, ctr, currentPstDate, date, dayjs, dayjsPst, daysAgo, device, eq, extractDateRange, extractMetricFilters, extractSpecialOperatorFilters, gsc, gt, gte, impressions, inArray, isJsonFilter, like, lt, lte, ne, not, notRegex, or, page, parseJsonFilter, position, query, queryCanonical, regex, searchAppearance, searchType, today, topLevel };
|
|
232
|
+
export { type BuilderState, type Column, type ComparisonFilter, Countries, type Country, type Device, Devices, type Dimension, type DimensionValueMap, type Filter, type FilterInput, type GSCQueryBuilder, type GSCResult, type GSCRow, type InternalFilter, type JsonFilter, type JsonInternalFilter, type LogicalComparisonPlan, type LogicalDataset, type LogicalDimensionFilter, type LogicalMetricFilter, type LogicalQueryPlan, type Metric, type MetricColumn, type PlannerCapabilities, type QueryParam, type QueryParamName, type QueryParamValueMap, type SearchType, SearchTypes, UnsupportedLogicalCapabilityError, and, between, buildLogicalComparisonPlan, buildLogicalPlan, clicks, contains, country, ctr, currentPstDate, date, dayjs, dayjsPst, daysAgo, device, eq, extractDateRange, extractMetricFilters, extractSpecialOperatorFilters, gsc, gt, gte, impressions, inArray, isJsonFilter, like, lt, lte, ne, normalizeFilter, not, notRegex, or, page, parseJsonFilter, position, query, queryCanonical, regex, searchAppearance, searchType, today, topLevel };
|