gscdump 0.17.0 → 0.17.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.
@@ -245,9 +245,16 @@ declare function extractDateRange(input?: FilterInput): {
245
245
  };
246
246
  declare function extractMetricFilters(input?: FilterInput): InternalFilter[];
247
247
  declare function extractSpecialOperatorFilters(input?: FilterInput): InternalFilter[];
248
+ /**
249
+ * Pull `searchType` out of a BuilderState filter. Returns undefined for
250
+ * missing/invalid shapes — callers treat that as "no scope" (cross-type read).
251
+ * Validated against the canonical `SearchTypes` set so unknown strings
252
+ * don't reach the engine.
253
+ */
254
+ declare function extractSearchType(state: BuilderState | undefined | null): SearchType | undefined;
248
255
  declare function dayjs(date?: _dayjs.ConfigType): Dayjs;
249
256
  declare function currentPstDate(): string;
250
257
  declare function dayjsPst(): Dayjs;
251
258
  declare function today(): string;
252
259
  declare function daysAgo(n: number): string;
253
- 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 };
260
+ 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, extractSearchType, 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 };
@@ -19,303 +19,6 @@ function toIsoDate(d) {
19
19
  function addDays(dateStr, n) {
20
20
  return toIsoDate(new Date(Date.parse(`${dateStr}T00:00:00Z`) + n * MS_PER_DAY));
21
21
  }
22
- const DATE_OPERATORS = [
23
- "gte",
24
- "gt",
25
- "lte",
26
- "lt",
27
- "between"
28
- ];
29
- const METRIC_OPERATORS = [
30
- "metricGte",
31
- "metricGt",
32
- "metricLte",
33
- "metricLt",
34
- "metricBetween"
35
- ];
36
- const SPECIAL_OPERATORS = ["topLevel"];
37
- const QUERY_PARAMS = ["searchType"];
38
- const FILTER_METRICS = [
39
- "clicks",
40
- "impressions",
41
- "ctr",
42
- "position"
43
- ];
44
- function isDateOperator(op) {
45
- return DATE_OPERATORS.includes(op);
46
- }
47
- function isMetricOperator(op) {
48
- return METRIC_OPERATORS.includes(op);
49
- }
50
- function isSpecialOperator(op) {
51
- return SPECIAL_OPERATORS.includes(op);
52
- }
53
- function isQueryParam(value) {
54
- return QUERY_PARAMS.includes(value);
55
- }
56
- function isMetric(value) {
57
- return FILTER_METRICS.includes(value);
58
- }
59
- function isRegexOperator(op) {
60
- return op === "includingRegex" || op === "excludingRegex";
61
- }
62
- function isJsonFilter(value) {
63
- return typeof value === "object" && value !== null && "_filters" in value && Array.isArray(value._filters);
64
- }
65
- function parseJsonFilter(json) {
66
- return {
67
- _constraints: {},
68
- _filters: json._filters.map((f) => ({
69
- dimension: f.dimension,
70
- operator: f.operator,
71
- expression: f.expression,
72
- expression2: f.expression2
73
- })),
74
- _nestedGroups: json._nestedGroups?.map(parseJsonFilter),
75
- _groupType: json._groupType
76
- };
77
- }
78
- function isWireGroupType(type) {
79
- return type === "and" || type === "or";
80
- }
81
- function convertWireLeaf(alt) {
82
- if (!alt.column || !alt.type || isWireGroupType(alt.type)) return null;
83
- const f = {
84
- dimension: alt.column,
85
- operator: alt.type,
86
- expression: alt.type === "between" ? alt.from ?? "" : alt.value ?? ""
87
- };
88
- if (alt.type === "between" && alt.to) f.expression2 = alt.to;
89
- return f;
90
- }
91
- function convertWireGroup(alt) {
92
- if (!isWireGroupType(alt.type)) {
93
- const leaf = convertWireLeaf(alt);
94
- return leaf ? { _filters: [leaf] } : null;
95
- }
96
- const leaves = [];
97
- const nested = [];
98
- for (const child of alt.filters ?? []) if (isWireGroupType(child.type)) {
99
- const sub = convertWireGroup(child);
100
- if (sub) nested.push(sub);
101
- } else {
102
- const leaf = convertWireLeaf(child);
103
- if (leaf) leaves.push(leaf);
104
- }
105
- if (leaves.length === 0 && nested.length === 0) return null;
106
- return {
107
- _filters: leaves,
108
- _nestedGroups: nested.length > 0 ? nested : void 0,
109
- _groupType: alt.type
110
- };
111
- }
112
- function isWireFilter(input) {
113
- if (!input || typeof input !== "object") return false;
114
- const o = input;
115
- if ("_filters" in o) return false;
116
- return "type" in o && typeof o.type === "string" || "filters" in o && Array.isArray(o.filters);
117
- }
118
- function normalizeFilter(input) {
119
- if (!input) return void 0;
120
- if (isWireFilter(input)) return convertWireGroup(input) ?? void 0;
121
- return input;
122
- }
123
- function extractSpecialFilters(filter) {
124
- if (!filter) return {};
125
- let startDate;
126
- let endDate;
127
- let searchType;
128
- const otherFilters = [];
129
- const cleanedNestedGroups = [];
130
- for (const f of filter._filters) if (f.dimension === "date" && isDateOperator(f.operator)) switch (f.operator) {
131
- case "gte":
132
- startDate = f.expression;
133
- break;
134
- case "gt":
135
- startDate = addDays(f.expression, 1);
136
- break;
137
- case "lte":
138
- endDate = f.expression;
139
- break;
140
- case "lt":
141
- endDate = addDays(f.expression, -1);
142
- break;
143
- case "between":
144
- startDate = f.expression;
145
- endDate = f.expression2;
146
- break;
147
- }
148
- else if (isQueryParam(f.dimension)) {
149
- if (f.dimension === "searchType") searchType = f.expression;
150
- } else if (isMetricOperator(f.operator) || isSpecialOperator(f.operator)) otherFilters.push(f);
151
- else otherFilters.push(f);
152
- if (filter._nestedGroups) for (const nested of filter._nestedGroups) {
153
- const extracted = extractSpecialFilters(nested);
154
- if (extracted.startDate) startDate = extracted.startDate;
155
- if (extracted.endDate) endDate = extracted.endDate;
156
- if (extracted.searchType) searchType = extracted.searchType;
157
- if (extracted.dimensionFilter) cleanedNestedGroups.push(extracted.dimensionFilter);
158
- }
159
- const dimensionFilter = otherFilters.length > 0 || cleanedNestedGroups.length > 0 ? {
160
- ...filter,
161
- _filters: otherFilters,
162
- _nestedGroups: cleanedNestedGroups.length > 0 ? cleanedNestedGroups : void 0
163
- } : void 0;
164
- return {
165
- startDate,
166
- endDate,
167
- searchType,
168
- dimensionFilter
169
- };
170
- }
171
- function extractDateRange(input) {
172
- const { startDate, endDate } = extractSpecialFilters(normalizeFilter(input));
173
- return {
174
- startDate,
175
- endDate
176
- };
177
- }
178
- function extractMetricFilters(input) {
179
- const filter = normalizeFilter(input);
180
- if (!filter) return [];
181
- const metricFilters = filter._filters.filter((f) => isMetricOperator(f.operator));
182
- const nested = filter._nestedGroups?.flatMap((g) => extractMetricFilters(g)) ?? [];
183
- return [...metricFilters, ...nested];
184
- }
185
- function extractSpecialOperatorFilters(input) {
186
- const filter = normalizeFilter(input);
187
- if (!filter) return [];
188
- const special = filter._filters.filter((f) => isSpecialOperator(f.operator));
189
- const nested = filter._nestedGroups?.flatMap((g) => extractSpecialOperatorFilters(g)) ?? [];
190
- return [...special, ...nested];
191
- }
192
- function resolveToBody(state) {
193
- const { startDate, endDate, searchType, dimensionFilter } = extractSpecialFilters(state.filter);
194
- if (!startDate || !endDate) throw new Error("Date range required: use .where(between(date, start, end)) or .where(and(gte(date, start), lte(date, end)))");
195
- const body = {
196
- dimensions: state.dimensions,
197
- startDate,
198
- endDate
199
- };
200
- if (searchType) body.searchType = searchType;
201
- if (state.rowLimit) body.rowLimit = state.rowLimit;
202
- if (state.startRow) body.startRow = state.startRow;
203
- const filterGroups = resolveFilter(dimensionFilter);
204
- if (filterGroups.length > 0) body.dimensionFilterGroups = filterGroups;
205
- return body;
206
- }
207
- function isApiFilter(f) {
208
- return !isMetricOperator(f.operator) && !isSpecialOperator(f.operator);
209
- }
210
- function resolveFilter(filter) {
211
- if (!filter) return [];
212
- const groups = [];
213
- const groupType = filter._groupType ?? "and";
214
- const apiFilters = filter._filters.filter(isApiFilter);
215
- if (groupType === "or") {
216
- if (apiFilters.length > 0) groups.push({
217
- groupType: "or",
218
- filters: apiFilters.map((f) => ({
219
- dimension: f.dimension,
220
- operator: f.operator,
221
- expression: f.expression
222
- }))
223
- });
224
- } else if (apiFilters.length > 0) groups.push({ filters: apiFilters.map((f) => ({
225
- dimension: f.dimension,
226
- operator: f.operator,
227
- expression: f.expression
228
- })) });
229
- if (filter._nestedGroups) for (const nested of filter._nestedGroups) groups.push(...resolveFilter(nested));
230
- return groups;
231
- }
232
- function isDimensionString(v) {
233
- return typeof v === "string";
234
- }
235
- function isMetricColumn(v) {
236
- return typeof v === "object" && v !== null && "metric" in v;
237
- }
238
- function isDimensionColumn(v) {
239
- return typeof v === "object" && v !== null && "dimension" in v && !("metric" in v);
240
- }
241
- function createBuilder(state) {
242
- return {
243
- select(...args) {
244
- const dimensions = [];
245
- const metrics = [];
246
- for (const arg of args) if (isDimensionString(arg)) dimensions.push(arg);
247
- else if (isDimensionColumn(arg)) dimensions.push(arg.dimension);
248
- else if (isMetricColumn(arg)) metrics.push(arg.metric);
249
- return createBuilder({
250
- ...state,
251
- dimensions,
252
- metrics: metrics.length > 0 ? metrics : void 0
253
- });
254
- },
255
- where(filter) {
256
- return createBuilder({
257
- ...state,
258
- filter
259
- });
260
- },
261
- prefilter(filter) {
262
- return createBuilder({
263
- ...state,
264
- prefilter: filter
265
- });
266
- },
267
- orderBy(col, dir) {
268
- const column = isMetricColumn(col) ? col.metric : col.dimension;
269
- return createBuilder({
270
- ...state,
271
- orderBy: {
272
- column,
273
- dir
274
- }
275
- });
276
- },
277
- limit(n) {
278
- return createBuilder({
279
- ...state,
280
- rowLimit: n
281
- });
282
- },
283
- offset(n) {
284
- return createBuilder({
285
- ...state,
286
- startRow: n
287
- });
288
- },
289
- toBody() {
290
- return resolveToBody(state);
291
- },
292
- getState() {
293
- return { ...state };
294
- }
295
- };
296
- }
297
- const gsc = createBuilder({ dimensions: [] });
298
- function createColumn(dimension) {
299
- return { dimension };
300
- }
301
- function createMetricColumn(metric) {
302
- return { metric };
303
- }
304
- function createQueryParam(param) {
305
- return { param };
306
- }
307
- const page = createColumn("page");
308
- const query = createColumn("query");
309
- const queryCanonical = createColumn("queryCanonical");
310
- const device = createColumn("device");
311
- const country = createColumn("country");
312
- const searchAppearance = createColumn("searchAppearance");
313
- const date = createColumn("date");
314
- const clicks = createMetricColumn("clicks");
315
- const impressions = createMetricColumn("impressions");
316
- const ctr = createMetricColumn("ctr");
317
- const position = createMetricColumn("position");
318
- const searchType = createQueryParam("searchType");
319
22
  var countries_default = [
320
23
  {
321
24
  "name": "Afghanistan",
@@ -1811,21 +1514,327 @@ var countries_default = [
1811
1514
  "alpha-3": "ZWE",
1812
1515
  "country-code": "716"
1813
1516
  }
1814
- ];
1815
- const Devices = {
1816
- MOBILE: "MOBILE",
1817
- DESKTOP: "DESKTOP",
1818
- TABLET: "TABLET"
1819
- };
1820
- const SearchTypes = {
1821
- WEB: "web",
1822
- IMAGE: "image",
1823
- VIDEO: "video",
1824
- NEWS: "news",
1825
- DISCOVER: "discover",
1826
- GOOGLE_NEWS: "googleNews"
1827
- };
1828
- const Countries = Object.fromEntries(countries_default.map((c) => [c["alpha-3"], c["alpha-3"].toLowerCase()]));
1517
+ ];
1518
+ const Devices = {
1519
+ MOBILE: "MOBILE",
1520
+ DESKTOP: "DESKTOP",
1521
+ TABLET: "TABLET"
1522
+ };
1523
+ const SearchTypes = {
1524
+ WEB: "web",
1525
+ IMAGE: "image",
1526
+ VIDEO: "video",
1527
+ NEWS: "news",
1528
+ DISCOVER: "discover",
1529
+ GOOGLE_NEWS: "googleNews"
1530
+ };
1531
+ const Countries = Object.fromEntries(countries_default.map((c) => [c["alpha-3"], c["alpha-3"].toLowerCase()]));
1532
+ const DATE_OPERATORS = [
1533
+ "gte",
1534
+ "gt",
1535
+ "lte",
1536
+ "lt",
1537
+ "between"
1538
+ ];
1539
+ const METRIC_OPERATORS = [
1540
+ "metricGte",
1541
+ "metricGt",
1542
+ "metricLte",
1543
+ "metricLt",
1544
+ "metricBetween"
1545
+ ];
1546
+ const SPECIAL_OPERATORS = ["topLevel"];
1547
+ const QUERY_PARAMS = ["searchType"];
1548
+ const FILTER_METRICS = [
1549
+ "clicks",
1550
+ "impressions",
1551
+ "ctr",
1552
+ "position"
1553
+ ];
1554
+ function isDateOperator(op) {
1555
+ return DATE_OPERATORS.includes(op);
1556
+ }
1557
+ function isMetricOperator(op) {
1558
+ return METRIC_OPERATORS.includes(op);
1559
+ }
1560
+ function isSpecialOperator(op) {
1561
+ return SPECIAL_OPERATORS.includes(op);
1562
+ }
1563
+ function isQueryParam(value) {
1564
+ return QUERY_PARAMS.includes(value);
1565
+ }
1566
+ function isMetric(value) {
1567
+ return FILTER_METRICS.includes(value);
1568
+ }
1569
+ function isRegexOperator(op) {
1570
+ return op === "includingRegex" || op === "excludingRegex";
1571
+ }
1572
+ const KNOWN_SEARCH_TYPES = new Set(Object.values(SearchTypes));
1573
+ function isJsonFilter(value) {
1574
+ return typeof value === "object" && value !== null && "_filters" in value && Array.isArray(value._filters);
1575
+ }
1576
+ function parseJsonFilter(json) {
1577
+ return {
1578
+ _constraints: {},
1579
+ _filters: json._filters.map((f) => ({
1580
+ dimension: f.dimension,
1581
+ operator: f.operator,
1582
+ expression: f.expression,
1583
+ expression2: f.expression2
1584
+ })),
1585
+ _nestedGroups: json._nestedGroups?.map(parseJsonFilter),
1586
+ _groupType: json._groupType
1587
+ };
1588
+ }
1589
+ function isWireGroupType(type) {
1590
+ return type === "and" || type === "or";
1591
+ }
1592
+ function convertWireLeaf(alt) {
1593
+ if (!alt.column || !alt.type || isWireGroupType(alt.type)) return null;
1594
+ const f = {
1595
+ dimension: alt.column,
1596
+ operator: alt.type,
1597
+ expression: alt.type === "between" ? alt.from ?? "" : alt.value ?? ""
1598
+ };
1599
+ if (alt.type === "between" && alt.to) f.expression2 = alt.to;
1600
+ return f;
1601
+ }
1602
+ function convertWireGroup(alt) {
1603
+ if (!isWireGroupType(alt.type)) {
1604
+ const leaf = convertWireLeaf(alt);
1605
+ return leaf ? { _filters: [leaf] } : null;
1606
+ }
1607
+ const leaves = [];
1608
+ const nested = [];
1609
+ for (const child of alt.filters ?? []) if (isWireGroupType(child.type)) {
1610
+ const sub = convertWireGroup(child);
1611
+ if (sub) nested.push(sub);
1612
+ } else {
1613
+ const leaf = convertWireLeaf(child);
1614
+ if (leaf) leaves.push(leaf);
1615
+ }
1616
+ if (leaves.length === 0 && nested.length === 0) return null;
1617
+ return {
1618
+ _filters: leaves,
1619
+ _nestedGroups: nested.length > 0 ? nested : void 0,
1620
+ _groupType: alt.type
1621
+ };
1622
+ }
1623
+ function isWireFilter(input) {
1624
+ if (!input || typeof input !== "object") return false;
1625
+ const o = input;
1626
+ if ("_filters" in o) return false;
1627
+ return "type" in o && typeof o.type === "string" || "filters" in o && Array.isArray(o.filters);
1628
+ }
1629
+ function normalizeFilter(input) {
1630
+ if (!input) return void 0;
1631
+ if (isWireFilter(input)) return convertWireGroup(input) ?? void 0;
1632
+ return input;
1633
+ }
1634
+ function extractSpecialFilters(filter) {
1635
+ if (!filter) return {};
1636
+ let startDate;
1637
+ let endDate;
1638
+ let searchType;
1639
+ const otherFilters = [];
1640
+ const cleanedNestedGroups = [];
1641
+ for (const f of filter._filters) if (f.dimension === "date" && isDateOperator(f.operator)) switch (f.operator) {
1642
+ case "gte":
1643
+ startDate = f.expression;
1644
+ break;
1645
+ case "gt":
1646
+ startDate = addDays(f.expression, 1);
1647
+ break;
1648
+ case "lte":
1649
+ endDate = f.expression;
1650
+ break;
1651
+ case "lt":
1652
+ endDate = addDays(f.expression, -1);
1653
+ break;
1654
+ case "between":
1655
+ startDate = f.expression;
1656
+ endDate = f.expression2;
1657
+ break;
1658
+ }
1659
+ else if (isQueryParam(f.dimension)) {
1660
+ if (f.dimension === "searchType") searchType = f.expression;
1661
+ } else if (isMetricOperator(f.operator) || isSpecialOperator(f.operator)) otherFilters.push(f);
1662
+ else otherFilters.push(f);
1663
+ if (filter._nestedGroups) for (const nested of filter._nestedGroups) {
1664
+ const extracted = extractSpecialFilters(nested);
1665
+ if (extracted.startDate) startDate = extracted.startDate;
1666
+ if (extracted.endDate) endDate = extracted.endDate;
1667
+ if (extracted.searchType) searchType = extracted.searchType;
1668
+ if (extracted.dimensionFilter) cleanedNestedGroups.push(extracted.dimensionFilter);
1669
+ }
1670
+ const dimensionFilter = otherFilters.length > 0 || cleanedNestedGroups.length > 0 ? {
1671
+ ...filter,
1672
+ _filters: otherFilters,
1673
+ _nestedGroups: cleanedNestedGroups.length > 0 ? cleanedNestedGroups : void 0
1674
+ } : void 0;
1675
+ return {
1676
+ startDate,
1677
+ endDate,
1678
+ searchType,
1679
+ dimensionFilter
1680
+ };
1681
+ }
1682
+ function extractDateRange(input) {
1683
+ const { startDate, endDate } = extractSpecialFilters(normalizeFilter(input));
1684
+ return {
1685
+ startDate,
1686
+ endDate
1687
+ };
1688
+ }
1689
+ function extractMetricFilters(input) {
1690
+ const filter = normalizeFilter(input);
1691
+ if (!filter) return [];
1692
+ const metricFilters = filter._filters.filter((f) => isMetricOperator(f.operator));
1693
+ const nested = filter._nestedGroups?.flatMap((g) => extractMetricFilters(g)) ?? [];
1694
+ return [...metricFilters, ...nested];
1695
+ }
1696
+ function extractSpecialOperatorFilters(input) {
1697
+ const filter = normalizeFilter(input);
1698
+ if (!filter) return [];
1699
+ const special = filter._filters.filter((f) => isSpecialOperator(f.operator));
1700
+ const nested = filter._nestedGroups?.flatMap((g) => extractSpecialOperatorFilters(g)) ?? [];
1701
+ return [...special, ...nested];
1702
+ }
1703
+ function extractSearchType(state) {
1704
+ if (!state) return void 0;
1705
+ const filter = state.filter;
1706
+ if (!filter || typeof filter !== "object") return void 0;
1707
+ const raw = filter.searchType;
1708
+ if (typeof raw !== "string" || raw.length === 0) return void 0;
1709
+ return KNOWN_SEARCH_TYPES.has(raw) ? raw : void 0;
1710
+ }
1711
+ function resolveToBody(state) {
1712
+ const { startDate, endDate, searchType, dimensionFilter } = extractSpecialFilters(state.filter);
1713
+ if (!startDate || !endDate) throw new Error("Date range required: use .where(between(date, start, end)) or .where(and(gte(date, start), lte(date, end)))");
1714
+ const body = {
1715
+ dimensions: state.dimensions,
1716
+ startDate,
1717
+ endDate
1718
+ };
1719
+ if (searchType) body.searchType = searchType;
1720
+ if (state.rowLimit) body.rowLimit = state.rowLimit;
1721
+ if (state.startRow) body.startRow = state.startRow;
1722
+ const filterGroups = resolveFilter(dimensionFilter);
1723
+ if (filterGroups.length > 0) body.dimensionFilterGroups = filterGroups;
1724
+ return body;
1725
+ }
1726
+ function isApiFilter(f) {
1727
+ return !isMetricOperator(f.operator) && !isSpecialOperator(f.operator);
1728
+ }
1729
+ function resolveFilter(filter) {
1730
+ if (!filter) return [];
1731
+ const groups = [];
1732
+ const groupType = filter._groupType ?? "and";
1733
+ const apiFilters = filter._filters.filter(isApiFilter);
1734
+ if (groupType === "or") {
1735
+ if (apiFilters.length > 0) groups.push({
1736
+ groupType: "or",
1737
+ filters: apiFilters.map((f) => ({
1738
+ dimension: f.dimension,
1739
+ operator: f.operator,
1740
+ expression: f.expression
1741
+ }))
1742
+ });
1743
+ } else if (apiFilters.length > 0) groups.push({ filters: apiFilters.map((f) => ({
1744
+ dimension: f.dimension,
1745
+ operator: f.operator,
1746
+ expression: f.expression
1747
+ })) });
1748
+ if (filter._nestedGroups) for (const nested of filter._nestedGroups) groups.push(...resolveFilter(nested));
1749
+ return groups;
1750
+ }
1751
+ function isDimensionString(v) {
1752
+ return typeof v === "string";
1753
+ }
1754
+ function isMetricColumn(v) {
1755
+ return typeof v === "object" && v !== null && "metric" in v;
1756
+ }
1757
+ function isDimensionColumn(v) {
1758
+ return typeof v === "object" && v !== null && "dimension" in v && !("metric" in v);
1759
+ }
1760
+ function createBuilder(state) {
1761
+ return {
1762
+ select(...args) {
1763
+ const dimensions = [];
1764
+ const metrics = [];
1765
+ for (const arg of args) if (isDimensionString(arg)) dimensions.push(arg);
1766
+ else if (isDimensionColumn(arg)) dimensions.push(arg.dimension);
1767
+ else if (isMetricColumn(arg)) metrics.push(arg.metric);
1768
+ return createBuilder({
1769
+ ...state,
1770
+ dimensions,
1771
+ metrics: metrics.length > 0 ? metrics : void 0
1772
+ });
1773
+ },
1774
+ where(filter) {
1775
+ return createBuilder({
1776
+ ...state,
1777
+ filter
1778
+ });
1779
+ },
1780
+ prefilter(filter) {
1781
+ return createBuilder({
1782
+ ...state,
1783
+ prefilter: filter
1784
+ });
1785
+ },
1786
+ orderBy(col, dir) {
1787
+ const column = isMetricColumn(col) ? col.metric : col.dimension;
1788
+ return createBuilder({
1789
+ ...state,
1790
+ orderBy: {
1791
+ column,
1792
+ dir
1793
+ }
1794
+ });
1795
+ },
1796
+ limit(n) {
1797
+ return createBuilder({
1798
+ ...state,
1799
+ rowLimit: n
1800
+ });
1801
+ },
1802
+ offset(n) {
1803
+ return createBuilder({
1804
+ ...state,
1805
+ startRow: n
1806
+ });
1807
+ },
1808
+ toBody() {
1809
+ return resolveToBody(state);
1810
+ },
1811
+ getState() {
1812
+ return { ...state };
1813
+ }
1814
+ };
1815
+ }
1816
+ const gsc = createBuilder({ dimensions: [] });
1817
+ function createColumn(dimension) {
1818
+ return { dimension };
1819
+ }
1820
+ function createMetricColumn(metric) {
1821
+ return { metric };
1822
+ }
1823
+ function createQueryParam(param) {
1824
+ return { param };
1825
+ }
1826
+ const page = createColumn("page");
1827
+ const query = createColumn("query");
1828
+ const queryCanonical = createColumn("queryCanonical");
1829
+ const device = createColumn("device");
1830
+ const country = createColumn("country");
1831
+ const searchAppearance = createColumn("searchAppearance");
1832
+ const date = createColumn("date");
1833
+ const clicks = createMetricColumn("clicks");
1834
+ const impressions = createMetricColumn("impressions");
1835
+ const ctr = createMetricColumn("ctr");
1836
+ const position = createMetricColumn("position");
1837
+ const searchType = createQueryParam("searchType");
1829
1838
  function leafFilter(dimension, operator, expression, expression2) {
1830
1839
  const filter = {
1831
1840
  dimension,
@@ -2076,4 +2085,4 @@ function today() {
2076
2085
  function daysAgo(n) {
2077
2086
  return dayjsPst().subtract(n, "day").format("YYYY-MM-DD");
2078
2087
  }
2079
- export { Countries, Devices, 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 };
2088
+ export { Countries, Devices, SearchTypes, UnsupportedLogicalCapabilityError, and, between, buildLogicalComparisonPlan, buildLogicalPlan, clicks, contains, country, ctr, currentPstDate, date, dayjs, dayjsPst, daysAgo, device, eq, extractDateRange, extractMetricFilters, extractSearchType, 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 };