gscdump 0.1.1 → 0.1.3

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 CHANGED
@@ -23,8 +23,8 @@ npm install gscdump
23
23
  ## Usage
24
24
 
25
25
  ```ts
26
- import { daysAgo, today } from '@gscdump/query'
27
26
  import { fetchKeywordsWithComparison, fetchPagesWithComparison } from 'gscdump'
27
+ import { daysAgo, today } from 'gscdump/query'
28
28
 
29
29
  // Auth accepts token string or object
30
30
  const auth = 'ya29.xxx...'
@@ -64,16 +64,16 @@ for await (const batch of queryRecursiveStream(client, site, {
64
64
  Drizzle-style query builder with full type safety. Filter constraints flow through to result types.
65
65
 
66
66
  ```ts
67
- import { and, contains, country, Country, device, Device, eq, gsc, inArray, page } from 'gscdump/query'
67
+ import { and, between, contains, country, Country, date, device, Device, eq, gsc, inArray, page } from 'gscdump/query'
68
68
 
69
69
  const result = await gsc
70
70
  .select('page', 'query', 'device', 'country')
71
71
  .where(and(
72
72
  eq(device, Device.MOBILE),
73
73
  inArray(country, [Country.USA, Country.GBR]),
74
- contains(page, '/blog/')
74
+ contains(page, '/blog/'),
75
+ between(date, '2024-01-01', '2024-01-31')
75
76
  ))
76
- .period('2024-01-01', '2024-01-31')
77
77
  .siteUrl('https://example.com')
78
78
  .execute(client)
79
79
 
@@ -84,6 +84,20 @@ result.rows[0].page // type: string (contains doesn't narrow)
84
84
  result.rows[0].clicks // type: number
