@tinybirdco/sdk 0.0.6 → 0.0.8
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/dist/api/branches.d.ts.map +1 -1
- package/dist/api/branches.js +6 -5
- package/dist/api/branches.js.map +1 -1
- package/dist/api/branches.test.js +32 -6
- package/dist/api/branches.test.js.map +1 -1
- package/dist/api/build.d.ts.map +1 -1
- package/dist/api/build.js +2 -1
- package/dist/api/build.js.map +1 -1
- package/dist/api/deploy.d.ts +1 -0
- package/dist/api/deploy.d.ts.map +1 -1
- package/dist/api/deploy.js +27 -6
- package/dist/api/deploy.js.map +1 -1
- package/dist/api/deploy.test.js +6 -2
- package/dist/api/deploy.test.js.map +1 -1
- package/dist/api/fetcher.d.ts +6 -0
- package/dist/api/fetcher.d.ts.map +1 -0
- package/dist/api/fetcher.js +13 -0
- package/dist/api/fetcher.js.map +1 -0
- package/dist/api/local.d.ts.map +1 -1
- package/dist/api/local.js +5 -4
- package/dist/api/local.js.map +1 -1
- package/dist/api/local.test.js.map +1 -1
- package/dist/api/resources.d.ts +2 -0
- package/dist/api/resources.d.ts.map +1 -1
- package/dist/api/resources.js +6 -4
- package/dist/api/resources.js.map +1 -1
- package/dist/api/workspaces.d.ts.map +1 -1
- package/dist/api/workspaces.js +2 -1
- package/dist/api/workspaces.js.map +1 -1
- package/dist/api/workspaces.test.js +9 -1
- package/dist/api/workspaces.test.js.map +1 -1
- package/dist/cli/auth.d.ts.map +1 -1
- package/dist/cli/auth.js +2 -1
- package/dist/cli/auth.js.map +1 -1
- package/dist/cli/commands/deploy.d.ts +2 -0
- package/dist/cli/commands/deploy.d.ts.map +1 -1
- package/dist/cli/commands/deploy.js +3 -1
- package/dist/cli/commands/deploy.js.map +1 -1
- package/dist/cli/commands/init.d.ts +14 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +264 -4
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/index.js +8 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/client/base.d.ts.map +1 -1
- package/dist/client/base.js +2 -1
- package/dist/client/base.js.map +1 -1
- package/dist/codegen/index.d.ts.map +1 -1
- package/dist/codegen/index.js +4 -0
- package/dist/codegen/index.js.map +1 -1
- package/dist/codegen/index.test.js +10 -0
- package/dist/codegen/index.test.js.map +1 -1
- package/dist/generator/datasource.d.ts.map +1 -1
- package/dist/generator/datasource.js +20 -0
- package/dist/generator/datasource.js.map +1 -1
- package/dist/generator/datasource.test.js +11 -0
- package/dist/generator/datasource.test.js.map +1 -1
- package/dist/schema/connection.d.ts.map +1 -1
- package/dist/schema/connection.js +3 -2
- package/dist/schema/connection.js.map +1 -1
- package/dist/schema/datasource.d.ts +5 -0
- package/dist/schema/datasource.d.ts.map +1 -1
- package/dist/schema/datasource.js +3 -2
- package/dist/schema/datasource.js.map +1 -1
- package/dist/schema/params.d.ts.map +1 -1
- package/dist/schema/params.js +3 -2
- package/dist/schema/params.js.map +1 -1
- package/dist/schema/pipe.d.ts +2 -2
- package/dist/schema/pipe.d.ts.map +1 -1
- package/dist/schema/pipe.js +4 -4
- package/dist/schema/pipe.js.map +1 -1
- package/dist/schema/project.d.ts.map +1 -1
- package/dist/schema/project.js +3 -2
- package/dist/schema/project.js.map +1 -1
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/schema/types.js +3 -2
- package/dist/schema/types.js.map +1 -1
- package/package.json +1 -1
- package/src/api/branches.test.ts +65 -57
- package/src/api/branches.ts +7 -5
- package/src/api/build.ts +2 -1
- package/src/api/deploy.test.ts +6 -2
- package/src/api/deploy.ts +35 -7
- package/src/api/fetcher.ts +17 -0
- package/src/api/local.test.ts +43 -31
- package/src/api/local.ts +5 -4
- package/src/api/resources.ts +9 -4
- package/src/api/workspaces.test.ts +15 -9
- package/src/api/workspaces.ts +3 -1
- package/src/cli/auth.ts +2 -1
- package/src/cli/commands/deploy.ts +6 -1
- package/src/cli/commands/init.ts +311 -6
- package/src/cli/index.ts +35 -11
- package/src/client/base.ts +3 -2
- package/src/codegen/index.test.ts +12 -0
- package/src/codegen/index.ts +5 -0
- package/src/generator/datasource.test.ts +13 -0
- package/src/generator/datasource.ts +24 -0
- package/src/schema/connection.ts +3 -2
- package/src/schema/datasource.ts +8 -2
- package/src/schema/params.ts +3 -2
- package/src/schema/pipe.ts +4 -4
- package/src/schema/project.ts +3 -2
- package/src/schema/types.ts +3 -2
package/dist/schema/types.js
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* Column type validators for Tinybird datasources
|
|
3
3
|
* Similar to Convex's `v.*` pattern, but for ClickHouse types
|
|
4
4
|
*/
|
|
5
|
-
// Symbol for brand typing
|
|
6
|
-
|
|
5
|
+
// Symbol for brand typing - use Symbol.for() for global registry
|
|
6
|
+
// This ensures the same symbol is used across module instances
|
|
7
|
+
const VALIDATOR_BRAND = Symbol.for("tinybird.validator");
|
|
7
8
|
function createValidator(tinybirdType, modifiers = {}) {
|
|
8
9
|
const validator = {
|
|
9
10
|
[VALIDATOR_BRAND]: true,
|
package/dist/schema/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/schema/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/schema/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/api/branches.test.ts
CHANGED
|
@@ -14,6 +14,12 @@ import {
|
|
|
14
14
|
const mockFetch = vi.fn();
|
|
15
15
|
global.fetch = mockFetch;
|
|
16
16
|
|
|
17
|
+
function expectFromParam(url: string) {
|
|
18
|
+
const parsed = new URL(url);
|
|
19
|
+
expect(parsed.searchParams.get("from")).toBe("ts-sdk");
|
|
20
|
+
return parsed;
|
|
21
|
+
}
|
|
22
|
+
|
|
17
23
|
describe("Branch API client", () => {
|
|
18
24
|
const config: BranchApiConfig = {
|
|
19
25
|
baseUrl: "https://api.tinybird.co",
|
|
@@ -62,36 +68,37 @@ describe("Branch API client", () => {
|
|
|
62
68
|
const result = await createBranch(config, "my-feature");
|
|
63
69
|
|
|
64
70
|
expect(mockFetch).toHaveBeenCalledTimes(3);
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
);
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
71
|
+
const [createUrl, createInit] = mockFetch.mock.calls[0];
|
|
72
|
+
const createParsed = expectFromParam(createUrl);
|
|
73
|
+
expect(createParsed.pathname).toBe("/v1/environments");
|
|
74
|
+
expect(createParsed.searchParams.get("name")).toBe("my-feature");
|
|
75
|
+
expect(createInit).toEqual({
|
|
76
|
+
method: "POST",
|
|
77
|
+
headers: {
|
|
78
|
+
Authorization: "Bearer p.test-token",
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const [jobUrl, jobInit] = mockFetch.mock.calls[1];
|
|
83
|
+
const jobParsed = expectFromParam(jobUrl);
|
|
84
|
+
expect(jobParsed.pathname).toBe("/v0/jobs/job-123");
|
|
85
|
+
expect(jobInit).toEqual({
|
|
86
|
+
method: "GET",
|
|
87
|
+
headers: {
|
|
88
|
+
Authorization: "Bearer p.test-token",
|
|
89
|
+
},
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const [branchUrl, branchInit] = mockFetch.mock.calls[2];
|
|
93
|
+
const branchParsed = expectFromParam(branchUrl);
|
|
94
|
+
expect(branchParsed.pathname).toBe("/v0/environments/my-feature");
|
|
95
|
+
expect(branchParsed.searchParams.get("with_token")).toBe("true");
|
|
96
|
+
expect(branchInit).toEqual({
|
|
97
|
+
method: "GET",
|
|
98
|
+
headers: {
|
|
99
|
+
Authorization: "Bearer p.test-token",
|
|
100
|
+
},
|
|
101
|
+
});
|
|
95
102
|
expect(result).toEqual(mockBranch);
|
|
96
103
|
});
|
|
97
104
|
|
|
@@ -196,15 +203,15 @@ describe("Branch API client", () => {
|
|
|
196
203
|
|
|
197
204
|
const result = await listBranches(config);
|
|
198
205
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
);
|
|
206
|
+
const [url, init] = mockFetch.mock.calls[0];
|
|
207
|
+
const parsed = expectFromParam(url);
|
|
208
|
+
expect(parsed.pathname).toBe("/v1/environments");
|
|
209
|
+
expect(init).toEqual({
|
|
210
|
+
method: "GET",
|
|
211
|
+
headers: {
|
|
212
|
+
Authorization: "Bearer p.test-token",
|
|
213
|
+
},
|
|
214
|
+
});
|
|
208
215
|
expect(result).toEqual(mockBranches);
|
|
209
216
|
});
|
|
210
217
|
|
|
@@ -235,15 +242,16 @@ describe("Branch API client", () => {
|
|
|
235
242
|
|
|
236
243
|
const result = await getBranch(config, "my-feature");
|
|
237
244
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
245
|
+
const [url, init] = mockFetch.mock.calls[0];
|
|
246
|
+
const parsed = expectFromParam(url);
|
|
247
|
+
expect(parsed.pathname).toBe("/v0/environments/my-feature");
|
|
248
|
+
expect(parsed.searchParams.get("with_token")).toBe("true");
|
|
249
|
+
expect(init).toEqual({
|
|
250
|
+
method: "GET",
|
|
251
|
+
headers: {
|
|
252
|
+
Authorization: "Bearer p.test-token",
|
|
253
|
+
},
|
|
254
|
+
});
|
|
247
255
|
expect(result).toEqual(mockBranch);
|
|
248
256
|
});
|
|
249
257
|
|
|
@@ -269,15 +277,15 @@ describe("Branch API client", () => {
|
|
|
269
277
|
|
|
270
278
|
await deleteBranch(config, "my-feature");
|
|
271
279
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
}
|
|
280
|
-
);
|
|
280
|
+
const [url, init] = mockFetch.mock.calls[0];
|
|
281
|
+
const parsed = expectFromParam(url);
|
|
282
|
+
expect(parsed.pathname).toBe("/v1/environments/my-feature");
|
|
283
|
+
expect(init).toEqual({
|
|
284
|
+
method: "DELETE",
|
|
285
|
+
headers: {
|
|
286
|
+
Authorization: "Bearer p.test-token",
|
|
287
|
+
},
|
|
288
|
+
});
|
|
281
289
|
});
|
|
282
290
|
});
|
|
283
291
|
|
package/src/api/branches.ts
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* Uses the /v1/environments endpoints (Forward API)
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { tinybirdFetch } from "./fetcher.js";
|
|
7
|
+
|
|
6
8
|
/**
|
|
7
9
|
* Branch information from Tinybird API
|
|
8
10
|
*/
|
|
@@ -90,7 +92,7 @@ async function pollJob(
|
|
|
90
92
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
91
93
|
const url = new URL(`/v0/jobs/${jobId}`, config.baseUrl);
|
|
92
94
|
|
|
93
|
-
const response = await
|
|
95
|
+
const response = await tinybirdFetch(url.toString(), {
|
|
94
96
|
method: "GET",
|
|
95
97
|
headers: {
|
|
96
98
|
Authorization: `Bearer ${config.token}`,
|
|
@@ -148,7 +150,7 @@ export async function createBranch(
|
|
|
148
150
|
const url = new URL("/v1/environments", config.baseUrl);
|
|
149
151
|
url.searchParams.set("name", name);
|
|
150
152
|
|
|
151
|
-
const response = await
|
|
153
|
+
const response = await tinybirdFetch(url.toString(), {
|
|
152
154
|
method: "POST",
|
|
153
155
|
headers: {
|
|
154
156
|
Authorization: `Bearer ${config.token}`,
|
|
@@ -205,7 +207,7 @@ export async function listBranches(
|
|
|
205
207
|
): Promise<TinybirdBranch[]> {
|
|
206
208
|
const url = new URL("/v1/environments", config.baseUrl);
|
|
207
209
|
|
|
208
|
-
const response = await
|
|
210
|
+
const response = await tinybirdFetch(url.toString(), {
|
|
209
211
|
method: "GET",
|
|
210
212
|
headers: {
|
|
211
213
|
Authorization: `Bearer ${config.token}`,
|
|
@@ -240,7 +242,7 @@ export async function getBranch(
|
|
|
240
242
|
const url = new URL(`/v0/environments/${encodeURIComponent(name)}`, config.baseUrl);
|
|
241
243
|
url.searchParams.set("with_token", "true");
|
|
242
244
|
|
|
243
|
-
const response = await
|
|
245
|
+
const response = await tinybirdFetch(url.toString(), {
|
|
244
246
|
method: "GET",
|
|
245
247
|
headers: {
|
|
246
248
|
Authorization: `Bearer ${config.token}`,
|
|
@@ -273,7 +275,7 @@ export async function deleteBranch(
|
|
|
273
275
|
): Promise<void> {
|
|
274
276
|
const url = new URL(`/v1/environments/${encodeURIComponent(name)}`, config.baseUrl);
|
|
275
277
|
|
|
276
|
-
const response = await
|
|
278
|
+
const response = await tinybirdFetch(url.toString(), {
|
|
277
279
|
method: "DELETE",
|
|
278
280
|
headers: {
|
|
279
281
|
Authorization: `Bearer ${config.token}`,
|
package/src/api/build.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { GeneratedResources } from "../generator/index.js";
|
|
7
|
+
import { tinybirdFetch } from "./fetcher.js";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Configuration for building/deploying to Tinybird
|
|
@@ -190,7 +191,7 @@ export async function buildToTinybird(
|
|
|
190
191
|
console.log(`[debug] POST ${url}`);
|
|
191
192
|
}
|
|
192
193
|
|
|
193
|
-
const response = await
|
|
194
|
+
const response = await tinybirdFetch(url, {
|
|
194
195
|
method: "POST",
|
|
195
196
|
headers: {
|
|
196
197
|
Authorization: `Bearer ${config.token}`,
|
package/src/api/deploy.test.ts
CHANGED
|
@@ -194,7 +194,9 @@ describe("Deploy API", () => {
|
|
|
194
194
|
|
|
195
195
|
await deployToMain(config, resources, { pollIntervalMs: 1 });
|
|
196
196
|
|
|
197
|
-
|
|
197
|
+
const parsed = new URL(capturedUrl ?? "");
|
|
198
|
+
expect(parsed.pathname).toBe("/v1/deploy");
|
|
199
|
+
expect(parsed.searchParams.get("from")).toBe("ts-sdk");
|
|
198
200
|
});
|
|
199
201
|
|
|
200
202
|
it("handles failed deployment status", async () => {
|
|
@@ -266,7 +268,9 @@ describe("Deploy API", () => {
|
|
|
266
268
|
{ pollIntervalMs: 1 }
|
|
267
269
|
);
|
|
268
270
|
|
|
269
|
-
|
|
271
|
+
const parsed = new URL(capturedUrl ?? "");
|
|
272
|
+
expect(parsed.pathname).toBe("/v1/deploy");
|
|
273
|
+
expect(parsed.searchParams.get("from")).toBe("ts-sdk");
|
|
270
274
|
});
|
|
271
275
|
|
|
272
276
|
it("times out when deployment never becomes ready", async () => {
|
package/src/api/deploy.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import type { GeneratedResources } from "../generator/index.js";
|
|
7
7
|
import type { BuildConfig, BuildApiResult } from "./build.js";
|
|
8
|
+
import { tinybirdFetch } from "./fetcher.js";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Deployment object returned by the /v1/deploy endpoint
|
|
@@ -75,7 +76,12 @@ export interface DeploymentStatusResponse {
|
|
|
75
76
|
export async function deployToMain(
|
|
76
77
|
config: BuildConfig,
|
|
77
78
|
resources: GeneratedResources,
|
|
78
|
-
options?: {
|
|
79
|
+
options?: {
|
|
80
|
+
debug?: boolean;
|
|
81
|
+
pollIntervalMs?: number;
|
|
82
|
+
maxPollAttempts?: number;
|
|
83
|
+
check?: boolean;
|
|
84
|
+
}
|
|
79
85
|
): Promise<BuildApiResult> {
|
|
80
86
|
const debug = options?.debug ?? !!process.env.TINYBIRD_DEBUG;
|
|
81
87
|
const pollIntervalMs = options?.pollIntervalMs ?? 1000;
|
|
@@ -117,7 +123,7 @@ export async function deployToMain(
|
|
|
117
123
|
// Step 0: Clean up any stale non-live deployments that might block the new deployment
|
|
118
124
|
try {
|
|
119
125
|
const deploymentsUrl = `${baseUrl}/v1/deployments`;
|
|
120
|
-
const deploymentsResponse = await
|
|
126
|
+
const deploymentsResponse = await tinybirdFetch(deploymentsUrl, {
|
|
121
127
|
headers: {
|
|
122
128
|
Authorization: `Bearer ${config.token}`,
|
|
123
129
|
},
|
|
@@ -133,7 +139,7 @@ export async function deployToMain(
|
|
|
133
139
|
if (debug) {
|
|
134
140
|
console.log(`[debug] Cleaning up stale deployment: ${stale.id} (status: ${stale.status})`);
|
|
135
141
|
}
|
|
136
|
-
await
|
|
142
|
+
await tinybirdFetch(`${baseUrl}/v1/deployments/${stale.id}`, {
|
|
137
143
|
method: "DELETE",
|
|
138
144
|
headers: {
|
|
139
145
|
Authorization: `Bearer ${config.token}`,
|
|
@@ -149,13 +155,14 @@ export async function deployToMain(
|
|
|
149
155
|
}
|
|
150
156
|
|
|
151
157
|
// Step 1: Create deployment via /v1/deploy
|
|
152
|
-
const
|
|
158
|
+
const deployUrlBase = `${baseUrl}/v1/deploy`;
|
|
159
|
+
const deployUrl = options?.check ? `${deployUrlBase}?check=true` : deployUrlBase;
|
|
153
160
|
|
|
154
161
|
if (debug) {
|
|
155
162
|
console.log(`[debug] POST ${deployUrl}`);
|
|
156
163
|
}
|
|
157
164
|
|
|
158
|
-
const response = await
|
|
165
|
+
const response = await tinybirdFetch(deployUrl, {
|
|
159
166
|
method: "POST",
|
|
160
167
|
headers: {
|
|
161
168
|
Authorization: `Bearer ${config.token}`,
|
|
@@ -205,6 +212,27 @@ export async function deployToMain(
|
|
|
205
212
|
};
|
|
206
213
|
}
|
|
207
214
|
|
|
215
|
+
if (options?.check) {
|
|
216
|
+
if (body.result === "failed") {
|
|
217
|
+
return {
|
|
218
|
+
success: false,
|
|
219
|
+
result: "failed",
|
|
220
|
+
error: formatErrors(),
|
|
221
|
+
datasourceCount: resources.datasources.length,
|
|
222
|
+
pipeCount: resources.pipes.length,
|
|
223
|
+
connectionCount: resources.connections?.length ?? 0,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
success: true,
|
|
229
|
+
result: body.result ?? "success",
|
|
230
|
+
datasourceCount: resources.datasources.length,
|
|
231
|
+
pipeCount: resources.pipes.length,
|
|
232
|
+
connectionCount: resources.connections?.length ?? 0,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
|
|
208
236
|
// Handle API result
|
|
209
237
|
if (body.result === "failed" || !body.deployment) {
|
|
210
238
|
return {
|
|
@@ -236,7 +264,7 @@ export async function deployToMain(
|
|
|
236
264
|
}
|
|
237
265
|
|
|
238
266
|
const statusUrl = `${baseUrl}/v1/deployments/${deploymentId}`;
|
|
239
|
-
const statusResponse = await
|
|
267
|
+
const statusResponse = await tinybirdFetch(statusUrl, {
|
|
240
268
|
headers: {
|
|
241
269
|
Authorization: `Bearer ${config.token}`,
|
|
242
270
|
},
|
|
@@ -294,7 +322,7 @@ export async function deployToMain(
|
|
|
294
322
|
console.log(`[debug] POST ${setLiveUrl}`);
|
|
295
323
|
}
|
|
296
324
|
|
|
297
|
-
const setLiveResponse = await
|
|
325
|
+
const setLiveResponse = await tinybirdFetch(setLiveUrl, {
|
|
298
326
|
method: "POST",
|
|
299
327
|
headers: {
|
|
300
328
|
Authorization: `Bearer ${config.token}`,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export const TINYBIRD_FROM_PARAM = "ts-sdk";
|
|
2
|
+
|
|
3
|
+
export type TinybirdFetch = (url: string, init?: RequestInit) => Promise<Response>;
|
|
4
|
+
|
|
5
|
+
export function withTinybirdFromParam(url: string): string {
|
|
6
|
+
const parsedUrl = new URL(url);
|
|
7
|
+
parsedUrl.searchParams.set("from", TINYBIRD_FROM_PARAM);
|
|
8
|
+
return parsedUrl.toString();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function createTinybirdFetcher(fetchFn: typeof fetch): TinybirdFetch {
|
|
12
|
+
return (url, init) => fetchFn(withTinybirdFromParam(url), init);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function tinybirdFetch(url: string, init?: RequestInit): Promise<Response> {
|
|
16
|
+
return fetch(withTinybirdFromParam(url), init);
|
|
17
|
+
}
|
package/src/api/local.test.ts
CHANGED
|
@@ -94,15 +94,18 @@ describe("Local API", () => {
|
|
|
94
94
|
describe("listLocalWorkspaces", () => {
|
|
95
95
|
it("returns list of workspaces", async () => {
|
|
96
96
|
server.use(
|
|
97
|
-
http.get(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
97
|
+
http.get(
|
|
98
|
+
`${LOCAL_BASE_URL}/v1/user/workspaces`,
|
|
99
|
+
() => {
|
|
100
|
+
return HttpResponse.json({
|
|
101
|
+
organization_id: "org-123",
|
|
102
|
+
workspaces: [
|
|
103
|
+
{ id: "ws-1", name: "Workspace1", token: "token-1" },
|
|
104
|
+
{ id: "ws-2", name: "Workspace2", token: "token-2" },
|
|
105
|
+
],
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
)
|
|
106
109
|
);
|
|
107
110
|
|
|
108
111
|
const result = await listLocalWorkspaces("admin-token");
|
|
@@ -118,9 +121,12 @@ describe("Local API", () => {
|
|
|
118
121
|
|
|
119
122
|
it("throws LocalApiError on failure", async () => {
|
|
120
123
|
server.use(
|
|
121
|
-
http.get(
|
|
122
|
-
|
|
123
|
-
|
|
124
|
+
http.get(
|
|
125
|
+
`${LOCAL_BASE_URL}/v1/user/workspaces`,
|
|
126
|
+
() => {
|
|
127
|
+
return new HttpResponse("Not found", { status: 404 });
|
|
128
|
+
}
|
|
129
|
+
)
|
|
124
130
|
);
|
|
125
131
|
|
|
126
132
|
await expect(listLocalWorkspaces("admin-token")).rejects.toThrow(LocalApiError);
|
|
@@ -170,14 +176,17 @@ describe("Local API", () => {
|
|
|
170
176
|
|
|
171
177
|
it("returns existing workspace if found", async () => {
|
|
172
178
|
server.use(
|
|
173
|
-
http.get(
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
179
|
+
http.get(
|
|
180
|
+
`${LOCAL_BASE_URL}/v1/user/workspaces`,
|
|
181
|
+
() => {
|
|
182
|
+
return HttpResponse.json({
|
|
183
|
+
organization_id: "org-123",
|
|
184
|
+
workspaces: [
|
|
185
|
+
{ id: "existing-ws", name: "MyWorkspace", token: "existing-token" },
|
|
186
|
+
],
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
)
|
|
181
190
|
);
|
|
182
191
|
|
|
183
192
|
const result = await getOrCreateLocalWorkspace(tokens, "MyWorkspace");
|
|
@@ -191,21 +200,24 @@ describe("Local API", () => {
|
|
|
191
200
|
let createCalled = false;
|
|
192
201
|
|
|
193
202
|
server.use(
|
|
194
|
-
http.get(
|
|
195
|
-
|
|
196
|
-
|
|
203
|
+
http.get(
|
|
204
|
+
`${LOCAL_BASE_URL}/v1/user/workspaces`,
|
|
205
|
+
() => {
|
|
206
|
+
// Return different response based on whether create was called
|
|
207
|
+
if (createCalled) {
|
|
208
|
+
return HttpResponse.json({
|
|
209
|
+
organization_id: "org-123",
|
|
210
|
+
workspaces: [
|
|
211
|
+
{ id: "new-ws", name: "NewWorkspace", token: "new-token" },
|
|
212
|
+
],
|
|
213
|
+
});
|
|
214
|
+
}
|
|
197
215
|
return HttpResponse.json({
|
|
198
216
|
organization_id: "org-123",
|
|
199
|
-
workspaces: [
|
|
200
|
-
{ id: "new-ws", name: "NewWorkspace", token: "new-token" },
|
|
201
|
-
],
|
|
217
|
+
workspaces: [], // Empty initially
|
|
202
218
|
});
|
|
203
219
|
}
|
|
204
|
-
|
|
205
|
-
organization_id: "org-123",
|
|
206
|
-
workspaces: [], // Empty initially
|
|
207
|
-
});
|
|
208
|
-
}),
|
|
220
|
+
),
|
|
209
221
|
http.post(`${LOCAL_BASE_URL}/v1/workspaces`, () => {
|
|
210
222
|
createCalled = true;
|
|
211
223
|
return HttpResponse.json({
|
package/src/api/local.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import * as crypto from "crypto";
|
|
7
7
|
import { LOCAL_BASE_URL } from "../cli/config.js";
|
|
8
|
+
import { tinybirdFetch } from "./fetcher.js";
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Tokens returned by the local /tokens endpoint
|
|
@@ -76,7 +77,7 @@ export class LocalApiError extends Error {
|
|
|
76
77
|
*/
|
|
77
78
|
export async function isLocalRunning(): Promise<boolean> {
|
|
78
79
|
try {
|
|
79
|
-
const response = await
|
|
80
|
+
const response = await tinybirdFetch(`${LOCAL_BASE_URL}/tokens`, {
|
|
80
81
|
method: "GET",
|
|
81
82
|
signal: AbortSignal.timeout(5000),
|
|
82
83
|
});
|
|
@@ -94,7 +95,7 @@ export async function isLocalRunning(): Promise<boolean> {
|
|
|
94
95
|
*/
|
|
95
96
|
export async function getLocalTokens(): Promise<LocalTokens> {
|
|
96
97
|
try {
|
|
97
|
-
const response = await
|
|
98
|
+
const response = await tinybirdFetch(`${LOCAL_BASE_URL}/tokens`, {
|
|
98
99
|
method: "GET",
|
|
99
100
|
signal: AbortSignal.timeout(5000),
|
|
100
101
|
});
|
|
@@ -136,7 +137,7 @@ export async function listLocalWorkspaces(
|
|
|
136
137
|
): Promise<{ workspaces: LocalWorkspace[]; organizationId?: string }> {
|
|
137
138
|
const url = `${LOCAL_BASE_URL}/v1/user/workspaces?with_organization=true&token=${adminToken}`;
|
|
138
139
|
|
|
139
|
-
const response = await
|
|
140
|
+
const response = await tinybirdFetch(url, {
|
|
140
141
|
method: "GET",
|
|
141
142
|
});
|
|
142
143
|
|
|
@@ -182,7 +183,7 @@ export async function createLocalWorkspace(
|
|
|
182
183
|
formData.append("assign_to_organization_id", organizationId);
|
|
183
184
|
}
|
|
184
185
|
|
|
185
|
-
const response = await
|
|
186
|
+
const response = await tinybirdFetch(url, {
|
|
186
187
|
method: "POST",
|
|
187
188
|
headers: {
|
|
188
189
|
Authorization: `Bearer ${userToken}`,
|
package/src/api/resources.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { WorkspaceApiConfig } from "./workspaces.js";
|
|
7
|
+
import { tinybirdFetch } from "./fetcher.js";
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Error thrown by resource API operations
|
|
@@ -74,6 +75,8 @@ export interface DatasourceInfo {
|
|
|
74
75
|
columns: DatasourceColumn[];
|
|
75
76
|
/** Engine configuration */
|
|
76
77
|
engine: DatasourceEngine;
|
|
78
|
+
/** Forward query for schema evolution */
|
|
79
|
+
forward_query?: string;
|
|
77
80
|
}
|
|
78
81
|
|
|
79
82
|
/**
|
|
@@ -134,6 +137,7 @@ interface DatasourceDetailResponse {
|
|
|
134
137
|
partition_key?: string;
|
|
135
138
|
primary_key?: string;
|
|
136
139
|
ttl?: string;
|
|
140
|
+
forward_query?: string;
|
|
137
141
|
}
|
|
138
142
|
|
|
139
143
|
// ============ Pipe Types ============
|
|
@@ -299,7 +303,7 @@ export async function listDatasources(
|
|
|
299
303
|
): Promise<string[]> {
|
|
300
304
|
const url = new URL("/v0/datasources", config.baseUrl);
|
|
301
305
|
|
|
302
|
-
const response = await
|
|
306
|
+
const response = await tinybirdFetch(url.toString(), {
|
|
303
307
|
method: "GET",
|
|
304
308
|
headers: {
|
|
305
309
|
Authorization: `Bearer ${config.token}`,
|
|
@@ -327,7 +331,7 @@ export async function getDatasource(
|
|
|
327
331
|
): Promise<DatasourceInfo> {
|
|
328
332
|
const url = new URL(`/v0/datasources/${encodeURIComponent(name)}`, config.baseUrl);
|
|
329
333
|
|
|
330
|
-
const response = await
|
|
334
|
+
const response = await tinybirdFetch(url.toString(), {
|
|
331
335
|
method: "GET",
|
|
332
336
|
headers: {
|
|
333
337
|
Authorization: `Bearer ${config.token}`,
|
|
@@ -375,6 +379,7 @@ export async function getDatasource(
|
|
|
375
379
|
version: engineObj?.engine_version,
|
|
376
380
|
summing_columns: engineObj?.engine_summing_columns,
|
|
377
381
|
},
|
|
382
|
+
forward_query: data.forward_query,
|
|
378
383
|
};
|
|
379
384
|
}
|
|
380
385
|
|
|
@@ -404,7 +409,7 @@ export async function listPipes(
|
|
|
404
409
|
): Promise<string[]> {
|
|
405
410
|
const url = new URL("/v0/pipes", config.baseUrl);
|
|
406
411
|
|
|
407
|
-
const response = await
|
|
412
|
+
const response = await tinybirdFetch(url.toString(), {
|
|
408
413
|
method: "GET",
|
|
409
414
|
headers: {
|
|
410
415
|
Authorization: `Bearer ${config.token}`,
|
|
@@ -432,7 +437,7 @@ export async function getPipe(
|
|
|
432
437
|
): Promise<PipeInfo> {
|
|
433
438
|
const url = new URL(`/v0/pipes/${encodeURIComponent(name)}`, config.baseUrl);
|
|
434
439
|
|
|
435
|
-
const response = await
|
|
440
|
+
const response = await tinybirdFetch(url.toString(), {
|
|
436
441
|
method: "GET",
|
|
437
442
|
headers: {
|
|
438
443
|
Authorization: `Bearer ${config.token}`,
|