@tinybirdco/sdk 0.0.19 → 0.0.20
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 +47 -0
- package/dist/api/api.d.ts +89 -0
- package/dist/api/api.d.ts.map +1 -0
- package/dist/api/api.js +218 -0
- package/dist/api/api.js.map +1 -0
- package/dist/api/api.test.d.ts +2 -0
- package/dist/api/api.test.d.ts.map +1 -0
- package/dist/api/api.test.js +226 -0
- package/dist/api/api.test.js.map +1 -0
- package/dist/client/base.d.ts +3 -17
- package/dist/client/base.d.ts.map +1 -1
- package/dist/client/base.js +31 -153
- package/dist/client/base.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +7 -2
- package/src/api/api.test.ts +295 -0
- package/src/api/api.ts +345 -0
- package/src/client/base.ts +34 -181
- package/src/index.ts +14 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/client/base.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,aAAa,
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/client/base.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,aAAa,EACd,MAAM,YAAY,CAAC;AAapB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IACtC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkC;IAC9D,OAAO,CAAC,YAAY,CAA2C;IAC/D,OAAO,CAAC,aAAa,CAAuB;gBAEhC,MAAM,EAAE,YAAY;IAgBhC;;OAEG;YACW,QAAQ;IAsBtB;;OAEG;YACW,kBAAkB;IAsChC;;;;;;;OAOG;IACG,KAAK,CAAC,CAAC,GAAG,OAAO,EACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EACpC,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAU1B;;;;;;;OAOG;IACG,MAAM,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5C,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,CAAC,EACR,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC;IAIxB;;;;;;;OAOG;IACG,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjD,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,CAAC,EAAE,EACX,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,YAAY,CAAC;IAUxB;;;;;;OAMG;IACG,GAAG,CAAC,CAAC,GAAG,OAAO,EACnB,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAU1B,OAAO,CAAC,MAAM;IAiBd,OAAO,CAAC,eAAe;CAWxB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,cAAc,CAEjE"}
|
package/dist/client/base.js
CHANGED
|
@@ -2,11 +2,7 @@
|
|
|
2
2
|
* Tinybird client for querying pipes and ingesting events
|
|
3
3
|
*/
|
|
4
4
|
import { TinybirdError } from "./types.js";
|
|
5
|
-
import {
|
|
6
|
-
/**
|
|
7
|
-
* Default timeout for requests (30 seconds)
|
|
8
|
-
*/
|
|
9
|
-
const DEFAULT_TIMEOUT = 30000;
|
|
5
|
+
import { TinybirdApi, TinybirdApiError } from "../api/api.js";
|
|
10
6
|
/**
|
|
11
7
|
* Tinybird API client
|
|
12
8
|
*
|
|
@@ -37,7 +33,7 @@ const DEFAULT_TIMEOUT = 30000;
|
|
|
37
33
|
*/
|
|
38
34
|
export class TinybirdClient {
|
|
39
35
|
config;
|
|
40
|
-
|
|
36
|
+
apisByToken = new Map();
|
|
41
37
|
tokenPromise = null;
|
|
42
38
|
resolvedToken = null;
|
|
43
39
|
constructor(config) {
|
|
@@ -53,7 +49,6 @@ export class TinybirdClient {
|
|
|
53
49
|
...config,
|
|
54
50
|
baseUrl: config.baseUrl.replace(/\/$/, ""),
|
|
55
51
|
};
|
|
56
|
-
this.fetchFn = createTinybirdFetcher(config.fetch ?? globalThis.fetch);
|
|
57
52
|
}
|
|
58
53
|
/**
|
|
59
54
|
* Get the effective token, resolving branch token in dev mode if needed
|
|
@@ -118,37 +113,12 @@ export class TinybirdClient {
|
|
|
118
113
|
*/
|
|
119
114
|
async query(pipeName, params = {}, options = {}) {
|
|
120
115
|
const token = await this.getToken();
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
for (const [key, value] of Object.entries(params)) {
|
|
124
|
-
if (value !== undefined && value !== null) {
|
|
125
|
-
if (Array.isArray(value)) {
|
|
126
|
-
// Handle array parameters
|
|
127
|
-
for (const item of value) {
|
|
128
|
-
url.searchParams.append(key, String(item));
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
else if (value instanceof Date) {
|
|
132
|
-
// Handle Date objects
|
|
133
|
-
url.searchParams.set(key, value.toISOString());
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
url.searchParams.set(key, String(value));
|
|
137
|
-
}
|
|
138
|
-
}
|
|
116
|
+
try {
|
|
117
|
+
return await this.getApi(token).query(pipeName, params, options);
|
|
139
118
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
headers: {
|
|
143
|
-
Authorization: `Bearer ${token}`,
|
|
144
|
-
},
|
|
145
|
-
signal: this.createAbortSignal(options.timeout, options.signal),
|
|
146
|
-
});
|
|
147
|
-
if (!response.ok) {
|
|
148
|
-
await this.handleErrorResponse(response);
|
|
119
|
+
catch (error) {
|
|
120
|
+
this.rethrowApiError(error);
|
|
149
121
|
}
|
|
150
|
-
const result = (await response.json());
|
|
151
|
-
return result;
|
|
152
122
|
}
|
|
153
123
|
/**
|
|
154
124
|
* Ingest a single event to a datasource
|
|
@@ -170,33 +140,13 @@ export class TinybirdClient {
|
|
|
170
140
|
* @returns Ingest result
|
|
171
141
|
*/
|
|
172
142
|
async ingestBatch(datasourceName, events, options = {}) {
|
|
173
|
-
if (events.length === 0) {
|
|
174
|
-
return { successful_rows: 0, quarantined_rows: 0 };
|
|
175
|
-
}
|
|
176
143
|
const token = await this.getToken();
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
if (options.wait !== false) {
|
|
180
|
-
url.searchParams.set("wait", "true");
|
|
144
|
+
try {
|
|
145
|
+
return await this.getApi(token).ingestBatch(datasourceName, events, options);
|
|
181
146
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
.map((event) => JSON.stringify(this.serializeEvent(event)))
|
|
185
|
-
.join("\n");
|
|
186
|
-
const response = await this.fetch(url.toString(), {
|
|
187
|
-
method: "POST",
|
|
188
|
-
headers: {
|
|
189
|
-
Authorization: `Bearer ${token}`,
|
|
190
|
-
"Content-Type": "application/x-ndjson",
|
|
191
|
-
},
|
|
192
|
-
body: ndjson,
|
|
193
|
-
signal: this.createAbortSignal(options.timeout, options.signal),
|
|
194
|
-
});
|
|
195
|
-
if (!response.ok) {
|
|
196
|
-
await this.handleErrorResponse(response);
|
|
147
|
+
catch (error) {
|
|
148
|
+
this.rethrowApiError(error);
|
|
197
149
|
}
|
|
198
|
-
const result = (await response.json());
|
|
199
|
-
return result;
|
|
200
150
|
}
|
|
201
151
|
/**
|
|
202
152
|
* Execute a raw SQL query
|
|
@@ -207,104 +157,32 @@ export class TinybirdClient {
|
|
|
207
157
|
*/
|
|
208
158
|
async sql(sql, options = {}) {
|
|
209
159
|
const token = await this.getToken();
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
method: "POST",
|
|
213
|
-
headers: {
|
|
214
|
-
Authorization: `Bearer ${token}`,
|
|
215
|
-
"Content-Type": "text/plain",
|
|
216
|
-
},
|
|
217
|
-
body: sql,
|
|
218
|
-
signal: this.createAbortSignal(options.timeout, options.signal),
|
|
219
|
-
});
|
|
220
|
-
if (!response.ok) {
|
|
221
|
-
await this.handleErrorResponse(response);
|
|
160
|
+
try {
|
|
161
|
+
return await this.getApi(token).sql(sql, options);
|
|
222
162
|
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Serialize an event for ingestion, handling Date objects and other special types
|
|
228
|
-
*/
|
|
229
|
-
serializeEvent(event) {
|
|
230
|
-
const serialized = {};
|
|
231
|
-
for (const [key, value] of Object.entries(event)) {
|
|
232
|
-
if (value instanceof Date) {
|
|
233
|
-
// Convert Date to ISO string
|
|
234
|
-
serialized[key] = value.toISOString();
|
|
235
|
-
}
|
|
236
|
-
else if (value instanceof Map) {
|
|
237
|
-
// Convert Map to object
|
|
238
|
-
serialized[key] = Object.fromEntries(value);
|
|
239
|
-
}
|
|
240
|
-
else if (typeof value === "bigint") {
|
|
241
|
-
// Convert BigInt to string (ClickHouse will parse it)
|
|
242
|
-
serialized[key] = value.toString();
|
|
243
|
-
}
|
|
244
|
-
else if (Array.isArray(value)) {
|
|
245
|
-
// Recursively serialize array elements
|
|
246
|
-
serialized[key] = value.map((item) => typeof item === "object" && item !== null
|
|
247
|
-
? this.serializeEvent(item)
|
|
248
|
-
: item instanceof Date
|
|
249
|
-
? item.toISOString()
|
|
250
|
-
: item);
|
|
251
|
-
}
|
|
252
|
-
else if (typeof value === "object" && value !== null) {
|
|
253
|
-
// Recursively serialize nested objects
|
|
254
|
-
serialized[key] = this.serializeEvent(value);
|
|
255
|
-
}
|
|
256
|
-
else {
|
|
257
|
-
serialized[key] = value;
|
|
258
|
-
}
|
|
163
|
+
catch (error) {
|
|
164
|
+
this.rethrowApiError(error);
|
|
259
165
|
}
|
|
260
|
-
return serialized;
|
|
261
166
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
// Create timeout signal
|
|
276
|
-
const timeoutSignal = AbortSignal.timeout(timeoutMs);
|
|
277
|
-
// If only timeout, return timeout signal
|
|
278
|
-
if (!existingSignal) {
|
|
279
|
-
return timeoutSignal;
|
|
280
|
-
}
|
|
281
|
-
// Combine both signals
|
|
282
|
-
return AbortSignal.any([timeoutSignal, existingSignal]);
|
|
167
|
+
getApi(token) {
|
|
168
|
+
const existing = this.apisByToken.get(token);
|
|
169
|
+
if (existing) {
|
|
170
|
+
return existing;
|
|
171
|
+
}
|
|
172
|
+
const api = new TinybirdApi({
|
|
173
|
+
baseUrl: this.config.baseUrl,
|
|
174
|
+
token,
|
|
175
|
+
fetch: this.config.fetch,
|
|
176
|
+
timeout: this.config.timeout,
|
|
177
|
+
});
|
|
178
|
+
this.apisByToken.set(token, api);
|
|
179
|
+
return api;
|
|
283
180
|
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
async handleErrorResponse(response) {
|
|
288
|
-
let errorResponse;
|
|
289
|
-
let rawBody;
|
|
290
|
-
try {
|
|
291
|
-
rawBody = await response.text();
|
|
292
|
-
errorResponse = JSON.parse(rawBody);
|
|
293
|
-
}
|
|
294
|
-
catch {
|
|
295
|
-
// Failed to parse error response - include raw body in message
|
|
296
|
-
if (rawBody) {
|
|
297
|
-
throw new TinybirdError(`Request failed with status ${response.status}: ${rawBody}`, response.status, undefined);
|
|
298
|
-
}
|
|
181
|
+
rethrowApiError(error) {
|
|
182
|
+
if (error instanceof TinybirdApiError) {
|
|
183
|
+
throw new TinybirdError(error.message, error.statusCode, error.response);
|
|
299
184
|
}
|
|
300
|
-
|
|
301
|
-
throw new TinybirdError(message, response.status, errorResponse);
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Internal fetch wrapper
|
|
305
|
-
*/
|
|
306
|
-
fetch(url, init) {
|
|
307
|
-
return this.fetchFn(url, init);
|
|
185
|
+
throw error;
|
|
308
186
|
}
|
|
309
187
|
}
|
|
310
188
|
/**
|
package/dist/client/base.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/client/base.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/client/base.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -75,5 +75,7 @@ export type { Infer, InferRow, InferParams, InferOutput, InferOutputRow, InferEv
|
|
|
75
75
|
export { TinybirdClient, createClient } from "./client/base.js";
|
|
76
76
|
export { TinybirdError } from "./client/types.js";
|
|
77
77
|
export type { ClientConfig, QueryResult, IngestResult, QueryOptions, IngestOptions, ColumnMeta, QueryStatistics, TinybirdErrorResponse, TypedPipeEndpoint, TypedDatasourceIngest, } from "./client/types.js";
|
|
78
|
+
export { TinybirdApi, TinybirdApiError, createTinybirdApi, createTinybirdApiWrapper, } from "./api/api.js";
|
|
79
|
+
export type { TinybirdApiConfig, TinybirdApiQueryOptions, TinybirdApiIngestOptions, TinybirdApiRequestInit, } from "./api/api.js";
|
|
78
80
|
export { isPreviewEnvironment, getPreviewBranchName, resolveToken, clearTokenCache, } from "./client/preview.js";
|
|
79
81
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -74,6 +74,8 @@ export { defineProject, isProjectDefinition, getDatasourceNames, getPipeNames, g
|
|
|
74
74
|
// ============ Client ============
|
|
75
75
|
export { TinybirdClient, createClient } from "./client/base.js";
|
|
76
76
|
export { TinybirdError } from "./client/types.js";
|
|
77
|
+
// ============ Public Tinybird API ============
|
|
78
|
+
export { TinybirdApi, TinybirdApiError, createTinybirdApi, createTinybirdApiWrapper, } from "./api/api.js";
|
|
77
79
|
// ============ Preview Environment ============
|
|
78
80
|
export { isPreviewEnvironment, getPreviewBranchName, resolveToken, clearTokenCache, } from "./client/preview.js";
|
|
79
81
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,yCAAyC;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAQtC,OAAO,EACL,eAAe,EACf,eAAe,EACf,YAAY,GACb,MAAM,mBAAmB,CAAC;AAE3B,4CAA4C;AAC5C,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAC;AAMvC,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAE5B,kDAAkD;AAClD,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAY5F,uCAAuC;AACvC,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAa5I,uCAAuC;AACvC,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AASvI,kCAAkC;AAClC,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAOnE,iCAAiC;AACjC,OAAO,EACL,UAAU,EACV,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,IAAI,EACJ,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,UAAU,EACV,YAAY,EACZ,OAAO,EACP,GAAG,GACJ,MAAM,kBAAkB,CAAC;AAqB1B,oCAAoC;AACpC,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AA8BzJ,mCAAmC;AACnC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAclD,gDAAgD;AAChD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,EACZ,eAAe,GAChB,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,yCAAyC;AACzC,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAQtC,OAAO,EACL,eAAe,EACf,eAAe,EACf,YAAY,GACb,MAAM,mBAAmB,CAAC;AAE3B,4CAA4C;AAC5C,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAC;AAMvC,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,eAAe,EACf,mBAAmB,GACpB,MAAM,oBAAoB,CAAC;AAE5B,kDAAkD;AAClD,OAAO,EAAE,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAY5F,uCAAuC;AACvC,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAa5I,uCAAuC;AACvC,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AASvI,kCAAkC;AAClC,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAOnE,iCAAiC;AACjC,OAAO,EACL,UAAU,EACV,cAAc,EACd,sBAAsB,EACtB,cAAc,EACd,IAAI,EACJ,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,UAAU,EACV,YAAY,EACZ,OAAO,EACP,GAAG,GACJ,MAAM,kBAAkB,CAAC;AAqB1B,oCAAoC;AACpC,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AA8BzJ,mCAAmC;AACnC,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAclD,gDAAgD;AAChD,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,cAAc,CAAC;AAQtB,gDAAgD;AAChD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,YAAY,EACZ,eAAe,GAChB,MAAM,qBAAqB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tinybirdco/sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.20",
|
|
4
4
|
"description": "TypeScript SDK for Tinybird Forward - define datasources and pipes as TypeScript",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -13,6 +13,10 @@
|
|
|
13
13
|
".": {
|
|
14
14
|
"import": "./dist/index.js",
|
|
15
15
|
"types": "./dist/index.d.ts"
|
|
16
|
+
},
|
|
17
|
+
"./api": {
|
|
18
|
+
"import": "./dist/api/api.js",
|
|
19
|
+
"types": "./dist/api/api.d.ts"
|
|
16
20
|
}
|
|
17
21
|
},
|
|
18
22
|
"files": [
|
|
@@ -36,7 +40,8 @@
|
|
|
36
40
|
"commander": "^12.0.0",
|
|
37
41
|
"dotenv": "^16.0.0",
|
|
38
42
|
"esbuild": "^0.24.0",
|
|
39
|
-
"picocolors": "^1.1.1"
|
|
43
|
+
"picocolors": "^1.1.1",
|
|
44
|
+
"zod": "^3.25.0"
|
|
40
45
|
},
|
|
41
46
|
"devDependencies": {
|
|
42
47
|
"@types/node": "^20.0.0",
|
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest";
|
|
2
|
+
import { setupServer } from "msw/node";
|
|
3
|
+
import { http, HttpResponse } from "msw";
|
|
4
|
+
import { createTinybirdApi } from "./api.js";
|
|
5
|
+
import { TINYBIRD_FROM_PARAM } from "./fetcher.js";
|
|
6
|
+
import { BASE_URL } from "../test/handlers.js";
|
|
7
|
+
|
|
8
|
+
const server = setupServer();
|
|
9
|
+
|
|
10
|
+
beforeAll(() => server.listen({ onUnhandledRequest: "error" }));
|
|
11
|
+
afterEach(() => server.resetHandlers());
|
|
12
|
+
afterAll(() => server.close());
|
|
13
|
+
|
|
14
|
+
describe("TinybirdApi", () => {
|
|
15
|
+
it("sends authorization header and from=ts-sdk param", async () => {
|
|
16
|
+
let authorizationHeader: string | null = null;
|
|
17
|
+
let fromParam: string | null = null;
|
|
18
|
+
|
|
19
|
+
server.use(
|
|
20
|
+
http.get(`${BASE_URL}/v1/workspace`, ({ request }) => {
|
|
21
|
+
authorizationHeader = request.headers.get("Authorization");
|
|
22
|
+
const url = new URL(request.url);
|
|
23
|
+
fromParam = url.searchParams.get("from");
|
|
24
|
+
return HttpResponse.json({ ok: true });
|
|
25
|
+
})
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const api = createTinybirdApi({
|
|
29
|
+
baseUrl: BASE_URL,
|
|
30
|
+
token: "p.default-token",
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
await api.request("/v1/workspace");
|
|
34
|
+
|
|
35
|
+
expect(authorizationHeader).toBe("Bearer p.default-token");
|
|
36
|
+
expect(fromParam).toBe(TINYBIRD_FROM_PARAM);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it("resolves relative paths and preserves query params", async () => {
|
|
40
|
+
let fooParam: string | null = null;
|
|
41
|
+
let fromParam: string | null = null;
|
|
42
|
+
|
|
43
|
+
server.use(
|
|
44
|
+
http.get(`${BASE_URL}/v1/build`, ({ request }) => {
|
|
45
|
+
const url = new URL(request.url);
|
|
46
|
+
fooParam = url.searchParams.get("foo");
|
|
47
|
+
fromParam = url.searchParams.get("from");
|
|
48
|
+
return HttpResponse.json({ ok: true });
|
|
49
|
+
})
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
const api = createTinybirdApi({
|
|
53
|
+
baseUrl: `${BASE_URL}/`,
|
|
54
|
+
token: "p.default-token",
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
await api.request("v1/build?foo=bar");
|
|
58
|
+
|
|
59
|
+
expect(fooParam).toBe("bar");
|
|
60
|
+
expect(fromParam).toBe(TINYBIRD_FROM_PARAM);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("allows per-request token override", async () => {
|
|
64
|
+
let authorizationHeader: string | null = null;
|
|
65
|
+
|
|
66
|
+
server.use(
|
|
67
|
+
http.get(`${BASE_URL}/v1/workspace`, ({ request }) => {
|
|
68
|
+
authorizationHeader = request.headers.get("Authorization");
|
|
69
|
+
return HttpResponse.json({ ok: true });
|
|
70
|
+
})
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
const api = createTinybirdApi({
|
|
74
|
+
baseUrl: BASE_URL,
|
|
75
|
+
token: "p.default-token",
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
await api.request("/v1/workspace", { token: "p.override-token" });
|
|
79
|
+
|
|
80
|
+
expect(authorizationHeader).toBe("Bearer p.override-token");
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it("queries endpoint params via tinybirdApi.query", async () => {
|
|
84
|
+
let fromParam: string | null = null;
|
|
85
|
+
let startDateParam: string | null = null;
|
|
86
|
+
let limitParam: string | null = null;
|
|
87
|
+
let tagsParams: string[] = [];
|
|
88
|
+
|
|
89
|
+
server.use(
|
|
90
|
+
http.get(`${BASE_URL}/v0/pipes/top_pages.json`, ({ request }) => {
|
|
91
|
+
const url = new URL(request.url);
|
|
92
|
+
fromParam = url.searchParams.get("from");
|
|
93
|
+
startDateParam = url.searchParams.get("start_date");
|
|
94
|
+
limitParam = url.searchParams.get("limit");
|
|
95
|
+
tagsParams = url.searchParams.getAll("tags");
|
|
96
|
+
|
|
97
|
+
return HttpResponse.json({
|
|
98
|
+
data: [{ pathname: "/", views: 1 }],
|
|
99
|
+
meta: [
|
|
100
|
+
{ name: "pathname", type: "String" },
|
|
101
|
+
{ name: "views", type: "UInt64" },
|
|
102
|
+
],
|
|
103
|
+
rows: 1,
|
|
104
|
+
statistics: {
|
|
105
|
+
elapsed: 0.001,
|
|
106
|
+
rows_read: 1,
|
|
107
|
+
bytes_read: 10,
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
})
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
const api = createTinybirdApi({
|
|
114
|
+
baseUrl: BASE_URL,
|
|
115
|
+
token: "p.default-token",
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
const result = await api.query<{ pathname: string; views: number }>("top_pages", {
|
|
119
|
+
start_date: new Date("2024-01-01T00:00:00.000Z"),
|
|
120
|
+
limit: 5,
|
|
121
|
+
tags: ["a", "b"],
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
expect(result.rows).toBe(1);
|
|
125
|
+
expect(result.data[0]).toEqual({ pathname: "/", views: 1 });
|
|
126
|
+
expect(fromParam).toBe(TINYBIRD_FROM_PARAM);
|
|
127
|
+
expect(startDateParam).toBe("2024-01-01T00:00:00.000Z");
|
|
128
|
+
expect(limitParam).toBe("5");
|
|
129
|
+
expect(tagsParams).toEqual(["a", "b"]);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("ingests rows via tinybirdApi.ingest", async () => {
|
|
133
|
+
let datasourceName: string | null = null;
|
|
134
|
+
let waitParam: string | null = null;
|
|
135
|
+
let fromParam: string | null = null;
|
|
136
|
+
let contentType: string | null = null;
|
|
137
|
+
let parsedBody: Record<string, unknown> | null = null;
|
|
138
|
+
|
|
139
|
+
server.use(
|
|
140
|
+
http.post(`${BASE_URL}/v0/events`, async ({ request }) => {
|
|
141
|
+
const url = new URL(request.url);
|
|
142
|
+
datasourceName = url.searchParams.get("name");
|
|
143
|
+
waitParam = url.searchParams.get("wait");
|
|
144
|
+
fromParam = url.searchParams.get("from");
|
|
145
|
+
contentType = request.headers.get("content-type");
|
|
146
|
+
|
|
147
|
+
const rawBody = await request.text();
|
|
148
|
+
parsedBody = JSON.parse(rawBody);
|
|
149
|
+
|
|
150
|
+
return HttpResponse.json({
|
|
151
|
+
successful_rows: 1,
|
|
152
|
+
quarantined_rows: 0,
|
|
153
|
+
});
|
|
154
|
+
})
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
const api = createTinybirdApi({
|
|
158
|
+
baseUrl: BASE_URL,
|
|
159
|
+
token: "p.default-token",
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
const result = await api.ingest("events", {
|
|
163
|
+
timestamp: new Date("2024-01-01T00:00:00.000Z"),
|
|
164
|
+
count: 10n,
|
|
165
|
+
payload: new Map([["k", "v"]]),
|
|
166
|
+
nested: {
|
|
167
|
+
when: new Date("2024-01-02T00:00:00.000Z"),
|
|
168
|
+
},
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
expect(result).toEqual({ successful_rows: 1, quarantined_rows: 0 });
|
|
172
|
+
expect(datasourceName).toBe("events");
|
|
173
|
+
expect(waitParam).toBe("true");
|
|
174
|
+
expect(fromParam).toBe(TINYBIRD_FROM_PARAM);
|
|
175
|
+
expect(contentType).toBe("application/x-ndjson");
|
|
176
|
+
expect(parsedBody).toEqual({
|
|
177
|
+
timestamp: "2024-01-01T00:00:00.000Z",
|
|
178
|
+
count: "10",
|
|
179
|
+
payload: { k: "v" },
|
|
180
|
+
nested: { when: "2024-01-02T00:00:00.000Z" },
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it("executes raw SQL via tinybirdApi.sql", async () => {
|
|
185
|
+
let rawSql: string | null = null;
|
|
186
|
+
let contentType: string | null = null;
|
|
187
|
+
|
|
188
|
+
server.use(
|
|
189
|
+
http.post(`${BASE_URL}/v0/sql`, async ({ request }) => {
|
|
190
|
+
contentType = request.headers.get("content-type");
|
|
191
|
+
rawSql = await request.text();
|
|
192
|
+
|
|
193
|
+
return HttpResponse.json({
|
|
194
|
+
data: [{ value: 1 }],
|
|
195
|
+
meta: [{ name: "value", type: "UInt8" }],
|
|
196
|
+
rows: 1,
|
|
197
|
+
statistics: {
|
|
198
|
+
elapsed: 0.001,
|
|
199
|
+
rows_read: 1,
|
|
200
|
+
bytes_read: 1,
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
})
|
|
204
|
+
);
|
|
205
|
+
|
|
206
|
+
const api = createTinybirdApi({
|
|
207
|
+
baseUrl: BASE_URL,
|
|
208
|
+
token: "p.default-token",
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
const result = await api.sql<{ value: number }>("SELECT 1 AS value");
|
|
212
|
+
|
|
213
|
+
expect(result.data[0]?.value).toBe(1);
|
|
214
|
+
expect(contentType).toBe("text/plain");
|
|
215
|
+
expect(rawSql).toBe("SELECT 1 AS value");
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
it("returns zero counts for empty ingest batches", async () => {
|
|
219
|
+
const api = createTinybirdApi({
|
|
220
|
+
baseUrl: BASE_URL,
|
|
221
|
+
token: "p.default-token",
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
const result = await api.ingestBatch("events", []);
|
|
225
|
+
|
|
226
|
+
expect(result).toEqual({ successful_rows: 0, quarantined_rows: 0 });
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it("parses JSON responses", async () => {
|
|
230
|
+
server.use(
|
|
231
|
+
http.get(`${BASE_URL}/v1/workspace`, () => {
|
|
232
|
+
return HttpResponse.json({ id: "ws_123", name: "main" });
|
|
233
|
+
})
|
|
234
|
+
);
|
|
235
|
+
|
|
236
|
+
const api = createTinybirdApi({
|
|
237
|
+
baseUrl: BASE_URL,
|
|
238
|
+
token: "p.default-token",
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
const result = await api.requestJson<{ id: string; name: string }>("/v1/workspace");
|
|
242
|
+
|
|
243
|
+
expect(result.id).toBe("ws_123");
|
|
244
|
+
expect(result.name).toBe("main");
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
it("throws TinybirdApiError for non-OK responses", async () => {
|
|
248
|
+
server.use(
|
|
249
|
+
http.get(`${BASE_URL}/v1/workspace`, () => {
|
|
250
|
+
return new HttpResponse("Unauthorized", { status: 401 });
|
|
251
|
+
})
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
const api = createTinybirdApi({
|
|
255
|
+
baseUrl: BASE_URL,
|
|
256
|
+
token: "p.default-token",
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
await expect(api.requestJson("/v1/workspace")).rejects.toMatchObject({
|
|
260
|
+
name: "TinybirdApiError",
|
|
261
|
+
statusCode: 401,
|
|
262
|
+
responseBody: "Unauthorized",
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
it("throws TinybirdApiError with parsed API details", async () => {
|
|
267
|
+
server.use(
|
|
268
|
+
http.get(`${BASE_URL}/v0/pipes/broken.json`, () => {
|
|
269
|
+
return HttpResponse.json(
|
|
270
|
+
{
|
|
271
|
+
error: "Invalid query",
|
|
272
|
+
status: 400,
|
|
273
|
+
documentation: "https://www.tinybird.co/docs",
|
|
274
|
+
},
|
|
275
|
+
{ status: 400 }
|
|
276
|
+
);
|
|
277
|
+
})
|
|
278
|
+
);
|
|
279
|
+
|
|
280
|
+
const api = createTinybirdApi({
|
|
281
|
+
baseUrl: BASE_URL,
|
|
282
|
+
token: "p.default-token",
|
|
283
|
+
});
|
|
284
|
+
|
|
285
|
+
await expect(api.query("broken")).rejects.toMatchObject({
|
|
286
|
+
name: "TinybirdApiError",
|
|
287
|
+
statusCode: 400,
|
|
288
|
+
message: "Invalid query",
|
|
289
|
+
response: {
|
|
290
|
+
error: "Invalid query",
|
|
291
|
+
status: 400,
|
|
292
|
+
},
|
|
293
|
+
});
|
|
294
|
+
});
|
|
295
|
+
});
|