@tinybirdco/sdk 0.0.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 +518 -0
- package/bin/tinybird.js +7 -0
- package/dist/api/branches.d.ts +98 -0
- package/dist/api/branches.d.ts.map +1 -0
- package/dist/api/branches.js +203 -0
- package/dist/api/branches.js.map +1 -0
- package/dist/api/branches.test.d.ts +2 -0
- package/dist/api/branches.test.d.ts.map +1 -0
- package/dist/api/branches.test.js +286 -0
- package/dist/api/branches.test.js.map +1 -0
- package/dist/api/build.d.ts +130 -0
- package/dist/api/build.d.ts.map +1 -0
- package/dist/api/build.js +143 -0
- package/dist/api/build.js.map +1 -0
- package/dist/api/build.test.d.ts +2 -0
- package/dist/api/build.test.d.ts.map +1 -0
- package/dist/api/build.test.js +138 -0
- package/dist/api/build.test.js.map +1 -0
- package/dist/api/deploy.d.ts +39 -0
- package/dist/api/deploy.d.ts.map +1 -0
- package/dist/api/deploy.js +135 -0
- package/dist/api/deploy.js.map +1 -0
- package/dist/api/deploy.test.d.ts +2 -0
- package/dist/api/deploy.test.d.ts.map +1 -0
- package/dist/api/deploy.test.js +118 -0
- package/dist/api/deploy.test.js.map +1 -0
- package/dist/api/workspaces.d.ts +46 -0
- package/dist/api/workspaces.d.ts.map +1 -0
- package/dist/api/workspaces.js +39 -0
- package/dist/api/workspaces.js.map +1 -0
- package/dist/api/workspaces.test.d.ts +2 -0
- package/dist/api/workspaces.test.d.ts.map +1 -0
- package/dist/api/workspaces.test.js +65 -0
- package/dist/api/workspaces.test.js.map +1 -0
- package/dist/cli/auth.d.ts +86 -0
- package/dist/cli/auth.d.ts.map +1 -0
- package/dist/cli/auth.js +284 -0
- package/dist/cli/auth.js.map +1 -0
- package/dist/cli/branch-store.d.ts +53 -0
- package/dist/cli/branch-store.d.ts.map +1 -0
- package/dist/cli/branch-store.js +91 -0
- package/dist/cli/branch-store.js.map +1 -0
- package/dist/cli/branch-store.test.d.ts +2 -0
- package/dist/cli/branch-store.test.d.ts.map +1 -0
- package/dist/cli/branch-store.test.js +115 -0
- package/dist/cli/branch-store.test.js.map +1 -0
- package/dist/cli/commands/branch.d.ts +82 -0
- package/dist/cli/commands/branch.d.ts.map +1 -0
- package/dist/cli/commands/branch.js +215 -0
- package/dist/cli/commands/branch.js.map +1 -0
- package/dist/cli/commands/build.d.ts +43 -0
- package/dist/cli/commands/build.d.ts.map +1 -0
- package/dist/cli/commands/build.js +138 -0
- package/dist/cli/commands/build.js.map +1 -0
- package/dist/cli/commands/dev.d.ts +78 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/dev.js +226 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/init.d.ts +45 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +277 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/init.test.d.ts +2 -0
- package/dist/cli/commands/init.test.d.ts.map +1 -0
- package/dist/cli/commands/init.test.js +158 -0
- package/dist/cli/commands/init.test.js.map +1 -0
- package/dist/cli/commands/login.d.ts +37 -0
- package/dist/cli/commands/login.d.ts.map +1 -0
- package/dist/cli/commands/login.js +64 -0
- package/dist/cli/commands/login.js.map +1 -0
- package/dist/cli/config.d.ts +114 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +258 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/config.test.d.ts +2 -0
- package/dist/cli/config.test.d.ts.map +1 -0
- package/dist/cli/config.test.js +243 -0
- package/dist/cli/config.test.js.map +1 -0
- package/dist/cli/env.d.ts +29 -0
- package/dist/cli/env.d.ts.map +1 -0
- package/dist/cli/env.js +66 -0
- package/dist/cli/env.js.map +1 -0
- package/dist/cli/git.d.ts +29 -0
- package/dist/cli/git.d.ts.map +1 -0
- package/dist/cli/git.js +114 -0
- package/dist/cli/git.js.map +1 -0
- package/dist/cli/git.test.d.ts +2 -0
- package/dist/cli/git.test.d.ts.map +1 -0
- package/dist/cli/git.test.js +125 -0
- package/dist/cli/git.test.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +337 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/utils/schema-validation.d.ts +95 -0
- package/dist/cli/utils/schema-validation.d.ts.map +1 -0
- package/dist/cli/utils/schema-validation.js +175 -0
- package/dist/cli/utils/schema-validation.js.map +1 -0
- package/dist/cli/utils/schema-validation.test.d.ts +5 -0
- package/dist/cli/utils/schema-validation.test.d.ts.map +1 -0
- package/dist/cli/utils/schema-validation.test.js +173 -0
- package/dist/cli/utils/schema-validation.test.js.map +1 -0
- package/dist/client/base.d.ts +116 -0
- package/dist/client/base.d.ts.map +1 -0
- package/dist/client/base.js +328 -0
- package/dist/client/base.js.map +1 -0
- package/dist/client/types.d.ts +137 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +43 -0
- package/dist/client/types.js.map +1 -0
- package/dist/generator/client.d.ts +44 -0
- package/dist/generator/client.d.ts.map +1 -0
- package/dist/generator/client.js +144 -0
- package/dist/generator/client.js.map +1 -0
- package/dist/generator/datasource.d.ts +57 -0
- package/dist/generator/datasource.d.ts.map +1 -0
- package/dist/generator/datasource.js +169 -0
- package/dist/generator/datasource.js.map +1 -0
- package/dist/generator/datasource.test.d.ts +2 -0
- package/dist/generator/datasource.test.d.ts.map +1 -0
- package/dist/generator/datasource.test.js +254 -0
- package/dist/generator/datasource.test.js.map +1 -0
- package/dist/generator/index.d.ts +131 -0
- package/dist/generator/index.d.ts.map +1 -0
- package/dist/generator/index.js +121 -0
- package/dist/generator/index.js.map +1 -0
- package/dist/generator/index.test.d.ts +2 -0
- package/dist/generator/index.test.d.ts.map +1 -0
- package/dist/generator/index.test.js +175 -0
- package/dist/generator/index.test.js.map +1 -0
- package/dist/generator/loader.d.ts +156 -0
- package/dist/generator/loader.d.ts.map +1 -0
- package/dist/generator/loader.js +295 -0
- package/dist/generator/loader.js.map +1 -0
- package/dist/generator/pipe.d.ts +72 -0
- package/dist/generator/pipe.d.ts.map +1 -0
- package/dist/generator/pipe.js +174 -0
- package/dist/generator/pipe.js.map +1 -0
- package/dist/generator/pipe.test.d.ts +2 -0
- package/dist/generator/pipe.test.d.ts.map +1 -0
- package/dist/generator/pipe.test.js +393 -0
- package/dist/generator/pipe.test.js.map +1 -0
- package/dist/index.d.ts +74 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +73 -0
- package/dist/index.js.map +1 -0
- package/dist/infer/index.d.ts +202 -0
- package/dist/infer/index.d.ts.map +1 -0
- package/dist/infer/index.js +5 -0
- package/dist/infer/index.js.map +1 -0
- package/dist/schema/datasource.d.ts +135 -0
- package/dist/schema/datasource.d.ts.map +1 -0
- package/dist/schema/datasource.js +105 -0
- package/dist/schema/datasource.js.map +1 -0
- package/dist/schema/datasource.test.d.ts +2 -0
- package/dist/schema/datasource.test.d.ts.map +1 -0
- package/dist/schema/datasource.test.js +142 -0
- package/dist/schema/datasource.test.js.map +1 -0
- package/dist/schema/engines.d.ts +157 -0
- package/dist/schema/engines.d.ts.map +1 -0
- package/dist/schema/engines.js +155 -0
- package/dist/schema/engines.js.map +1 -0
- package/dist/schema/engines.test.d.ts +2 -0
- package/dist/schema/engines.test.d.ts.map +1 -0
- package/dist/schema/engines.test.js +221 -0
- package/dist/schema/engines.test.js.map +1 -0
- package/dist/schema/params.d.ts +106 -0
- package/dist/schema/params.d.ts.map +1 -0
- package/dist/schema/params.js +138 -0
- package/dist/schema/params.js.map +1 -0
- package/dist/schema/params.test.d.ts +2 -0
- package/dist/schema/params.test.d.ts.map +1 -0
- package/dist/schema/params.test.js +175 -0
- package/dist/schema/params.test.js.map +1 -0
- package/dist/schema/pipe.d.ts +436 -0
- package/dist/schema/pipe.d.ts.map +1 -0
- package/dist/schema/pipe.js +484 -0
- package/dist/schema/pipe.js.map +1 -0
- package/dist/schema/pipe.test.d.ts +2 -0
- package/dist/schema/pipe.test.d.ts.map +1 -0
- package/dist/schema/pipe.test.js +488 -0
- package/dist/schema/pipe.test.js.map +1 -0
- package/dist/schema/project.d.ts +202 -0
- package/dist/schema/project.d.ts.map +1 -0
- package/dist/schema/project.js +188 -0
- package/dist/schema/project.js.map +1 -0
- package/dist/schema/project.test.d.ts +2 -0
- package/dist/schema/project.test.d.ts.map +1 -0
- package/dist/schema/project.test.js +180 -0
- package/dist/schema/project.test.js.map +1 -0
- package/dist/schema/types.d.ts +140 -0
- package/dist/schema/types.d.ts.map +1 -0
- package/dist/schema/types.js +174 -0
- package/dist/schema/types.js.map +1 -0
- package/dist/schema/types.test.d.ts +2 -0
- package/dist/schema/types.test.d.ts.map +1 -0
- package/dist/schema/types.test.js +176 -0
- package/dist/schema/types.test.js.map +1 -0
- package/dist/test/handlers.d.ts +58 -0
- package/dist/test/handlers.d.ts.map +1 -0
- package/dist/test/handlers.js +62 -0
- package/dist/test/handlers.js.map +1 -0
- package/dist/test/setup.d.ts +5 -0
- package/dist/test/setup.d.ts.map +1 -0
- package/dist/test/setup.js +11 -0
- package/dist/test/setup.js.map +1 -0
- package/package.json +57 -0
- package/src/api/branches.test.ts +377 -0
- package/src/api/branches.ts +334 -0
- package/src/api/build.test.ts +216 -0
- package/src/api/build.ts +266 -0
- package/src/api/deploy.test.ts +193 -0
- package/src/api/deploy.ts +163 -0
- package/src/api/workspaces.test.ts +81 -0
- package/src/api/workspaces.ts +77 -0
- package/src/cli/auth.ts +358 -0
- package/src/cli/branch-store.test.ts +139 -0
- package/src/cli/branch-store.ts +137 -0
- package/src/cli/commands/branch.ts +306 -0
- package/src/cli/commands/build.ts +183 -0
- package/src/cli/commands/dev.ts +334 -0
- package/src/cli/commands/init.test.ts +249 -0
- package/src/cli/commands/init.ts +323 -0
- package/src/cli/commands/login.ts +98 -0
- package/src/cli/config.test.ts +359 -0
- package/src/cli/config.ts +335 -0
- package/src/cli/env.ts +86 -0
- package/src/cli/git.test.ts +147 -0
- package/src/cli/git.ts +125 -0
- package/src/cli/index.ts +382 -0
- package/src/cli/utils/schema-validation.test.ts +222 -0
- package/src/cli/utils/schema-validation.ts +272 -0
- package/src/client/base.ts +414 -0
- package/src/client/types.ts +165 -0
- package/src/generator/client.ts +194 -0
- package/src/generator/datasource.test.ts +297 -0
- package/src/generator/datasource.ts +217 -0
- package/src/generator/index.test.ts +209 -0
- package/src/generator/index.ts +203 -0
- package/src/generator/loader.ts +406 -0
- package/src/generator/pipe.test.ts +441 -0
- package/src/generator/pipe.ts +220 -0
- package/src/index.ts +191 -0
- package/src/infer/index.ts +247 -0
- package/src/schema/datasource.test.ts +187 -0
- package/src/schema/datasource.ts +195 -0
- package/src/schema/engines.test.ts +247 -0
- package/src/schema/engines.ts +271 -0
- package/src/schema/params.test.ts +208 -0
- package/src/schema/params.ts +249 -0
- package/src/schema/pipe.test.ts +588 -0
- package/src/schema/pipe.ts +832 -0
- package/src/schema/project.test.ts +236 -0
- package/src/schema/project.ts +394 -0
- package/src/schema/types.test.ts +212 -0
- package/src/schema/types.ts +366 -0
- package/src/test/handlers.ts +79 -0
- package/src/test/setup.ts +13 -0
package/README.md
ADDED
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
# @tinybirdco/sdk
|
|
2
|
+
|
|
3
|
+
> **Note:** This package is experimental. APIs may change between versions.
|
|
4
|
+
|
|
5
|
+
A TypeScript SDK for defining Tinybird resources with full type inference. Define your datasources, pipes, and queries in TypeScript and sync them directly to Tinybird.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @tinybirdco/sdk
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### 1. Initialize your project
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx tinybird init
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
This creates:
|
|
22
|
+
- `tinybird.json` - Configuration file
|
|
23
|
+
- `src/tinybird/datasources.ts` - Define your datasources
|
|
24
|
+
- `src/tinybird/pipes.ts` - Define your pipes/endpoints
|
|
25
|
+
- `src/tinybird/client.ts` - Your typed Tinybird client
|
|
26
|
+
|
|
27
|
+
### 2. Configure your token
|
|
28
|
+
|
|
29
|
+
Create a `.env.local` file:
|
|
30
|
+
|
|
31
|
+
```env
|
|
32
|
+
TINYBIRD_TOKEN=p.your_token_here
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### 3. Define your datasources
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
// src/tinybird/datasources.ts
|
|
39
|
+
import { defineDatasource, t, engine, type InferRow } from "@tinybirdco/sdk";
|
|
40
|
+
|
|
41
|
+
export const pageViews = defineDatasource("page_views", {
|
|
42
|
+
description: "Page view tracking data",
|
|
43
|
+
schema: {
|
|
44
|
+
timestamp: t.dateTime(),
|
|
45
|
+
pathname: t.string(),
|
|
46
|
+
session_id: t.string(),
|
|
47
|
+
country: t.string().lowCardinality().nullable(),
|
|
48
|
+
},
|
|
49
|
+
engine: engine.mergeTree({
|
|
50
|
+
sortingKey: ["pathname", "timestamp"],
|
|
51
|
+
}),
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Export row type for ingestion
|
|
55
|
+
export type PageViewsRow = InferRow<typeof pageViews>;
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 4. Define your endpoints
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
// src/tinybird/pipes.ts
|
|
62
|
+
import { defineEndpoint, node, t, p, type InferParams, type InferOutputRow } from "@tinybirdco/sdk";
|
|
63
|
+
|
|
64
|
+
export const topPages = defineEndpoint("top_pages", {
|
|
65
|
+
description: "Get the most visited pages",
|
|
66
|
+
params: {
|
|
67
|
+
start_date: p.dateTime(),
|
|
68
|
+
end_date: p.dateTime(),
|
|
69
|
+
limit: p.int32().optional(10),
|
|
70
|
+
},
|
|
71
|
+
nodes: [
|
|
72
|
+
node({
|
|
73
|
+
name: "aggregated",
|
|
74
|
+
sql: `
|
|
75
|
+
SELECT pathname, count() AS views
|
|
76
|
+
FROM page_views
|
|
77
|
+
WHERE timestamp >= {{DateTime(start_date)}}
|
|
78
|
+
AND timestamp <= {{DateTime(end_date)}}
|
|
79
|
+
GROUP BY pathname
|
|
80
|
+
ORDER BY views DESC
|
|
81
|
+
LIMIT {{Int32(limit, 10)}}
|
|
82
|
+
`,
|
|
83
|
+
}),
|
|
84
|
+
],
|
|
85
|
+
output: {
|
|
86
|
+
pathname: t.string(),
|
|
87
|
+
views: t.uint64(),
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Export endpoint types
|
|
92
|
+
export type TopPagesParams = InferParams<typeof topPages>;
|
|
93
|
+
export type TopPagesOutput = InferOutputRow<typeof topPages>;
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### 5. Create your client
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
// src/tinybird/client.ts
|
|
100
|
+
import { createTinybirdClient } from "@tinybirdco/sdk";
|
|
101
|
+
import { pageViews, type PageViewsRow } from "./datasources";
|
|
102
|
+
import { topPages, type TopPagesParams, type TopPagesOutput } from "./pipes";
|
|
103
|
+
|
|
104
|
+
export const tinybird = createTinybirdClient({
|
|
105
|
+
datasources: { pageViews },
|
|
106
|
+
pipes: { topPages },
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Re-export types for convenience
|
|
110
|
+
export type { PageViewsRow, TopPagesParams, TopPagesOutput };
|
|
111
|
+
export { pageViews, topPages };
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 6. Add path alias (for Next.js/TypeScript projects)
|
|
115
|
+
|
|
116
|
+
Add to your `tsconfig.json`:
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
{
|
|
120
|
+
"compilerOptions": {
|
|
121
|
+
"paths": {
|
|
122
|
+
"@tinybird/client": ["./src/tinybird/client.ts"]
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### 7. Start development
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
npx tinybird dev
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
This watches your schema files and automatically syncs changes to Tinybird.
|
|
135
|
+
|
|
136
|
+
### 8. Use the typed client
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
import { tinybird, type PageViewsRow } from "@tinybird/client";
|
|
140
|
+
|
|
141
|
+
// Type-safe data ingestion
|
|
142
|
+
await tinybird.ingest.pageViews({
|
|
143
|
+
timestamp: new Date(),
|
|
144
|
+
pathname: "/home",
|
|
145
|
+
session_id: "abc123",
|
|
146
|
+
country: "US",
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
// Type-safe queries with autocomplete
|
|
150
|
+
const result = await tinybird.query.topPages({
|
|
151
|
+
start_date: new Date("2024-01-01"),
|
|
152
|
+
end_date: new Date(),
|
|
153
|
+
limit: 5,
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
// result.data is fully typed: { pathname: string, views: bigint }[]
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## CLI Commands
|
|
160
|
+
|
|
161
|
+
### `npx tinybird init`
|
|
162
|
+
|
|
163
|
+
Initialize a new Tinybird TypeScript project.
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
npx tinybird init
|
|
167
|
+
npx tinybird init --force # Overwrite existing files
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### `npx tinybird build`
|
|
171
|
+
|
|
172
|
+
Build and push resources to Tinybird.
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
npx tinybird build
|
|
176
|
+
npx tinybird build --dry-run # Preview without pushing
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### `npx tinybird dev`
|
|
180
|
+
|
|
181
|
+
Watch for changes and sync with Tinybird automatically.
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
npx tinybird dev
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Configuration
|
|
188
|
+
|
|
189
|
+
Create a `tinybird.json` in your project root:
|
|
190
|
+
|
|
191
|
+
```json
|
|
192
|
+
{
|
|
193
|
+
"include": [
|
|
194
|
+
"src/tinybird/datasources.ts",
|
|
195
|
+
"src/tinybird/pipes.ts"
|
|
196
|
+
],
|
|
197
|
+
"token": "${TINYBIRD_TOKEN}",
|
|
198
|
+
"baseUrl": "https://api.tinybird.co"
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
- `include` - Array of TypeScript files to scan for datasources and pipes
|
|
203
|
+
- `token` - API token (supports environment variable interpolation)
|
|
204
|
+
- `baseUrl` - Tinybird API URL (defaults to EU region)
|
|
205
|
+
|
|
206
|
+
## Defining Resources
|
|
207
|
+
|
|
208
|
+
### Datasources
|
|
209
|
+
|
|
210
|
+
```typescript
|
|
211
|
+
import { defineDatasource, t, engine, type InferRow } from "@tinybirdco/sdk";
|
|
212
|
+
|
|
213
|
+
export const events = defineDatasource("events", {
|
|
214
|
+
description: "Event tracking data",
|
|
215
|
+
schema: {
|
|
216
|
+
timestamp: t.dateTime(),
|
|
217
|
+
event_name: t.string().lowCardinality(),
|
|
218
|
+
user_id: t.string().nullable(),
|
|
219
|
+
properties: t.string(), // JSON as string
|
|
220
|
+
},
|
|
221
|
+
engine: engine.mergeTree({
|
|
222
|
+
sortingKey: ["event_name", "timestamp"],
|
|
223
|
+
partitionKey: "toYYYYMM(timestamp)",
|
|
224
|
+
ttl: "timestamp + INTERVAL 90 DAY",
|
|
225
|
+
}),
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
export type EventsRow = InferRow<typeof events>;
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Endpoints (API pipes)
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
import { defineEndpoint, node, t, p, type InferParams, type InferOutputRow } from "@tinybirdco/sdk";
|
|
235
|
+
|
|
236
|
+
export const topEvents = defineEndpoint("top_events", {
|
|
237
|
+
description: "Get the most frequent events",
|
|
238
|
+
params: {
|
|
239
|
+
start_date: p.dateTime(),
|
|
240
|
+
end_date: p.dateTime(),
|
|
241
|
+
limit: p.int32().optional(10),
|
|
242
|
+
},
|
|
243
|
+
nodes: [
|
|
244
|
+
node({
|
|
245
|
+
name: "aggregated",
|
|
246
|
+
sql: `
|
|
247
|
+
SELECT event_name, count() AS event_count
|
|
248
|
+
FROM events
|
|
249
|
+
WHERE timestamp >= {{DateTime(start_date)}}
|
|
250
|
+
AND timestamp <= {{DateTime(end_date)}}
|
|
251
|
+
GROUP BY event_name
|
|
252
|
+
ORDER BY event_count DESC
|
|
253
|
+
LIMIT {{Int32(limit, 10)}}
|
|
254
|
+
`,
|
|
255
|
+
}),
|
|
256
|
+
],
|
|
257
|
+
output: {
|
|
258
|
+
event_name: t.string(),
|
|
259
|
+
event_count: t.uint64(),
|
|
260
|
+
},
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
export type TopEventsParams = InferParams<typeof topEvents>;
|
|
264
|
+
export type TopEventsOutput = InferOutputRow<typeof topEvents>;
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Internal Pipes (not exposed as API)
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
import { definePipe, node } from "@tinybirdco/sdk";
|
|
271
|
+
|
|
272
|
+
export const filteredEvents = definePipe("filtered_events", {
|
|
273
|
+
description: "Filter events by date range",
|
|
274
|
+
params: {
|
|
275
|
+
start_date: p.dateTime(),
|
|
276
|
+
end_date: p.dateTime(),
|
|
277
|
+
},
|
|
278
|
+
nodes: [
|
|
279
|
+
node({
|
|
280
|
+
name: "filtered",
|
|
281
|
+
sql: `
|
|
282
|
+
SELECT * FROM events
|
|
283
|
+
WHERE timestamp >= {{DateTime(start_date)}}
|
|
284
|
+
AND timestamp <= {{DateTime(end_date)}}
|
|
285
|
+
`,
|
|
286
|
+
}),
|
|
287
|
+
],
|
|
288
|
+
});
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Materialized Views
|
|
292
|
+
|
|
293
|
+
```typescript
|
|
294
|
+
import { defineDatasource, defineMaterializedView, t, engine } from "@tinybirdco/sdk";
|
|
295
|
+
|
|
296
|
+
// Target datasource for the materialized view
|
|
297
|
+
export const dailyStats = defineDatasource("daily_stats", {
|
|
298
|
+
description: "Daily aggregated statistics",
|
|
299
|
+
schema: {
|
|
300
|
+
date: t.date(),
|
|
301
|
+
pathname: t.string(),
|
|
302
|
+
views: t.simpleAggregateFunction("sum", t.uint64()),
|
|
303
|
+
unique_sessions: t.aggregateFunction("uniq", t.string()),
|
|
304
|
+
},
|
|
305
|
+
engine: engine.aggregatingMergeTree({
|
|
306
|
+
sortingKey: ["date", "pathname"],
|
|
307
|
+
}),
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
// Materialized view that populates the datasource
|
|
311
|
+
export const dailyStatsMv = defineMaterializedView("daily_stats_mv", {
|
|
312
|
+
description: "Materialize daily page view aggregations",
|
|
313
|
+
datasource: dailyStats,
|
|
314
|
+
nodes: [
|
|
315
|
+
node({
|
|
316
|
+
name: "aggregate",
|
|
317
|
+
sql: `
|
|
318
|
+
SELECT
|
|
319
|
+
toDate(timestamp) AS date,
|
|
320
|
+
pathname,
|
|
321
|
+
count() AS views,
|
|
322
|
+
uniqState(session_id) AS unique_sessions
|
|
323
|
+
FROM page_views
|
|
324
|
+
GROUP BY date, pathname
|
|
325
|
+
`,
|
|
326
|
+
}),
|
|
327
|
+
],
|
|
328
|
+
});
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Copy Pipes
|
|
332
|
+
|
|
333
|
+
```typescript
|
|
334
|
+
import { defineCopyPipe, node } from "@tinybirdco/sdk";
|
|
335
|
+
|
|
336
|
+
// Scheduled copy pipe
|
|
337
|
+
export const dailySnapshot = defineCopyPipe("daily_snapshot", {
|
|
338
|
+
description: "Daily snapshot of statistics",
|
|
339
|
+
datasource: snapshotDatasource,
|
|
340
|
+
schedule: "0 0 * * *", // Run daily at midnight
|
|
341
|
+
mode: "append",
|
|
342
|
+
nodes: [
|
|
343
|
+
node({
|
|
344
|
+
name: "snapshot",
|
|
345
|
+
sql: `
|
|
346
|
+
SELECT today() AS snapshot_date, pathname, count() AS views
|
|
347
|
+
FROM page_views
|
|
348
|
+
WHERE toDate(timestamp) = today() - 1
|
|
349
|
+
GROUP BY pathname
|
|
350
|
+
`,
|
|
351
|
+
}),
|
|
352
|
+
],
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// On-demand copy pipe
|
|
356
|
+
export const manualReport = defineCopyPipe("manual_report", {
|
|
357
|
+
description: "On-demand report generation",
|
|
358
|
+
datasource: reportDatasource,
|
|
359
|
+
schedule: "@on-demand",
|
|
360
|
+
mode: "replace",
|
|
361
|
+
nodes: [
|
|
362
|
+
node({
|
|
363
|
+
name: "report",
|
|
364
|
+
sql: `SELECT * FROM events WHERE timestamp >= now() - interval 7 day`,
|
|
365
|
+
}),
|
|
366
|
+
],
|
|
367
|
+
});
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
## Type Validators
|
|
371
|
+
|
|
372
|
+
Use `t.*` to define column types with full TypeScript inference:
|
|
373
|
+
|
|
374
|
+
```typescript
|
|
375
|
+
import { t } from "@tinybirdco/sdk";
|
|
376
|
+
|
|
377
|
+
const schema = {
|
|
378
|
+
// Strings
|
|
379
|
+
name: t.string(),
|
|
380
|
+
id: t.uuid(),
|
|
381
|
+
code: t.fixedString(3),
|
|
382
|
+
|
|
383
|
+
// Numbers
|
|
384
|
+
count: t.int32(),
|
|
385
|
+
amount: t.float64(),
|
|
386
|
+
big_number: t.uint64(),
|
|
387
|
+
price: t.decimal(10, 2),
|
|
388
|
+
|
|
389
|
+
// Date/Time
|
|
390
|
+
created_at: t.dateTime(),
|
|
391
|
+
updated_at: t.dateTime64(3),
|
|
392
|
+
birth_date: t.date(),
|
|
393
|
+
|
|
394
|
+
// Boolean
|
|
395
|
+
is_active: t.bool(),
|
|
396
|
+
|
|
397
|
+
// Complex types
|
|
398
|
+
tags: t.array(t.string()),
|
|
399
|
+
metadata: t.map(t.string(), t.string()),
|
|
400
|
+
|
|
401
|
+
// Aggregate functions (for materialized views)
|
|
402
|
+
total: t.simpleAggregateFunction("sum", t.uint64()),
|
|
403
|
+
unique_users: t.aggregateFunction("uniq", t.string()),
|
|
404
|
+
|
|
405
|
+
// Modifiers
|
|
406
|
+
optional_field: t.string().nullable(),
|
|
407
|
+
category: t.string().lowCardinality(),
|
|
408
|
+
status: t.string().default("pending"),
|
|
409
|
+
};
|
|
410
|
+
```
|
|
411
|
+
|
|
412
|
+
## Parameter Validators
|
|
413
|
+
|
|
414
|
+
Use `p.*` to define pipe query parameters:
|
|
415
|
+
|
|
416
|
+
```typescript
|
|
417
|
+
import { p } from "@tinybirdco/sdk";
|
|
418
|
+
|
|
419
|
+
const params = {
|
|
420
|
+
// Required parameters
|
|
421
|
+
start_date: p.dateTime(),
|
|
422
|
+
user_id: p.string(),
|
|
423
|
+
|
|
424
|
+
// Optional with defaults
|
|
425
|
+
limit: p.int32().optional(10),
|
|
426
|
+
offset: p.int32().optional(0),
|
|
427
|
+
|
|
428
|
+
// With descriptions (for documentation)
|
|
429
|
+
status: p.string().optional("active").describe("Filter by status"),
|
|
430
|
+
};
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
## Engine Configurations
|
|
434
|
+
|
|
435
|
+
```typescript
|
|
436
|
+
import { engine } from "@tinybirdco/sdk";
|
|
437
|
+
|
|
438
|
+
// MergeTree (default)
|
|
439
|
+
engine.mergeTree({
|
|
440
|
+
sortingKey: ["user_id", "timestamp"],
|
|
441
|
+
partitionKey: "toYYYYMM(timestamp)",
|
|
442
|
+
ttl: "timestamp + INTERVAL 90 DAY",
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
// ReplacingMergeTree (for upserts)
|
|
446
|
+
engine.replacingMergeTree({
|
|
447
|
+
sortingKey: ["id"],
|
|
448
|
+
version: "updated_at",
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
// SummingMergeTree (for pre-aggregation)
|
|
452
|
+
engine.summingMergeTree({
|
|
453
|
+
sortingKey: ["date", "category"],
|
|
454
|
+
columns: ["count", "total"],
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
// AggregatingMergeTree (for complex aggregates)
|
|
458
|
+
engine.aggregatingMergeTree({
|
|
459
|
+
sortingKey: ["date"],
|
|
460
|
+
});
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
## Next.js Integration
|
|
464
|
+
|
|
465
|
+
For Next.js projects, add these scripts to your `package.json`:
|
|
466
|
+
|
|
467
|
+
```json
|
|
468
|
+
{
|
|
469
|
+
"scripts": {
|
|
470
|
+
"dev": "concurrently -n next,tinybird \"next dev\" \"dotenv -e .env.local -- npx tinybird dev\"",
|
|
471
|
+
"tinybird:build": "dotenv -e .env.local -- npx tinybird build"
|
|
472
|
+
},
|
|
473
|
+
"devDependencies": {
|
|
474
|
+
"concurrently": "^9.0.0",
|
|
475
|
+
"dotenv-cli": "^11.0.0"
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
Add the path alias to `tsconfig.json`:
|
|
481
|
+
|
|
482
|
+
```json
|
|
483
|
+
{
|
|
484
|
+
"compilerOptions": {
|
|
485
|
+
"paths": {
|
|
486
|
+
"@/*": ["./src/*"],
|
|
487
|
+
"@tinybird/client": ["./src/tinybird/client.ts"]
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
Now `npm run dev` starts both Next.js and Tinybird sync together.
|
|
494
|
+
|
|
495
|
+
## Type Inference
|
|
496
|
+
|
|
497
|
+
The SDK provides full type inference for your schemas:
|
|
498
|
+
|
|
499
|
+
```typescript
|
|
500
|
+
import { type InferRow, type InferParams, type InferOutputRow } from "@tinybirdco/sdk";
|
|
501
|
+
import { pageViews, topPages } from "./tinybird/datasources";
|
|
502
|
+
|
|
503
|
+
// Infer the row type for a datasource
|
|
504
|
+
type PageViewRow = InferRow<typeof pageViews>;
|
|
505
|
+
// { timestamp: Date, pathname: string, session_id: string, country: string | null }
|
|
506
|
+
|
|
507
|
+
// Infer the parameters for a pipe
|
|
508
|
+
type TopPagesParams = InferParams<typeof topPages>;
|
|
509
|
+
// { start_date: Date, end_date: Date, limit?: number }
|
|
510
|
+
|
|
511
|
+
// Infer the output type for a pipe
|
|
512
|
+
type TopPagesOutput = InferOutputRow<typeof topPages>;
|
|
513
|
+
// { pathname: string, views: bigint }
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
## License
|
|
517
|
+
|
|
518
|
+
MIT
|
package/bin/tinybird.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tinybird Branch (Environment) API client
|
|
3
|
+
* Uses the /v1/environments endpoints (Forward API)
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Branch information from Tinybird API
|
|
7
|
+
*/
|
|
8
|
+
export interface TinybirdBranch {
|
|
9
|
+
/** Branch ID */
|
|
10
|
+
id: string;
|
|
11
|
+
/** Branch name */
|
|
12
|
+
name: string;
|
|
13
|
+
/** Branch token (only present when requested with with_token=true) */
|
|
14
|
+
token?: string;
|
|
15
|
+
/** When the branch was created */
|
|
16
|
+
created_at: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Result of getOrCreateBranch operation
|
|
20
|
+
*/
|
|
21
|
+
export interface GetOrCreateBranchResult extends TinybirdBranch {
|
|
22
|
+
/** Whether the branch was newly created (vs already existed) */
|
|
23
|
+
wasCreated: boolean;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* API configuration for branch operations
|
|
27
|
+
*/
|
|
28
|
+
export interface BranchApiConfig {
|
|
29
|
+
/** Tinybird API base URL */
|
|
30
|
+
baseUrl: string;
|
|
31
|
+
/** Parent workspace token (used to create/manage branches) */
|
|
32
|
+
token: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Error thrown by branch API operations
|
|
36
|
+
*/
|
|
37
|
+
export declare class BranchApiError extends Error {
|
|
38
|
+
readonly status: number;
|
|
39
|
+
readonly body?: unknown | undefined;
|
|
40
|
+
constructor(message: string, status: number, body?: unknown | undefined);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Create a new branch
|
|
44
|
+
* POST /v1/environments?name={name}
|
|
45
|
+
*
|
|
46
|
+
* This is an async operation that returns a job. We poll the job until
|
|
47
|
+
* it completes, then fetch the branch with its token.
|
|
48
|
+
*
|
|
49
|
+
* @param config - API configuration
|
|
50
|
+
* @param name - Branch name to create
|
|
51
|
+
* @returns The created branch with token
|
|
52
|
+
*/
|
|
53
|
+
export declare function createBranch(config: BranchApiConfig, name: string): Promise<TinybirdBranch>;
|
|
54
|
+
/**
|
|
55
|
+
* List all branches in the workspace
|
|
56
|
+
* GET /v1/environments
|
|
57
|
+
*
|
|
58
|
+
* @param config - API configuration
|
|
59
|
+
* @returns Array of branches
|
|
60
|
+
*/
|
|
61
|
+
export declare function listBranches(config: BranchApiConfig): Promise<TinybirdBranch[]>;
|
|
62
|
+
/**
|
|
63
|
+
* Get a branch by name with its token
|
|
64
|
+
* GET /v0/environments/{name}?with_token=true
|
|
65
|
+
*
|
|
66
|
+
* @param config - API configuration
|
|
67
|
+
* @param name - Branch name
|
|
68
|
+
* @returns Branch with token
|
|
69
|
+
*/
|
|
70
|
+
export declare function getBranch(config: BranchApiConfig, name: string): Promise<TinybirdBranch>;
|
|
71
|
+
/**
|
|
72
|
+
* Delete a branch
|
|
73
|
+
* DELETE /v1/environments/{name}
|
|
74
|
+
*
|
|
75
|
+
* @param config - API configuration
|
|
76
|
+
* @param name - Branch name to delete
|
|
77
|
+
*/
|
|
78
|
+
export declare function deleteBranch(config: BranchApiConfig, name: string): Promise<void>;
|
|
79
|
+
/**
|
|
80
|
+
* Check if a branch exists
|
|
81
|
+
*
|
|
82
|
+
* @param config - API configuration
|
|
83
|
+
* @param name - Branch name to check
|
|
84
|
+
* @returns true if branch exists, false if not
|
|
85
|
+
* @throws BranchApiError on API/network/auth failures
|
|
86
|
+
*/
|
|
87
|
+
export declare function branchExists(config: BranchApiConfig, name: string): Promise<boolean>;
|
|
88
|
+
/**
|
|
89
|
+
* Get or create a branch
|
|
90
|
+
* If the branch exists, returns it with token.
|
|
91
|
+
* If it doesn't exist, creates it.
|
|
92
|
+
*
|
|
93
|
+
* @param config - API configuration
|
|
94
|
+
* @param name - Branch name
|
|
95
|
+
* @returns Branch with token
|
|
96
|
+
*/
|
|
97
|
+
export declare function getOrCreateBranch(config: BranchApiConfig, name: string): Promise<GetOrCreateBranchResult>;
|
|
98
|
+
//# sourceMappingURL=branches.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"branches.d.ts","sourceRoot":"","sources":["../../src/api/branches.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,gBAAgB;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,kBAAkB;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAwB,SAAQ,cAAc;IAC7D,gEAAgE;IAChE,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,4BAA4B;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;CACf;AAyBD;;GAEG;AACH,qBAAa,cAAe,SAAQ,KAAK;aAGrB,MAAM,EAAE,MAAM;aACd,IAAI,CAAC,EAAE,OAAO;gBAF9B,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,OAAO,YAAA;CAKjC;AA4DD;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,cAAc,CAAC,CA+CzB;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,eAAe,GACtB,OAAO,CAAC,cAAc,EAAE,CAAC,CAqB3B;AAED;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,cAAc,CAAC,CAsBzB;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,OAAO,CAAC,CAGlB;AAED;;;;;;;;GAQG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,uBAAuB,CAAC,CAalC"}
|