@tinybirdco/sdk 0.0.37 → 0.0.38
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 +50 -1
- package/dist/api/api.d.ts +49 -0
- package/dist/api/api.d.ts.map +1 -1
- package/dist/api/api.js +23 -0
- package/dist/api/api.js.map +1 -1
- package/dist/api/api.test.js +32 -0
- package/dist/api/api.test.js.map +1 -1
- package/dist/api/tokens.d.ts +79 -0
- package/dist/api/tokens.d.ts.map +1 -0
- package/dist/api/tokens.js +80 -0
- package/dist/api/tokens.js.map +1 -0
- package/dist/api/tokens.test.d.ts +2 -0
- package/dist/api/tokens.test.d.ts.map +1 -0
- package/dist/api/tokens.test.js +209 -0
- package/dist/api/tokens.test.js.map +1 -0
- package/dist/client/base.d.ts +3 -0
- package/dist/client/base.d.ts.map +1 -1
- package/dist/client/base.js +5 -0
- package/dist/client/base.js.map +1 -1
- package/dist/client/tokens.d.ts +42 -0
- package/dist/client/tokens.d.ts.map +1 -0
- package/dist/client/tokens.js +67 -0
- package/dist/client/tokens.js.map +1 -0
- package/dist/client/tokens.test.d.ts +2 -0
- package/dist/client/tokens.test.d.ts.map +1 -0
- package/dist/client/tokens.test.js +79 -0
- package/dist/client/tokens.test.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/schema/project.d.ts +21 -12
- package/dist/schema/project.d.ts.map +1 -1
- package/dist/schema/project.js +55 -13
- package/dist/schema/project.js.map +1 -1
- package/dist/schema/project.test.js +11 -10
- package/dist/schema/project.test.js.map +1 -1
- package/package.json +1 -1
- package/src/api/api.test.ts +43 -0
- package/src/api/api.ts +79 -0
- package/src/api/tokens.test.ts +253 -0
- package/src/api/tokens.ts +169 -0
- package/src/client/base.ts +12 -0
- package/src/client/tokens.test.ts +103 -0
- package/src/client/tokens.ts +69 -0
- package/src/index.ts +15 -0
- package/src/schema/project.test.ts +11 -10
- package/src/schema/project.ts +95 -27
|
@@ -70,7 +70,7 @@ describe("Project Schema", () => {
|
|
|
70
70
|
expect(project.pipes.topEvents).toBe(topEvents);
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
-
it("creates tinybird client with
|
|
73
|
+
it("creates tinybird client with pipe accessors and ingest methods", () => {
|
|
74
74
|
const events = defineDatasource("events", {
|
|
75
75
|
schema: { id: t.string() },
|
|
76
76
|
});
|
|
@@ -86,11 +86,12 @@ describe("Project Schema", () => {
|
|
|
86
86
|
pipes: { topEvents },
|
|
87
87
|
});
|
|
88
88
|
|
|
89
|
-
expect(project.tinybird.query).toBeDefined();
|
|
90
89
|
expect(project.tinybird.ingest).toBeDefined();
|
|
91
|
-
expect(typeof project.tinybird.query
|
|
90
|
+
expect(typeof project.tinybird.topEvents.query).toBe("function");
|
|
92
91
|
expect(typeof project.tinybird.ingest.events).toBe("function");
|
|
93
92
|
expect(typeof project.tinybird.ingest.eventsBatch).toBe("function");
|
|
93
|
+
expect((project.tinybird as unknown as Record<string, unknown>).query).toBeUndefined();
|
|
94
|
+
expect((project.tinybird as unknown as Record<string, unknown>).pipes).toBeUndefined();
|
|
94
95
|
});
|
|
95
96
|
|
|
96
97
|
it("creates datasource accessors with append method", () => {
|
|
@@ -144,7 +145,7 @@ describe("Project Schema", () => {
|
|
|
144
145
|
});
|
|
145
146
|
|
|
146
147
|
// Cast to any since the type system expects params but stub throws regardless
|
|
147
|
-
const queryFn = project.tinybird.query
|
|
148
|
+
const queryFn = project.tinybird.internalPipe.query as () => Promise<unknown>;
|
|
148
149
|
await expect(queryFn()).rejects.toThrow(
|
|
149
150
|
'Pipe "internalPipe" is not exposed as an endpoint'
|
|
150
151
|
);
|
|
@@ -277,7 +278,7 @@ describe("Project Schema", () => {
|
|
|
277
278
|
process.env.NODE_ENV = originalNodeEnv;
|
|
278
279
|
});
|
|
279
280
|
|
|
280
|
-
it("creates a client with
|
|
281
|
+
it("creates a client with pipe accessors and ingest methods", () => {
|
|
281
282
|
const events = defineDatasource("events", {
|
|
282
283
|
schema: { id: t.string() },
|
|
283
284
|
});
|
|
@@ -293,11 +294,14 @@ describe("Project Schema", () => {
|
|
|
293
294
|
pipes: { topEvents },
|
|
294
295
|
});
|
|
295
296
|
|
|
296
|
-
expect(client.query).toBeDefined();
|
|
297
297
|
expect(client.ingest).toBeDefined();
|
|
298
|
-
expect(
|
|
298
|
+
expect(client.sql).toBeDefined();
|
|
299
|
+
expect(typeof client.topEvents.query).toBe("function");
|
|
299
300
|
expect(typeof client.ingest.events).toBe("function");
|
|
300
301
|
expect(typeof client.ingest.eventsBatch).toBe("function");
|
|
302
|
+
expect(typeof client.sql).toBe("function");
|
|
303
|
+
expect((client as unknown as Record<string, unknown>).query).toBeUndefined();
|
|
304
|
+
expect((client as unknown as Record<string, unknown>).pipes).toBeUndefined();
|
|
301
305
|
});
|
|
302
306
|
|
|
303
307
|
it("creates datasource accessors with append method", () => {
|
|
@@ -345,7 +349,6 @@ describe("Project Schema", () => {
|
|
|
345
349
|
devMode: true,
|
|
346
350
|
});
|
|
347
351
|
|
|
348
|
-
expect(clientWithDevMode.query).toBeDefined();
|
|
349
352
|
expect(clientWithDevMode.ingest).toBeDefined();
|
|
350
353
|
|
|
351
354
|
const clientWithoutDevMode = createTinybirdClient({
|
|
@@ -354,7 +357,6 @@ describe("Project Schema", () => {
|
|
|
354
357
|
devMode: false,
|
|
355
358
|
});
|
|
356
359
|
|
|
357
|
-
expect(clientWithoutDevMode.query).toBeDefined();
|
|
358
360
|
expect(clientWithoutDevMode.ingest).toBeDefined();
|
|
359
361
|
});
|
|
360
362
|
|
|
@@ -373,7 +375,6 @@ describe("Project Schema", () => {
|
|
|
373
375
|
devMode: true,
|
|
374
376
|
});
|
|
375
377
|
|
|
376
|
-
expect(client.query).toBeDefined();
|
|
377
378
|
expect(client.ingest).toBeDefined();
|
|
378
379
|
});
|
|
379
380
|
|
package/src/schema/project.ts
CHANGED
|
@@ -8,8 +8,15 @@ import type { PipeDefinition, ParamsDefinition, OutputDefinition } from "./pipe.
|
|
|
8
8
|
import type { ConnectionDefinition } from "./connection.js";
|
|
9
9
|
import { getEndpointConfig } from "./pipe.js";
|
|
10
10
|
import type { TinybirdClient } from "../client/base.js";
|
|
11
|
-
import type {
|
|
11
|
+
import type {
|
|
12
|
+
AppendOptions,
|
|
13
|
+
AppendResult,
|
|
14
|
+
DatasourcesNamespace,
|
|
15
|
+
QueryOptions,
|
|
16
|
+
QueryResult,
|
|
17
|
+
} from "../client/types.js";
|
|
12
18
|
import type { InferRow, InferParams, InferOutputRow } from "../infer/index.js";
|
|
19
|
+
import type { TokensNamespace } from "../client/tokens.js";
|
|
13
20
|
|
|
14
21
|
// Symbol for brand typing - use Symbol.for() for global registry
|
|
15
22
|
// This ensures the same symbol is used across module instances
|
|
@@ -41,11 +48,14 @@ type QueryMethod<T extends PipeDefinition<ParamsDefinition, OutputDefinition>> =
|
|
|
41
48
|
: never;
|
|
42
49
|
|
|
43
50
|
/**
|
|
44
|
-
* Type for
|
|
45
|
-
* Note: At runtime,
|
|
51
|
+
* Type for pipe entity accessors object
|
|
52
|
+
* Note: At runtime, all declared pipes are included. Non-endpoint pipes throw
|
|
53
|
+
* when queried with a clear error message.
|
|
46
54
|
*/
|
|
47
|
-
type
|
|
48
|
-
[K in keyof T]:
|
|
55
|
+
type PipeEntityAccessors<T extends PipesDefinition> = {
|
|
56
|
+
[K in keyof T]: {
|
|
57
|
+
query: QueryMethod<T[K]>;
|
|
58
|
+
};
|
|
49
59
|
};
|
|
50
60
|
|
|
51
61
|
/**
|
|
@@ -90,14 +100,15 @@ type DatasourceAccessors<T extends DatasourcesDefinition> = {
|
|
|
90
100
|
/**
|
|
91
101
|
* Base project client interface
|
|
92
102
|
*/
|
|
93
|
-
interface ProjectClientBase<
|
|
94
|
-
TDatasources extends DatasourcesDefinition,
|
|
95
|
-
TPipes extends PipesDefinition
|
|
96
|
-
> {
|
|
97
|
-
/** Query endpoint pipes */
|
|
98
|
-
query: QueryMethods<TPipes>;
|
|
103
|
+
interface ProjectClientBase<TDatasources extends DatasourcesDefinition> {
|
|
99
104
|
/** Ingest events to datasources */
|
|
100
105
|
ingest: IngestMethods<TDatasources>;
|
|
106
|
+
/** Token operations (JWT creation, etc.) */
|
|
107
|
+
readonly tokens: TokensNamespace;
|
|
108
|
+
/** Datasource operations (append from URL/file) */
|
|
109
|
+
readonly datasources: DatasourcesNamespace;
|
|
110
|
+
/** Execute raw SQL queries */
|
|
111
|
+
sql<T = unknown>(sql: string, options?: QueryOptions): Promise<QueryResult<T>>;
|
|
101
112
|
/** Raw client for advanced usage */
|
|
102
113
|
readonly client: TinybirdClient;
|
|
103
114
|
}
|
|
@@ -109,7 +120,9 @@ interface ProjectClientBase<
|
|
|
109
120
|
export type ProjectClient<
|
|
110
121
|
TDatasources extends DatasourcesDefinition,
|
|
111
122
|
TPipes extends PipesDefinition
|
|
112
|
-
> = ProjectClientBase<TDatasources
|
|
123
|
+
> = ProjectClientBase<TDatasources> &
|
|
124
|
+
DatasourceAccessors<TDatasources> &
|
|
125
|
+
PipeEntityAccessors<TPipes>;
|
|
113
126
|
|
|
114
127
|
/**
|
|
115
128
|
* Configuration for createTinybirdClient
|
|
@@ -243,7 +256,7 @@ export function isProjectDefinition(value: unknown): value is ProjectDefinition
|
|
|
243
256
|
/**
|
|
244
257
|
* Build a typed Tinybird client from datasources and pipes
|
|
245
258
|
*
|
|
246
|
-
* This is an internal helper that builds query
|
|
259
|
+
* This is an internal helper that builds pipe query and datasource ingest methods.
|
|
247
260
|
*/
|
|
248
261
|
function buildProjectClient<
|
|
249
262
|
TDatasources extends DatasourcesDefinition,
|
|
@@ -253,6 +266,14 @@ function buildProjectClient<
|
|
|
253
266
|
pipes: TPipes,
|
|
254
267
|
options?: { baseUrl?: string; token?: string; configDir?: string; devMode?: boolean }
|
|
255
268
|
): ProjectClient<TDatasources, TPipes> {
|
|
269
|
+
const RESERVED_CLIENT_NAMES = new Set([
|
|
270
|
+
"ingest",
|
|
271
|
+
"tokens",
|
|
272
|
+
"datasources",
|
|
273
|
+
"sql",
|
|
274
|
+
"client",
|
|
275
|
+
]);
|
|
276
|
+
|
|
256
277
|
// Lazy client initialization
|
|
257
278
|
let _client: TinybirdClient | null = null;
|
|
258
279
|
|
|
@@ -276,33 +297,57 @@ function buildProjectClient<
|
|
|
276
297
|
return _client;
|
|
277
298
|
};
|
|
278
299
|
|
|
279
|
-
// Build query methods
|
|
280
|
-
const
|
|
300
|
+
// Build pipe accessors with query methods
|
|
301
|
+
const pipeAccessors: Record<string, { query: (params?: unknown) => Promise<unknown> }> = {};
|
|
281
302
|
for (const [name, pipe] of Object.entries(pipes)) {
|
|
303
|
+
if (name in datasources) {
|
|
304
|
+
throw new Error(
|
|
305
|
+
`Name conflict in createTinybirdClient(): "${name}" is defined as both datasource and pipe. ` +
|
|
306
|
+
`Rename one of them to expose both as top-level client properties.`
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
if (RESERVED_CLIENT_NAMES.has(name)) {
|
|
310
|
+
throw new Error(
|
|
311
|
+
`Name conflict in createTinybirdClient(): "${name}" is reserved by the client API. ` +
|
|
312
|
+
`Rename this pipe to expose it as a top-level client property.`
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
|
|
282
316
|
const endpointConfig = getEndpointConfig(pipe);
|
|
283
317
|
|
|
284
318
|
if (!endpointConfig) {
|
|
285
319
|
// Non-endpoint pipes get a stub that throws a clear error
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
`
|
|
290
|
-
|
|
320
|
+
pipeAccessors[name] = {
|
|
321
|
+
query: async () => {
|
|
322
|
+
throw new Error(
|
|
323
|
+
`Pipe "${name}" is not exposed as an endpoint. ` +
|
|
324
|
+
`Set "endpoint: true" in the pipe definition to enable querying.`
|
|
325
|
+
);
|
|
326
|
+
},
|
|
291
327
|
};
|
|
292
328
|
continue;
|
|
293
329
|
}
|
|
294
330
|
|
|
295
331
|
// Use the Tinybird pipe name (snake_case)
|
|
296
332
|
const tinybirdName = pipe._name;
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
333
|
+
pipeAccessors[name] = {
|
|
334
|
+
query: async (params?: unknown) => {
|
|
335
|
+
const client = await getClient();
|
|
336
|
+
return client.query(tinybirdName, (params ?? {}) as Record<string, unknown>);
|
|
337
|
+
},
|
|
300
338
|
};
|
|
301
339
|
}
|
|
302
340
|
|
|
303
341
|
// Build ingest methods for datasources
|
|
304
342
|
const ingestMethods: Record<string, (data: unknown) => Promise<void>> = {};
|
|
305
343
|
for (const [name, datasource] of Object.entries(datasources)) {
|
|
344
|
+
if (RESERVED_CLIENT_NAMES.has(name)) {
|
|
345
|
+
throw new Error(
|
|
346
|
+
`Name conflict in createTinybirdClient(): "${name}" is reserved by the client API. ` +
|
|
347
|
+
`Rename this datasource to expose it as a top-level client property.`
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
|
|
306
351
|
// Use the Tinybird datasource name (snake_case)
|
|
307
352
|
const tinybirdName = datasource._name;
|
|
308
353
|
|
|
@@ -335,8 +380,30 @@ function buildProjectClient<
|
|
|
335
380
|
// Create the typed client object
|
|
336
381
|
return {
|
|
337
382
|
...datasourceAccessors,
|
|
338
|
-
|
|
383
|
+
...pipeAccessors,
|
|
339
384
|
ingest: ingestMethods,
|
|
385
|
+
sql: async <T = unknown>(sql: string, options: QueryOptions = {}) => {
|
|
386
|
+
const client = await getClient();
|
|
387
|
+
return client.sql<T>(sql, options);
|
|
388
|
+
},
|
|
389
|
+
get tokens(): TokensNamespace {
|
|
390
|
+
// Synchronous access - will throw if not initialized
|
|
391
|
+
if (!_client) {
|
|
392
|
+
throw new Error(
|
|
393
|
+
"Client not initialized. Call a query or ingest method first, or access client asynchronously."
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
return _client.tokens;
|
|
397
|
+
},
|
|
398
|
+
get datasources(): DatasourcesNamespace {
|
|
399
|
+
// Synchronous access - will throw if not initialized
|
|
400
|
+
if (!_client) {
|
|
401
|
+
throw new Error(
|
|
402
|
+
"Client not initialized. Call a query or ingest method first, or access client asynchronously."
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
return _client.datasources;
|
|
406
|
+
},
|
|
340
407
|
get client(): TinybirdClient {
|
|
341
408
|
// Synchronous client access - will throw if not initialized
|
|
342
409
|
if (!_client) {
|
|
@@ -352,12 +419,13 @@ function buildProjectClient<
|
|
|
352
419
|
/**
|
|
353
420
|
* Create a typed Tinybird client
|
|
354
421
|
*
|
|
355
|
-
* Creates a client with typed query and ingest methods based on
|
|
422
|
+
* Creates a client with typed pipe query and datasource ingest methods based on
|
|
423
|
+
* the provided
|
|
356
424
|
* datasources and pipes. This is the recommended way to create a Tinybird client
|
|
357
425
|
* when using the SDK's auto-generated client file.
|
|
358
426
|
*
|
|
359
427
|
* @param config - Client configuration with datasources and pipes
|
|
360
|
-
* @returns A typed client with query and ingest methods
|
|
428
|
+
* @returns A typed client with pipe query and datasource ingest methods
|
|
361
429
|
*
|
|
362
430
|
* @example
|
|
363
431
|
* ```ts
|
|
@@ -371,7 +439,7 @@ function buildProjectClient<
|
|
|
371
439
|
* });
|
|
372
440
|
*
|
|
373
441
|
* // Query a pipe (fully typed)
|
|
374
|
-
* const result = await tinybird.query
|
|
442
|
+
* const result = await tinybird.topPages.query({
|
|
375
443
|
* start_date: new Date('2024-01-01'),
|
|
376
444
|
* end_date: new Date('2024-01-31'),
|
|
377
445
|
* });
|