gscdump 0.0.1 → 0.1.2
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 +172 -0
- package/dist/index.d.mts +229 -249
- package/dist/index.mjs +358 -400
- package/dist/query/index.d.mts +157 -0
- package/dist/query/index.mjs +1848 -0
- package/package.json +16 -7
package/README.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# gscdump
|
|
2
|
+
|
|
3
|
+
[](https://npmjs.com/package/gscdump)
|
|
4
|
+
[](https://npm.chart.dev/gscdump)
|
|
5
|
+
[](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, between, contains, country, Country, date, 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
|
+
between(date, '2024-01-01', '2024-01-31')
|
|
76
|
+
))
|
|
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
|
+
**With date helpers:**
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
import { daysAgo, today } from '@gscdump/query'
|
|
91
|
+
import { and, between, date, gsc, query, regex } from 'gscdump/query'
|
|
92
|
+
|
|
93
|
+
const q = gsc
|
|
94
|
+
.select('query', 'page')
|
|
95
|
+
.where(and(
|
|
96
|
+
between(date, daysAgo(28), today()),
|
|
97
|
+
regex(query, /how to/)
|
|
98
|
+
))
|
|
99
|
+
.limit(100)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
**Operators:**
|
|
103
|
+
|
|
104
|
+
| Operator | Narrows Type? | Description |
|
|
105
|
+
|----------|---------------|-------------|
|
|
106
|
+
| `eq(col, val)` | ✓ | Exact match |
|
|
107
|
+
| `ne(col, val)` | ✗ | Not equal |
|
|
108
|
+
| `inArray(col, [a, b])` | ✓ | Value in array (becomes `a \| b`) |
|
|
109
|
+
| `contains(col, str)` | ✗ | String contains |
|
|
110
|
+
| `like(col, '%pattern%')` | ✗ | SQL LIKE pattern |
|
|
111
|
+
| `regex(col, /pattern/)` | ✗ | Regex match |
|
|
112
|
+
| `notRegex(col, /pattern/)` | ✗ | Regex exclusion |
|
|
113
|
+
| `between(col, start, end)` | ✗ | Inclusive range (primarily for date) |
|
|
114
|
+
| `gte(col, val)` | ✗ | Greater than or equal |
|
|
115
|
+
| `lte(col, val)` | ✗ | Less than or equal |
|
|
116
|
+
| `gt(col, val)` | ✗ | Greater than |
|
|
117
|
+
| `lt(col, val)` | ✗ | Less than |
|
|
118
|
+
| `and(...filters)` | ✓ | Merge constraints |
|
|
119
|
+
| `or(...filters)` | ✗ | Any match |
|
|
120
|
+
| `not(filter)` | ✗ | Invert filter |
|
|
121
|
+
|
|
122
|
+
### Analysis Functions
|
|
123
|
+
|
|
124
|
+
Analysis functions are pure - they operate on typed data arrays and return typed results.
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
import {
|
|
128
|
+
analyzeCannibalization,
|
|
129
|
+
analyzeDecay,
|
|
130
|
+
analyzeMovers,
|
|
131
|
+
analyzeStrikingDistance,
|
|
132
|
+
fetchKeywordsWithComparison,
|
|
133
|
+
} from 'gscdump'
|
|
134
|
+
|
|
135
|
+
// Fetch data first
|
|
136
|
+
const { current, previous } = await fetchKeywordsWithComparison(auth, site, range)
|
|
137
|
+
|
|
138
|
+
// Run pure analysis on the data
|
|
139
|
+
const striking = analyzeStrikingDistance(current)
|
|
140
|
+
const movers = analyzeMovers(current, previous)
|
|
141
|
+
const decay = analyzeDecay(current, previous)
|
|
142
|
+
const cannibalization = analyzeCannibalization(keywordPageData)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Exports
|
|
146
|
+
|
|
147
|
+
**Sites:** `fetchSites`, `fetchSitesWithSitemaps`, `fetchSitemaps`, `getSitemap`, `submitSitemap`, `deleteSitemap`, `inspectUrl`, `batchInspectUrls`
|
|
148
|
+
|
|
149
|
+
**Indexing:** `requestIndexing`, `getIndexingMetadata`, `batchRequestIndexing`
|
|
150
|
+
|
|
151
|
+
**Analytics:** `fetchAnalyticsWithComparison`, `fetchPagesWithComparison`, `fetchKeywordsWithComparison`, `fetchDevicesWithComparison`, `fetchCountriesWithComparison`, `fetchSearchAppearanceWithComparison`, `fetchDates`, `fetchDatesWithComparison`, `fetchPages`, `fetchPage`, `fetchKeyword`
|
|
152
|
+
|
|
153
|
+
**Analysis (Pure):** `analyzeStrikingDistance`, `analyzeOpportunity`, `analyzeBrandSegmentation`, `analyzeConcentration`, `analyzeDecay`, `analyzeMovers`, `analyzeCannibalization`, `analyzeZeroClick`, `analyzeSeasonality`, `analyzeClustering`
|
|
154
|
+
|
|
155
|
+
**Low-level:** `gscClient`, `queryRecursive`, `queryRecursiveStream`, `createQueryBody`, `withPropertyAggregation`, `withSearchAppearance`, `withDataType`, `withFreshData`, `withFinalData`
|
|
156
|
+
|
|
157
|
+
**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`
|
|
158
|
+
|
|
159
|
+
**Error Utilities:** `isQuotaError`, `isRateLimitError`, `isAuthError`, `getErrorCode`, `getErrorMessage`, `getRetryAfter`, `analyzeGscError`, `formatGscErrorForCli`
|
|
160
|
+
|
|
161
|
+
**Utils:** `formatDateGsc`, `percentDifference`
|
|
162
|
+
|
|
163
|
+
## Related Packages
|
|
164
|
+
|
|
165
|
+
- [`@gscdump/cli`](../cli) - CLI for dump, sync, compare, analyze
|
|
166
|
+
- [`@gscdump/mcp`](../mcp) - MCP server for AI agents
|
|
167
|
+
- [`@gscdump/db`](../db) - SQLite persistence
|
|
168
|
+
- [`@gscdump/query`](../query) - Unified data provider
|
|
169
|
+
|
|
170
|
+
## License
|
|
171
|
+
|
|
172
|
+
[MIT](../../LICENSE)
|