85
85
  ```
86
86
 
87
+ **With date helpers:**
88
+
89
+ ```ts
90
+ import { and, between, date, daysAgo, gsc, query, regex, today } from 'gscdump/query'
91
+
92
+ const q = gsc
93
+ .select('query', 'page')
94
+ .where(and(
95
+ between(date, daysAgo(28), today()),
96
+ regex(query, /how to/)
97
+ ))
98
+ .limit(100)
99
+ ```
100
+
87
101
  **Operators:**
88
102
 
89
103
  | Operator | Narrows Type? | Description |
@@ -94,6 +108,12 @@ result.rows[0].clicks // type: number
94
108
  | `contains(col, str)` | ✗ | String contains |
95
109
  | `like(col, '%pattern%')` | ✗ | SQL LIKE pattern |
96
110
  | `regex(col, /pattern/)` | ✗ | Regex match |
111
+ | `notRegex(col, /pattern/)` | ✗ | Regex exclusion |
112
+ | `between(col, start, end)` | ✗ | Inclusive range (primarily for date) |
113
+ | `gte(col, val)` | ✗ | Greater than or equal |
114
+ | `lte(col, val)` | ✗ | Less than or equal |
115
+ | `gt(col, val)` | ✗ | Greater than |
116
+ | `lt(col, val)` | ✗ | Less than |
97
117
  | `and(...filters)` | ✓ | Merge constraints |
98
118
  | `or(...filters)` | ✗ | Any match |
99
119
  | `not(filter)` | ✗ | Invert filter |
@@ -133,7 +153,7 @@ const cannibalization = analyzeCannibalization(keywordPageData)
133
153
 
134
154
  **Low-level:** `gscClient`, `queryRecursive`, `queryRecursiveStream`, `createQueryBody`, `withPropertyAggregation`, `withSearchAppearance`, `withDataType`, `withFreshData`, `withFinalData`
135
155
 
136
- **Query Builder (`gscdump/query`):** `gsc`, `eq`, `ne`, `and`, `or`, `inArray`, `contains`, `like`, `regex`, `notRegex`, `not`, `page`, `query`, `device`, `country`, `searchAppearance`, `Device`, `Country`
156
+ **Query Builder (`gscdump/query`):** `gsc`, `eq`, `ne`, `and`, `or`, `inArray`, `contains`, `like`, `regex`, `notRegex`, `not`, `between`, `gte`, `gt`, `lte`, `lt`, `page`, `query`, `device`, `country`, `date`, `searchAppearance`, `Device`, `Country`, `today`, `daysAgo`
137
157
 
138
158
  **Error Utilities:** `isQuotaError`, `isRateLimitError`, `isAuthError`, `getErrorCode`, `getErrorMessage`, `getRetryAfter`, `analyzeGscError`, `formatGscErrorForCli`
139
159
 
package/dist/index.d.mts CHANGED
@@ -1100,6 +1100,7 @@ interface BuilderState {
1100
1100
  filters: Filter<any>[];
1101
1101
  siteUrl?: string;
1102
1102
  rowLimit?: number;
1103
+ startRow?: number;
1103
1104
  }
1104
1105
  //#endregion
1105
1106
  //#region src/query/builder.d.ts
@@ -1108,6 +1109,7 @@ interface GSCQueryBuilder<D extends Dimension[] = [], C = object> {
1108
1109
  where: <F extends Filter<any>>(filter: F) => GSCQueryBuilder<D, C & F['_constraints']>;
1109
1110
  siteUrl: (url: string) => GSCQueryBuilder<D, C>;
1110
1111
  limit: (n: number) => GSCQueryBuilder<D, C>;
1112
+ offset: (n: number) => GSCQueryBuilder<D, C>;
1111
1113
  execute: (client: GoogleSearchConsoleClient) => Promise<GSCResult<D, C>>;
1112
1114
  toBody: () => SearchAnalyticsQuery;
1113
1115
  /** Expose internal state for analysis functions to merge with */
@@ -1149,6 +1151,10 @@ declare function extractDateRange(filters: Filter<any>[]): {
1149
1151
  endDate?: string;
1150
1152
  };
1151
1153
  //#endregion
1154
+ //#region src/query/index.d.ts
1155
+ declare function today(): string;
1156
+ declare function daysAgo(n: number): string;
1157
+ //#endregion
1152
1158
  //#region src/utils/dayjs.d.ts
1153
1159
  declare function dayjs(date?: _dayjs.ConfigType): Dayjs;
1154
1160
  declare function currentPstDate(): string;
@@ -1170,4 +1176,4 @@ declare function formatDateGsc(d?: Date | string | null): string | null | undefi
1170
1176
  */
1171
1177
  declare function percentDifference(a?: number | null, b?: number | null): number;
1172
1178
  //#endregion
1173
- export { AggregationType, AnalyticsData, ApiSite, ApiSitemap, ApiSitemapContent, Auth, AuthClient, AuthOptions, BaseMetrics, BrandSegmentationOptions, BrandSegmentationResult, BrandSummary, type BuilderState, CannibalizationOptions, CannibalizationPage, CannibalizationResult, CannibalizationSortMetric, ClusterType, ClusteringOptions, ClusteringResult, type Column, ComparisonResult, ConcentrationInput, ConcentrationItem, ConcentrationOptions, ConcentrationResult, ConcentrationRiskLevel, Country, type Country as CountryType, CountryData, DataRow, DataState, DataType, DateData, DateMetrics, DateRow, DatesComparisonResult, DecayInput, DecayOptions, DecayResult, DecaySortMetric, Device, type Device as DeviceType, DeviceData, type Dimension, DimensionFilter, DimensionFilterGroup, DimensionKey, type DimensionValueMap, ErrorInfo, FetchKeywordOptions, FetchKeywordResult, FetchPageOptions, FetchPageResult, type Filter, type GSCQueryBuilder, type GSCResult, type GSCRow, GSC_QUOTAS, GoogleSearchConsoleClient, GoogleSearchConsoleClientOptions, IndexStatusResult, IndexingMetadata, IndexingNotificationType, IndexingResult, InspectUrlIndexResponse, InspectUrlResult, KeywordCluster, KeywordData, KeywordRow, MobileUsabilityResult, MonthlyData, MoverData, MoversInput, MoversOptions, MoversResult, MoversSortMetric, OpportunityFactors, OpportunityOptions, OpportunityResult, OpportunitySortMetric, OpportunityWeights, Page, PageData, PageRow, Period, PublishUrlNotificationResponse, QueryOptions, QueryPageRow, QueryResultRow, RequiredNonNullable, ResolvedAnalyticsRange, RichResultsResult, SearchAnalyticsQuery, SearchAnalyticsResponse, SearchAppearanceData, SeasonalityMetric, SeasonalityOptions, SeasonalityResult, Site, SiteAnalytics, SortOrder, StreamRow, StrikingDistanceOptions, StrikingDistanceResult, StrikingDistanceSortMetric, UrlInspectionResult, UrlNotificationMetadata, YoYComparisonOptions, YoYComparisonResult, YoYMetrics, ZeroClickOptions, ZeroClickResult, analyzeBrandSegmentation, analyzeCannibalization, analyzeClustering, analyzeConcentration, analyzeDecay, analyzeError, analyzeKeywordConcentration, analyzeMovers, analyzeOpportunity, analyzePageConcentration, analyzeSeasonality, analyzeStrikingDistance, analyzeZeroClick, and, batchInspectUrls, batchRequestIndexing, between, collectStream, contains, _default as countries, country, createAuth, createFetch, createQueryBody, createSorter, currentPstDate, date, dayjs, dayjsPst, deleteSitemap, device, eq, extractDateRange, fetchAnalyticsWithComparison, fetchCountries, fetchCountriesWithComparison, fetchDates, fetchDatesWithComparison, fetchDevices, fetchDevicesWithComparison, fetchKeyword, fetchKeywords, fetchKeywordsWithComparison, fetchPage, fetchPages, fetchPagesWithComparison, fetchSearchAppearance, fetchSearchAppearanceWithComparison, fetchSitemap, fetchSitemaps, fetchSites, fetchSitesWithSitemaps, fetchYoYComparison, formatDateGsc, formatErrorForCli, getErrorCode, getErrorMessage, getIndexingMetadata, getRetryAfter, googleSearchConsole, gsc, gt, gte, inArray, inspectUrl, isAuthError, isQuotaError, isRateLimitError, like, lt, lte, ne, not, notRegex, num, or, page, percentDifference, query, queryRecursive, queryRecursiveStream, regex, requestIndexing, searchAppearance, submitSitemap, withDataType, withFinalData, withFreshData, withPropertyAggregation, withSearchAppearance };
1179
+ export { AggregationType, AnalyticsData, ApiSite, ApiSitemap, ApiSitemapContent, Auth, AuthClient, AuthOptions, BaseMetrics, BrandSegmentationOptions, BrandSegmentationResult, BrandSummary, type BuilderState, CannibalizationOptions, CannibalizationPage, CannibalizationResult, CannibalizationSortMetric, ClusterType, ClusteringOptions, ClusteringResult, type Column, ComparisonResult, ConcentrationInput, ConcentrationItem, ConcentrationOptions, ConcentrationResult, ConcentrationRiskLevel, Country, type Country as CountryType, CountryData, DataRow, DataState, DataType, DateData, DateMetrics, DateRow, DatesComparisonResult, DecayInput, DecayOptions, DecayResult, DecaySortMetric, Device, type Device as DeviceType, DeviceData, type Dimension, DimensionFilter, DimensionFilterGroup, DimensionKey, type DimensionValueMap, ErrorInfo, FetchKeywordOptions, FetchKeywordResult, FetchPageOptions, FetchPageResult, type Filter, type GSCQueryBuilder, type GSCResult, type GSCRow, GSC_QUOTAS, GoogleSearchConsoleClient, GoogleSearchConsoleClientOptions, IndexStatusResult, IndexingMetadata, IndexingNotificationType, IndexingResult, InspectUrlIndexResponse, InspectUrlResult, KeywordCluster, KeywordData, KeywordRow, MobileUsabilityResult, MonthlyData, MoverData, MoversInput, MoversOptions, MoversResult, MoversSortMetric, OpportunityFactors, OpportunityOptions, OpportunityResult, OpportunitySortMetric, OpportunityWeights, Page, PageData, PageRow, Period, PublishUrlNotificationResponse, QueryOptions, QueryPageRow, QueryResultRow, RequiredNonNullable, ResolvedAnalyticsRange, RichResultsResult, SearchAnalyticsQuery, SearchAnalyticsResponse, SearchAppearanceData, SeasonalityMetric, SeasonalityOptions, SeasonalityResult, Site, SiteAnalytics, SortOrder, StreamRow, StrikingDistanceOptions, StrikingDistanceResult, StrikingDistanceSortMetric, UrlInspectionResult, UrlNotificationMetadata, YoYComparisonOptions, YoYComparisonResult, YoYMetrics, ZeroClickOptions, ZeroClickResult, analyzeBrandSegmentation, analyzeCannibalization, analyzeClustering, analyzeConcentration, analyzeDecay, analyzeError, analyzeKeywordConcentration, analyzeMovers, analyzeOpportunity, analyzePageConcentration, analyzeSeasonality, analyzeStrikingDistance, analyzeZeroClick, and, batchInspectUrls, batchRequestIndexing, between, collectStream, contains, _default as countries, country, createAuth, createFetch, createQueryBody, createSorter, currentPstDate, date, dayjs, dayjsPst, daysAgo, deleteSitemap, device, eq, extractDateRange, fetchAnalyticsWithComparison, fetchCountries, fetchCountriesWithComparison, fetchDates, fetchDatesWithComparison, fetchDevices, fetchDevicesWithComparison, fetchKeyword, fetchKeywords, fetchKeywordsWithComparison, fetchPage, fetchPages, fetchPagesWithComparison, fetchSearchAppearance, fetchSearchAppearanceWithComparison, fetchSitemap, fetchSitemaps, fetchSites, fetchSitesWithSitemaps, fetchYoYComparison, formatDateGsc, formatErrorForCli, getErrorCode, getErrorMessage, getIndexingMetadata, getRetryAfter, googleSearchConsole, gsc, gt, gte, inArray, inspectUrl, isAuthError, isQuotaError, isRateLimitError, like, lt, lte, ne, not, notRegex, num, or, page, percentDifference, query, queryRecursive, queryRecursiveStream, regex, requestIndexing, searchAppearance, submitSitemap, today, withDataType, withFinalData, withFreshData, withPropertyAggregation, withSearchAppearance };
package/dist/index.mjs CHANGED
@@ -3503,6 +3503,7 @@ function resolveToBody(state) {
3503
3503
  endDate
3504
3504
  };
3505
3505
  if (state.rowLimit) body.rowLimit = state.rowLimit;
3506
+ if (state.startRow) body.startRow = state.startRow;
3506
3507
  const filterGroups = resolveFilters(nonDateFilters);
3507
3508
  if (filterGroups.length > 0) body.dimensionFilterGroups = filterGroups;
3508
3509
  return body;
@@ -3567,6 +3568,12 @@ function createBuilder(state) {
3567
3568
  rowLimit: n
3568
3569
  });
3569
3570
  },
3571
+ offset(n) {
3572
+ return createBuilder({
3573
+ ...state,
3574
+ startRow: n
3575
+ });
3576
+ },
3570
3577
  async execute(client) {
3571
3578
  const body = resolveToBody(state);
3572
3579
  return transformResponse(await client.searchAnalytics.query(state.siteUrl, body), state.dimensions);
@@ -3771,4 +3778,13 @@ function between(column, start, end) {
3771
3778
  }
3772
3779
 
3773
3780
  //#endregion
3774
- export { Country, Device, GSC_QUOTAS, analyzeBrandSegmentation, analyzeCannibalization, analyzeClustering, analyzeConcentration, analyzeDecay, analyzeError, analyzeKeywordConcentration, analyzeMovers, analyzeOpportunity, analyzePageConcentration, analyzeSeasonality, analyzeStrikingDistance, analyzeZeroClick, and, batchInspectUrls, batchRequestIndexing, between, collectStream, contains, countries_default as countries, country, createAuth, createFetch, createQueryBody, createSorter, currentPstDate, date, dayjs, dayjsPst, deleteSitemap, device, eq, extractDateRange, fetchAnalyticsWithComparison, fetchCountries, fetchCountriesWithComparison, fetchDates, fetchDatesWithComparison, fetchDevices, fetchDevicesWithComparison, fetchKeyword, fetchKeywords, fetchKeywordsWithComparison, fetchPage, fetchPages, fetchPagesWithComparison, fetchSearchAppearance, fetchSearchAppearanceWithComparison, fetchSitemap, fetchSitemaps, fetchSites, fetchSitesWithSitemaps, fetchYoYComparison, formatDateGsc, formatErrorForCli, getErrorCode, getErrorMessage, getIndexingMetadata, getRetryAfter, googleSearchConsole, gsc, gt, gte, inArray, inspectUrl, isAuthError, isQuotaError, isRateLimitError, like, lt, lte, ne, not, notRegex, num, or, page, percentDifference, query, queryRecursive, queryRecursiveStream, regex, requestIndexing, searchAppearance, submitSitemap, withDataType, withFinalData, withFreshData, withPropertyAggregation, withSearchAppearance };
3781
+ //#region src/query/index.ts
3782
+ function today() {
3783
+ return currentPstDate();
3784
+ }
3785
+ function daysAgo(n) {
3786
+ return dayjsPst().subtract(n, "day").format("YYYY-MM-DD");
3787
+ }
3788
+
3789
+ //#endregion
3790
+ export { Country, Device, GSC_QUOTAS, analyzeBrandSegmentation, analyzeCannibalization, analyzeClustering, analyzeConcentration, analyzeDecay, analyzeError, analyzeKeywordConcentration, analyzeMovers, analyzeOpportunity, analyzePageConcentration, analyzeSeasonality, analyzeStrikingDistance, analyzeZeroClick, and, batchInspectUrls, batchRequestIndexing, between, collectStream, contains, countries_default as countries, country, createAuth, createFetch, createQueryBody, createSorter, currentPstDate, date, dayjs, dayjsPst, daysAgo, deleteSitemap, device, eq, extractDateRange, fetchAnalyticsWithComparison, fetchCountries, fetchCountriesWithComparison, fetchDates, fetchDatesWithComparison, fetchDevices, fetchDevicesWithComparison, fetchKeyword, fetchKeywords, fetchKeywordsWithComparison, fetchPage, fetchPages, fetchPagesWithComparison, fetchSearchAppearance, fetchSearchAppearanceWithComparison, fetchSitemap, fetchSitemaps, fetchSites, fetchSitesWithSitemaps, fetchYoYComparison, formatDateGsc, formatErrorForCli, getErrorCode, getErrorMessage, getIndexingMetadata, getRetryAfter, googleSearchConsole, gsc, gt, gte, inArray, inspectUrl, isAuthError, isQuotaError, isRateLimitError, like, lt, lte, ne, not, notRegex, num, or, page, percentDifference, query, queryRecursive, queryRecursiveStream, regex, requestIndexing, searchAppearance, submitSitemap, today, withDataType, withFinalData, withFreshData, withPropertyAggregation, withSearchAppearance };
@@ -103,6 +103,7 @@ interface BuilderState {
103
103
  filters: Filter<any>[];
104
104
  siteUrl?: string;
105
105
  rowLimit?: number;
106
+ startRow?: number;
106
107
  }
107
108
  //#endregion
108
109
  //#region src/query/builder.d.ts
@@ -111,6 +112,7 @@ interface GSCQueryBuilder<D extends Dimension[] = [], C = object> {
111
112
  where: <F extends Filter<any>>(filter: F) => GSCQueryBuilder<D, C & F['_constraints']>;
112
113
  siteUrl: (url: string) => GSCQueryBuilder<D, C>;
113
114
  limit: (n: number) => GSCQueryBuilder<D, C>;
115
+ offset: (n: number) => GSCQueryBuilder<D, C>;
114
116
  execute: (client: GoogleSearchConsoleClient) => Promise<GSCResult<D, C>>;
115
117
  toBody: () => SearchAnalyticsQuery;
116
118
  /** Expose internal state for analysis functions to merge with */
@@ -152,4 +154,8 @@ declare function extractDateRange(filters: Filter<any>[]): {
152
154
  endDate?: string;
153
155
  };
154
156
  //#endregion
155
- export { type BuilderState, type Column, Country, type Country as CountryType, Device, type Device as DeviceType, type Dimension, type DimensionValueMap, type Filter, type GSCQueryBuilder, type GSCResult, type GSCRow, and, between, contains, country, date, device, eq, extractDateRange, gsc, gt, gte, inArray, like, lt, lte, ne, not, notRegex, or, page, query, regex, searchAppearance };
157
+ //#region src/query/index.d.ts
158
+ declare function today(): string;
159
+ declare function daysAgo(n: number): string;
160
+ //#endregion
161
+ export { type BuilderState, type Column, Country, type Country as CountryType, Device, type Device as DeviceType, type Dimension, type DimensionValueMap, type Filter, type GSCQueryBuilder, type GSCResult, type GSCRow, and, between, contains, country, date, daysAgo, device, eq, extractDateRange, gsc, gt, gte, inArray, like, lt, lte, ne, not, notRegex, or, page, query, regex, searchAppearance, today };
@@ -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/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",
@@ -71,6 +89,7 @@ function resolveToBody(state) {
71
89
  endDate
72
90
  };
73
91
  if (state.rowLimit) body.rowLimit = state.rowLimit;
92
+ if (state.startRow) body.startRow = state.startRow;
74
93
  const filterGroups = resolveFilters(nonDateFilters);
75
94
  if (filterGroups.length > 0) body.dimensionFilterGroups = filterGroups;
76
95
  return body;
@@ -135,6 +154,12 @@ function createBuilder(state) {
135
154
  rowLimit: n
136
155
  });
137
156
  },
157
+ offset(n) {
158
+ return createBuilder({
159
+ ...state,
160
+ startRow: n
161
+ });
162
+ },
138
163
  async execute(client) {
139
164
  const body = resolveToBody(state);
140
165
  return transformResponse(await client.searchAnalytics.query(state.siteUrl, body), state.dimensions);
@@ -1838,4 +1863,13 @@ function between(column, start, end) {
1838
1863
  }
1839
1864
 
1840
1865
  //#endregion
1841
- export { Country, Device, and, between, contains, country, date, device, eq, extractDateRange, gsc, gt, gte, inArray, like, lt, lte, ne, not, notRegex, or, page, query, regex, searchAppearance };
1866
+ //#region src/query/index.ts
1867
+ function today() {
1868
+ return currentPstDate();
1869
+ }
1870
+ function daysAgo(n) {
1871
+ return dayjsPst().subtract(n, "day").format("YYYY-MM-DD");
1872
+ }
1873
+
1874
+ //#endregion
1875
+ export { Country, Device, and, between, contains, country, date, daysAgo, device, eq, extractDateRange, gsc, gt, gte, inArray, like, lt, lte, ne, not, notRegex, or, page, query, regex, searchAppearance, today };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "gscdump",
3
3
  "type": "module",
4
- "version": "0.1.1",
4
+ "version": "0.1.3",
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",