gscdump 0.0.1 → 0.1.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.
package/README.md ADDED
@@ -0,0 +1,151 @@
1
+ # gscdump
2
+
3
+ [![npm version](https://img.shields.io/npm/v/gscdump?color=yellow)](https://npmjs.com/package/gscdump)
4
+ [![npm downloads](https://img.shields.io/npm/dm/gscdump?color=yellow)](https://npm.chart.dev/gscdump)
5
+ [![license](https://img.shields.io/github/license/harlan-zw/gscdump?color=yellow)](https://github.com/harlan-zw/gscdump/blob/main/LICENSE)
6
+
7
+ > Google Search Console API wrapper with typed query builder, streaming pagination, and SEO analysis functions.
8
+
9
+ ## Features
10
+
11
+ - **Typed Query Builder** - Drizzle-style API with filter constraints narrowing result types
12
+ - **Streaming Pagination** - Memory-efficient iteration over large datasets (>25k rows)
13
+ - **SEO Analysis** - Pure functions for cannibalization, striking distance, movers & shakers, decay detection
14
+ - **Edge-Compatible** - Works in Cloudflare Workers, Deno, and other edge runtimes
15
+ - **Full API Coverage** - Sites, sitemaps, indexing, and analytics
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ npm install gscdump
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ ```ts
26
+ import { daysAgo, today } from '@gscdump/query'
27
+ import { fetchKeywordsWithComparison, fetchPagesWithComparison } from 'gscdump'
28
+
29
+ // Auth accepts token string or object
30
+ const auth = 'ya29.xxx...'
31
+ // or: { accessToken: 'ya29.xxx...' }
32
+
33
+ const range = {
34
+ period: { start: daysAgo(28), end: today() },
35
+ }
36
+
37
+ // Pages with top keyword per page
38
+ const pages = await fetchPagesWithComparison(auth, site, range)
39
+
40
+ // Keywords with change percentages
41
+ const keywords = await fetchKeywordsWithComparison(auth, site, range)
42
+ ```
43
+
44
+ ### Streaming Large Datasets
45
+
46
+ For memory-efficient pagination of large datasets (>25k rows):
47
+
48
+ ```ts
49
+ import { queryRecursiveStream } from 'gscdump'
50
+
51
+ // Stream keyword+page combinations - yields batches as they're fetched
52
+ for await (const batch of queryRecursiveStream(client, site, {
53
+ dimensions: ['query', 'page'] as const, // as const required for type inference
54
+ startDate: '2024-01-01',
55
+ endDate: '2024-01-31',
56
+ })) {
57
+ // batch: { keyword: string, page: string, clicks, impressions, ctr, position }[]
58
+ await db.insert(batch)
59
+ }
60
+ ```
61
+
62
+ ### Typed Query Builder
63
+
64
+ Drizzle-style query builder with full type safety. Filter constraints flow through to result types.
65
+
66
+ ```ts
67
+ import { and, contains, country, Country, device, Device, eq, gsc, inArray, page } from 'gscdump/query'
68
+
69
+ const result = await gsc
70
+ .select('page', 'query', 'device', 'country')
71
+ .where(and(
72
+ eq(device, Device.MOBILE),
73
+ inArray(country, [Country.USA, Country.GBR]),
74
+ contains(page, '/blog/')
75
+ ))
76
+ .period('2024-01-01', '2024-01-31')
77
+ .siteUrl('https://example.com')
78
+ .execute(client)
79
+
80
+ // Fully typed results - narrowed by filters
81
+ result.rows[0].device // type: 'MOBILE' (narrowed by eq)
82
+ result.rows[0].country // type: 'usa' | 'gbr' (narrowed by inArray)
83
+ result.rows[0].page // type: string (contains doesn't narrow)
84
+ result.rows[0].clicks // type: number
85
+ ```
86
+
87
+ **Operators:**
88
+
89
+ | Operator | Narrows Type? | Description |
90
+ |----------|---------------|-------------|
91
+ | `eq(col, val)` | ✓ | Exact match |
92
+ | `ne(col, val)` | ✗ | Not equal |
93
+ | `inArray(col, [a, b])` | ✓ | Value in array (becomes `a \| b`) |
94
+ | `contains(col, str)` | ✗ | String contains |
95
+ | `like(col, '%pattern%')` | ✗ | SQL LIKE pattern |
96
+ | `regex(col, /pattern/)` | ✗ | Regex match |
97
+ | `and(...filters)` | ✓ | Merge constraints |
98
+ | `or(...filters)` | ✗ | Any match |
99
+ | `not(filter)` | ✗ | Invert filter |
100
+
101
+ ### Analysis Functions
102
+
103
+ Analysis functions are pure - they operate on typed data arrays and return typed results.
104
+
105
+ ```ts
106
+ import {
107
+ analyzeCannibalization,
108
+ analyzeDecay,
109
+ analyzeMovers,
110
+ analyzeStrikingDistance,
111
+ fetchKeywordsWithComparison,
112
+ } from 'gscdump'
113
+
114
+ // Fetch data first
115
+ const { current, previous } = await fetchKeywordsWithComparison(auth, site, range)
116
+
117
+ // Run pure analysis on the data
118
+ const striking = analyzeStrikingDistance(current)
119
+ const movers = analyzeMovers(current, previous)
120
+ const decay = analyzeDecay(current, previous)
121
+ const cannibalization = analyzeCannibalization(keywordPageData)
122
+ ```
123
+
124
+ ## Exports
125
+
126
+ **Sites:** `fetchSites`, `fetchSitesWithSitemaps`, `fetchSitemaps`, `getSitemap`, `submitSitemap`, `deleteSitemap`, `inspectUrl`, `batchInspectUrls`
127
+
128
+ **Indexing:** `requestIndexing`, `getIndexingMetadata`, `batchRequestIndexing`
129
+
130
+ **Analytics:** `fetchAnalyticsWithComparison`, `fetchPagesWithComparison`, `fetchKeywordsWithComparison`, `fetchDevicesWithComparison`, `fetchCountriesWithComparison`, `fetchSearchAppearanceWithComparison`, `fetchDates`, `fetchDatesWithComparison`, `fetchPages`, `fetchPage`, `fetchKeyword`
131
+
132
+ **Analysis (Pure):** `analyzeStrikingDistance`, `analyzeOpportunity`, `analyzeBrandSegmentation`, `analyzeConcentration`, `analyzeDecay`, `analyzeMovers`, `analyzeCannibalization`, `analyzeZeroClick`, `analyzeSeasonality`, `analyzeClustering`
133
+
134
+ **Low-level:** `gscClient`, `queryRecursive`, `queryRecursiveStream`, `createQueryBody`, `withPropertyAggregation`, `withSearchAppearance`, `withDataType`, `withFreshData`, `withFinalData`
135
+
136
+ **Query Builder (`gscdump/query`):** `gsc`, `eq`, `ne`, `and`, `or`, `inArray`, `contains`, `like`, `regex`, `notRegex`, `not`, `page`, `query`, `device`, `country`, `searchAppearance`, `Device`, `Country`
137
+
138
+ **Error Utilities:** `isQuotaError`, `isRateLimitError`, `isAuthError`, `getErrorCode`, `getErrorMessage`, `getRetryAfter`, `analyzeGscError`, `formatGscErrorForCli`
139
+
140
+ **Utils:** `formatDateGsc`, `percentDifference`
141
+
142
+ ## Related Packages
143
+
144
+ - [`@gscdump/cli`](../cli) - CLI for dump, sync, compare, analyze
145
+ - [`@gscdump/mcp`](../mcp) - MCP server for AI agents
146
+ - [`@gscdump/db`](../db) - SQLite persistence
147
+ - [`@gscdump/query`](../query) - Unified data provider
148
+
149
+ ## License
150
+
151
+ [MIT](../../LICENSE)