@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
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build and deploy resources to Tinybird API
|
|
3
|
+
* Uses the /v1/build endpoint to deploy all resources at once
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Build and deploy generated resources to Tinybird API
|
|
7
|
+
*
|
|
8
|
+
* Uses the /v1/build endpoint which accepts all resources in a single
|
|
9
|
+
* multipart form request.
|
|
10
|
+
*
|
|
11
|
+
* @param config - Build configuration with API URL and token
|
|
12
|
+
* @param resources - Generated resources to deploy
|
|
13
|
+
* @returns Build result
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const result = await buildToTinybird(
|
|
18
|
+
* {
|
|
19
|
+
* baseUrl: 'https://api.tinybird.co',
|
|
20
|
+
* token: 'p.xxx',
|
|
21
|
+
* },
|
|
22
|
+
* {
|
|
23
|
+
* datasources: [{ name: 'events', content: '...' }],
|
|
24
|
+
* pipes: [{ name: 'top_events', content: '...' }],
|
|
25
|
+
* }
|
|
26
|
+
* );
|
|
27
|
+
*
|
|
28
|
+
* if (result.success) {
|
|
29
|
+
* console.log('Build deployed successfully!');
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export async function buildToTinybird(config, resources, options) {
|
|
34
|
+
const debug = options?.debug ?? !!process.env.TINYBIRD_DEBUG;
|
|
35
|
+
const formData = new FormData();
|
|
36
|
+
// Add datasources
|
|
37
|
+
for (const ds of resources.datasources) {
|
|
38
|
+
const fieldName = `data_project://`;
|
|
39
|
+
const fileName = `${ds.name}.datasource`;
|
|
40
|
+
if (debug) {
|
|
41
|
+
console.log(`[debug] Adding datasource: ${fieldName} (filename: ${fileName})`);
|
|
42
|
+
console.log(`[debug] Content:\n${ds.content}\n`);
|
|
43
|
+
}
|
|
44
|
+
formData.append(fieldName, new Blob([ds.content], { type: "text/plain" }), fileName);
|
|
45
|
+
}
|
|
46
|
+
// Add pipes
|
|
47
|
+
for (const pipe of resources.pipes) {
|
|
48
|
+
const fieldName = `data_project://`;
|
|
49
|
+
const fileName = `${pipe.name}.pipe`;
|
|
50
|
+
if (debug) {
|
|
51
|
+
console.log(`[debug] Adding pipe: ${fieldName} (filename: ${fileName})`);
|
|
52
|
+
console.log(`[debug] Content:\n${pipe.content}\n`);
|
|
53
|
+
}
|
|
54
|
+
formData.append(fieldName, new Blob([pipe.content], { type: "text/plain" }), fileName);
|
|
55
|
+
}
|
|
56
|
+
// Make the request
|
|
57
|
+
const url = `${config.baseUrl.replace(/\/$/, "")}/v1/build`;
|
|
58
|
+
if (debug) {
|
|
59
|
+
console.log(`[debug] POST ${url}`);
|
|
60
|
+
}
|
|
61
|
+
const response = await fetch(url, {
|
|
62
|
+
method: "POST",
|
|
63
|
+
headers: {
|
|
64
|
+
Authorization: `Bearer ${config.token}`,
|
|
65
|
+
},
|
|
66
|
+
body: formData,
|
|
67
|
+
});
|
|
68
|
+
// Parse response
|
|
69
|
+
let body;
|
|
70
|
+
const rawBody = await response.text();
|
|
71
|
+
if (debug) {
|
|
72
|
+
console.log(`[debug] Response status: ${response.status}`);
|
|
73
|
+
console.log(`[debug] Response body: ${rawBody}`);
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
76
|
+
body = JSON.parse(rawBody);
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
throw new Error(`Failed to parse response from Tinybird API: ${response.status} ${response.statusText}\nBody: ${rawBody}`);
|
|
80
|
+
}
|
|
81
|
+
// Helper to format errors
|
|
82
|
+
const formatErrors = () => {
|
|
83
|
+
if (body.errors && body.errors.length > 0) {
|
|
84
|
+
return body.errors.map(e => {
|
|
85
|
+
const prefix = e.filename ? `[${e.filename}] ` : '';
|
|
86
|
+
return `${prefix}${e.error}`;
|
|
87
|
+
}).join('\n');
|
|
88
|
+
}
|
|
89
|
+
return body.error || `HTTP ${response.status}: ${response.statusText}`;
|
|
90
|
+
};
|
|
91
|
+
// Handle non-OK responses
|
|
92
|
+
if (!response.ok) {
|
|
93
|
+
return {
|
|
94
|
+
success: false,
|
|
95
|
+
result: "failed",
|
|
96
|
+
error: formatErrors(),
|
|
97
|
+
datasourceCount: resources.datasources.length,
|
|
98
|
+
pipeCount: resources.pipes.length,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
// Handle API result
|
|
102
|
+
if (body.result === "failed") {
|
|
103
|
+
return {
|
|
104
|
+
success: false,
|
|
105
|
+
result: "failed",
|
|
106
|
+
error: formatErrors(),
|
|
107
|
+
datasourceCount: resources.datasources.length,
|
|
108
|
+
pipeCount: resources.pipes.length,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
success: true,
|
|
113
|
+
result: body.result,
|
|
114
|
+
datasourceCount: resources.datasources.length,
|
|
115
|
+
pipeCount: resources.pipes.length,
|
|
116
|
+
buildId: body.build?.id,
|
|
117
|
+
pipes: {
|
|
118
|
+
changed: body.build?.changed_pipe_names ?? [],
|
|
119
|
+
created: body.build?.new_pipe_names ?? [],
|
|
120
|
+
deleted: body.build?.deleted_pipe_names ?? [],
|
|
121
|
+
},
|
|
122
|
+
datasources: {
|
|
123
|
+
changed: body.build?.changed_datasource_names ?? [],
|
|
124
|
+
created: body.build?.new_datasource_names ?? [],
|
|
125
|
+
deleted: body.build?.deleted_datasource_names ?? [],
|
|
126
|
+
},
|
|
127
|
+
// Keep deprecated fields for backwards compatibility
|
|
128
|
+
changedPipeNames: body.build?.changed_pipe_names ?? [],
|
|
129
|
+
newPipeNames: body.build?.new_pipe_names ?? [],
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Validate that the configuration is complete
|
|
134
|
+
*/
|
|
135
|
+
export function validateBuildConfig(config) {
|
|
136
|
+
if (!config.baseUrl) {
|
|
137
|
+
throw new Error("Missing baseUrl in configuration");
|
|
138
|
+
}
|
|
139
|
+
if (!config.token) {
|
|
140
|
+
throw new Error("Missing token in configuration");
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=build.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/api/build.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAmGH;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAmB,EACnB,SAA6B,EAC7B,OAA6B;IAE7B,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC7D,MAAM,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;IAEhC,kBAAkB;IAClB,KAAK,MAAM,EAAE,IAAI,SAAS,CAAC,WAAW,EAAE,CAAC;QACvC,MAAM,SAAS,GAAG,iBAAiB,CAAC;QACpC,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,IAAI,aAAa,CAAC;QACzC,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,GAAG,CAAC,8BAA8B,SAAS,eAAe,QAAQ,GAAG,CAAC,CAAC;YAC/E,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC,OAAO,IAAI,CAAC,CAAC;QACnD,CAAC;QACD,QAAQ,CAAC,MAAM,CACb,SAAS,EACT,IAAI,IAAI,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAC9C,QAAQ,CACT,CAAC;IACJ,CAAC;IAED,YAAY;IACZ,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;QACnC,MAAM,SAAS,GAAG,iBAAiB,CAAC;QACpC,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,IAAI,OAAO,CAAC;QACrC,IAAI,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,GAAG,CAAC,wBAAwB,SAAS,eAAe,QAAQ,GAAG,CAAC,CAAC;YACzE,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;QACrD,CAAC;QACD,QAAQ,CAAC,MAAM,CACb,SAAS,EACT,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,EAChD,QAAQ,CACT,CAAC;IACJ,CAAC;IAED,mBAAmB;IACnB,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC;IAE5D,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,EAAE,CAAC,CAAC;IACrC,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAChC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,MAAM,CAAC,KAAK,EAAE;SACxC;QACD,IAAI,EAAE,QAAQ;KACf,CAAC,CAAC;IAEH,iBAAiB;IACjB,IAAI,IAAmB,CAAC;IACxB,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IAEtC,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,4BAA4B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3D,OAAO,CAAC,GAAG,CAAC,0BAA0B,OAAO,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAkB,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,+CAA+C,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,WAAW,OAAO,EAAE,CAC1G,CAAC;IACJ,CAAC;IAED,0BAA0B;IAC1B,MAAM,YAAY,GAAG,GAAW,EAAE;QAChC,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;gBACzB,MAAM,MAAM,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpD,OAAO,GAAG,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC;YAC/B,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,IAAI,QAAQ,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC;IACzE,CAAC,CAAC;IAEF,0BAA0B;IAC1B,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,QAAQ;YAChB,KAAK,EAAE,YAAY,EAAE;YACrB,eAAe,EAAE,SAAS,CAAC,WAAW,CAAC,MAAM;YAC7C,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;SAClC,CAAC;IACJ,CAAC;IAED,oBAAoB;IACpB,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO;YACL,OAAO,EAAE,KAAK;YACd,MAAM,EAAE,QAAQ;YAChB,KAAK,EAAE,YAAY,EAAE;YACrB,eAAe,EAAE,SAAS,CAAC,WAAW,CAAC,MAAM;YAC7C,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;SAClC,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,eAAe,EAAE,SAAS,CAAC,WAAW,CAAC,MAAM;QAC7C,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC,MAAM;QACjC,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,EAAE;QACvB,KAAK,EAAE;YACL,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,kBAAkB,IAAI,EAAE;YAC7C,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,cAAc,IAAI,EAAE;YACzC,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,kBAAkB,IAAI,EAAE;SAC9C;QACD,WAAW,EAAE;YACX,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,wBAAwB,IAAI,EAAE;YACnD,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,oBAAoB,IAAI,EAAE;YAC/C,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,wBAAwB,IAAI,EAAE;SACpD;QACD,qDAAqD;QACrD,gBAAgB,EAAE,IAAI,CAAC,KAAK,EAAE,kBAAkB,IAAI,EAAE;QACtD,YAAY,EAAE,IAAI,CAAC,KAAK,EAAE,cAAc,IAAI,EAAE;KAC/C,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAA4B;IAC9D,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;IACpD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.test.d.ts","sourceRoot":"","sources":["../../src/api/build.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll, afterEach, afterAll } from "vitest";
|
|
2
|
+
import { setupServer } from "msw/node";
|
|
3
|
+
import { http, HttpResponse } from "msw";
|
|
4
|
+
import { buildToTinybird, validateBuildConfig } from "./build.js";
|
|
5
|
+
import { BASE_URL, createBuildSuccessResponse, createBuildFailureResponse, createBuildMultipleErrorsResponse, createNoChangesResponse, } from "../test/handlers.js";
|
|
6
|
+
const server = setupServer();
|
|
7
|
+
beforeAll(() => server.listen({ onUnhandledRequest: "error" }));
|
|
8
|
+
afterEach(() => server.resetHandlers());
|
|
9
|
+
afterAll(() => server.close());
|
|
10
|
+
describe("Build API", () => {
|
|
11
|
+
const config = {
|
|
12
|
+
baseUrl: BASE_URL,
|
|
13
|
+
token: "p.test-token",
|
|
14
|
+
};
|
|
15
|
+
const resources = {
|
|
16
|
+
datasources: [
|
|
17
|
+
{ name: "events", content: "SCHEMA > timestamp DateTime" },
|
|
18
|
+
{ name: "users", content: "SCHEMA > id String" },
|
|
19
|
+
],
|
|
20
|
+
pipes: [
|
|
21
|
+
{ name: "top_events", content: "NODE main\nSQL > SELECT * FROM events" },
|
|
22
|
+
],
|
|
23
|
+
};
|
|
24
|
+
describe("buildToTinybird", () => {
|
|
25
|
+
it("successfully builds resources", async () => {
|
|
26
|
+
server.use(http.post(`${BASE_URL}/v1/build`, () => {
|
|
27
|
+
return HttpResponse.json(createBuildSuccessResponse({
|
|
28
|
+
buildId: "build-abc",
|
|
29
|
+
newPipes: ["top_events"],
|
|
30
|
+
newDatasources: ["events", "users"],
|
|
31
|
+
}));
|
|
32
|
+
}));
|
|
33
|
+
const result = await buildToTinybird(config, resources);
|
|
34
|
+
expect(result.success).toBe(true);
|
|
35
|
+
expect(result.result).toBe("success");
|
|
36
|
+
expect(result.buildId).toBe("build-abc");
|
|
37
|
+
expect(result.datasourceCount).toBe(2);
|
|
38
|
+
expect(result.pipeCount).toBe(1);
|
|
39
|
+
expect(result.pipes?.created).toEqual(["top_events"]);
|
|
40
|
+
expect(result.datasources?.created).toEqual(["events", "users"]);
|
|
41
|
+
});
|
|
42
|
+
it("handles no changes response", async () => {
|
|
43
|
+
server.use(http.post(`${BASE_URL}/v1/build`, () => {
|
|
44
|
+
return HttpResponse.json(createNoChangesResponse());
|
|
45
|
+
}));
|
|
46
|
+
const result = await buildToTinybird(config, resources);
|
|
47
|
+
expect(result.success).toBe(true);
|
|
48
|
+
expect(result.result).toBe("no_changes");
|
|
49
|
+
});
|
|
50
|
+
it("handles build failure with single error", async () => {
|
|
51
|
+
server.use(http.post(`${BASE_URL}/v1/build`, () => {
|
|
52
|
+
return HttpResponse.json(createBuildFailureResponse("Invalid SQL syntax"), { status: 200 });
|
|
53
|
+
}));
|
|
54
|
+
const result = await buildToTinybird(config, resources);
|
|
55
|
+
expect(result.success).toBe(false);
|
|
56
|
+
expect(result.result).toBe("failed");
|
|
57
|
+
expect(result.error).toBe("Invalid SQL syntax");
|
|
58
|
+
});
|
|
59
|
+
it("handles build failure with multiple errors", async () => {
|
|
60
|
+
server.use(http.post(`${BASE_URL}/v1/build`, () => {
|
|
61
|
+
return HttpResponse.json(createBuildMultipleErrorsResponse([
|
|
62
|
+
{ filename: "events.datasource", error: "Invalid schema" },
|
|
63
|
+
{ filename: "top_events.pipe", error: "Unknown column" },
|
|
64
|
+
]), { status: 200 });
|
|
65
|
+
}));
|
|
66
|
+
const result = await buildToTinybird(config, resources);
|
|
67
|
+
expect(result.success).toBe(false);
|
|
68
|
+
expect(result.error).toContain("[events.datasource] Invalid schema");
|
|
69
|
+
expect(result.error).toContain("[top_events.pipe] Unknown column");
|
|
70
|
+
});
|
|
71
|
+
it("handles HTTP error responses", async () => {
|
|
72
|
+
server.use(http.post(`${BASE_URL}/v1/build`, () => {
|
|
73
|
+
return HttpResponse.json({ result: "failed", error: "Unauthorized" }, { status: 401 });
|
|
74
|
+
}));
|
|
75
|
+
const result = await buildToTinybird(config, resources);
|
|
76
|
+
expect(result.success).toBe(false);
|
|
77
|
+
expect(result.error).toBe("Unauthorized");
|
|
78
|
+
});
|
|
79
|
+
it("handles malformed JSON response", async () => {
|
|
80
|
+
server.use(http.post(`${BASE_URL}/v1/build`, () => {
|
|
81
|
+
return new HttpResponse("not json", {
|
|
82
|
+
status: 200,
|
|
83
|
+
headers: { "Content-Type": "text/plain" },
|
|
84
|
+
});
|
|
85
|
+
}));
|
|
86
|
+
await expect(buildToTinybird(config, resources)).rejects.toThrow("Failed to parse response");
|
|
87
|
+
});
|
|
88
|
+
it("tracks changed pipes and datasources", async () => {
|
|
89
|
+
server.use(http.post(`${BASE_URL}/v1/build`, () => {
|
|
90
|
+
return HttpResponse.json(createBuildSuccessResponse({
|
|
91
|
+
changedPipes: ["top_events"],
|
|
92
|
+
changedDatasources: ["events"],
|
|
93
|
+
deletedPipes: ["old_pipe"],
|
|
94
|
+
}));
|
|
95
|
+
}));
|
|
96
|
+
const result = await buildToTinybird(config, resources);
|
|
97
|
+
expect(result.pipes?.changed).toEqual(["top_events"]);
|
|
98
|
+
expect(result.pipes?.deleted).toEqual(["old_pipe"]);
|
|
99
|
+
expect(result.datasources?.changed).toEqual(["events"]);
|
|
100
|
+
// Deprecated fields should still work
|
|
101
|
+
expect(result.changedPipeNames).toEqual(["top_events"]);
|
|
102
|
+
});
|
|
103
|
+
it("sends correct authorization header", async () => {
|
|
104
|
+
let capturedAuth = null;
|
|
105
|
+
server.use(http.post(`${BASE_URL}/v1/build`, ({ request }) => {
|
|
106
|
+
capturedAuth = request.headers.get("Authorization");
|
|
107
|
+
return HttpResponse.json(createBuildSuccessResponse());
|
|
108
|
+
}));
|
|
109
|
+
await buildToTinybird(config, resources);
|
|
110
|
+
expect(capturedAuth).toBe("Bearer p.test-token");
|
|
111
|
+
});
|
|
112
|
+
it("sends resources as multipart form data", async () => {
|
|
113
|
+
let capturedFormData = null;
|
|
114
|
+
server.use(http.post(`${BASE_URL}/v1/build`, async ({ request }) => {
|
|
115
|
+
capturedFormData = await request.formData();
|
|
116
|
+
return HttpResponse.json(createBuildSuccessResponse());
|
|
117
|
+
}));
|
|
118
|
+
await buildToTinybird(config, resources);
|
|
119
|
+
expect(capturedFormData).not.toBeNull();
|
|
120
|
+
// FormData has 3 entries: 2 datasources + 1 pipe
|
|
121
|
+
// Use getAll since FormData.entries() is not available in Node.js types
|
|
122
|
+
const allValues = capturedFormData.getAll("data_project://");
|
|
123
|
+
expect(allValues.length).toBe(3);
|
|
124
|
+
});
|
|
125
|
+
});
|
|
126
|
+
describe("validateBuildConfig", () => {
|
|
127
|
+
it("passes with valid config", () => {
|
|
128
|
+
expect(() => validateBuildConfig(config)).not.toThrow();
|
|
129
|
+
});
|
|
130
|
+
it("throws on missing baseUrl", () => {
|
|
131
|
+
expect(() => validateBuildConfig({ token: "test" })).toThrow("Missing baseUrl");
|
|
132
|
+
});
|
|
133
|
+
it("throws on missing token", () => {
|
|
134
|
+
expect(() => validateBuildConfig({ baseUrl: "https://api.tinybird.co" })).toThrow("Missing token");
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
//# sourceMappingURL=build.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build.test.js","sourceRoot":"","sources":["../../src/api/build.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deploy resources to Tinybird main workspace
|
|
3
|
+
* Uses the /v1/deploy endpoint (same payload format as /v1/build)
|
|
4
|
+
*/
|
|
5
|
+
import type { GeneratedResources } from "../generator/index.js";
|
|
6
|
+
import type { BuildConfig, BuildApiResult } from "./build.js";
|
|
7
|
+
/**
|
|
8
|
+
* Deploy generated resources to Tinybird main workspace
|
|
9
|
+
*
|
|
10
|
+
* Uses the /v1/deploy endpoint which accepts all resources in a single
|
|
11
|
+
* multipart form request. This is used for deploying to the main workspace
|
|
12
|
+
* (not branches).
|
|
13
|
+
*
|
|
14
|
+
* @param config - Build configuration with API URL and token
|
|
15
|
+
* @param resources - Generated resources to deploy
|
|
16
|
+
* @returns Build result
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* const result = await deployToMain(
|
|
21
|
+
* {
|
|
22
|
+
* baseUrl: 'https://api.tinybird.co',
|
|
23
|
+
* token: 'p.xxx',
|
|
24
|
+
* },
|
|
25
|
+
* {
|
|
26
|
+
* datasources: [{ name: 'events', content: '...' }],
|
|
27
|
+
* pipes: [{ name: 'top_events', content: '...' }],
|
|
28
|
+
* }
|
|
29
|
+
* );
|
|
30
|
+
*
|
|
31
|
+
* if (result.success) {
|
|
32
|
+
* console.log('Deployed to main workspace!');
|
|
33
|
+
* }
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare function deployToMain(config: BuildConfig, resources: GeneratedResources, options?: {
|
|
37
|
+
debug?: boolean;
|
|
38
|
+
}): Promise<BuildApiResult>;
|
|
39
|
+
//# sourceMappingURL=deploy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/api/deploy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAiB,MAAM,YAAY,CAAC;AAE7E;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,kBAAkB,EAC7B,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5B,OAAO,CAAC,cAAc,CAAC,CAyHzB"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deploy resources to Tinybird main workspace
|
|
3
|
+
* Uses the /v1/deploy endpoint (same payload format as /v1/build)
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Deploy generated resources to Tinybird main workspace
|
|
7
|
+
*
|
|
8
|
+
* Uses the /v1/deploy endpoint which accepts all resources in a single
|
|
9
|
+
* multipart form request. This is used for deploying to the main workspace
|
|
10
|
+
* (not branches).
|
|
11
|
+
*
|
|
12
|
+
* @param config - Build configuration with API URL and token
|
|
13
|
+
* @param resources - Generated resources to deploy
|
|
14
|
+
* @returns Build result
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* const result = await deployToMain(
|
|
19
|
+
* {
|
|
20
|
+
* baseUrl: 'https://api.tinybird.co',
|
|
21
|
+
* token: 'p.xxx',
|
|
22
|
+
* },
|
|
23
|
+
* {
|
|
24
|
+
* datasources: [{ name: 'events', content: '...' }],
|
|
25
|
+
* pipes: [{ name: 'top_events', content: '...' }],
|
|
26
|
+
* }
|
|
27
|
+
* );
|
|
28
|
+
*
|
|
29
|
+
* if (result.success) {
|
|
30
|
+
* console.log('Deployed to main workspace!');
|
|
31
|
+
* }
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export async function deployToMain(config, resources, options) {
|
|
35
|
+
const debug = options?.debug ?? !!process.env.TINYBIRD_DEBUG;
|
|
36
|
+
const formData = new FormData();
|
|
37
|
+
// Add datasources
|
|
38
|
+
for (const ds of resources.datasources) {
|
|
39
|
+
const fieldName = `data_project://`;
|
|
40
|
+
const fileName = `${ds.name}.datasource`;
|
|
41
|
+
if (debug) {
|
|
42
|
+
console.log(`[debug] Adding datasource: ${fieldName} (filename: ${fileName})`);
|
|
43
|
+
console.log(`[debug] Content:\n${ds.content}\n`);
|
|
44
|
+
}
|
|
45
|
+
formData.append(fieldName, new Blob([ds.content], { type: "text/plain" }), fileName);
|
|
46
|
+
}
|
|
47
|
+
// Add pipes
|
|
48
|
+
for (const pipe of resources.pipes) {
|
|
49
|
+
const fieldName = `data_project://`;
|
|
50
|
+
const fileName = `${pipe.name}.pipe`;
|
|
51
|
+
if (debug) {
|
|
52
|
+
console.log(`[debug] Adding pipe: ${fieldName} (filename: ${fileName})`);
|
|
53
|
+
console.log(`[debug] Content:\n${pipe.content}\n`);
|
|
54
|
+
}
|
|
55
|
+
formData.append(fieldName, new Blob([pipe.content], { type: "text/plain" }), fileName);
|
|
56
|
+
}
|
|
57
|
+
// Make the request to /v1/deploy (instead of /v1/build)
|
|
58
|
+
const url = `${config.baseUrl.replace(/\/$/, "")}/v1/deploy`;
|
|
59
|
+
if (debug) {
|
|
60
|
+
console.log(`[debug] POST ${url}`);
|
|
61
|
+
}
|
|
62
|
+
const response = await fetch(url, {
|
|
63
|
+
method: "POST",
|
|
64
|
+
headers: {
|
|
65
|
+
Authorization: `Bearer ${config.token}`,
|
|
66
|
+
},
|
|
67
|
+
body: formData,
|
|
68
|
+
});
|
|
69
|
+
// Parse response
|
|
70
|
+
let body;
|
|
71
|
+
const rawBody = await response.text();
|
|
72
|
+
if (debug) {
|
|
73
|
+
console.log(`[debug] Response status: ${response.status}`);
|
|
74
|
+
console.log(`[debug] Response body: ${rawBody}`);
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
body = JSON.parse(rawBody);
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
throw new Error(`Failed to parse response from Tinybird API: ${response.status} ${response.statusText}\nBody: ${rawBody}`);
|
|
81
|
+
}
|
|
82
|
+
// Helper to format errors
|
|
83
|
+
const formatErrors = () => {
|
|
84
|
+
if (body.errors && body.errors.length > 0) {
|
|
85
|
+
return body.errors
|
|
86
|
+
.map((e) => {
|
|
87
|
+
const prefix = e.filename ? `[${e.filename}] ` : "";
|
|
88
|
+
return `${prefix}${e.error}`;
|
|
89
|
+
})
|
|
90
|
+
.join("\n");
|
|
91
|
+
}
|
|
92
|
+
return body.error || `HTTP ${response.status}: ${response.statusText}`;
|
|
93
|
+
};
|
|
94
|
+
// Handle non-OK responses
|
|
95
|
+
if (!response.ok) {
|
|
96
|
+
return {
|
|
97
|
+
success: false,
|
|
98
|
+
result: "failed",
|
|
99
|
+
error: formatErrors(),
|
|
100
|
+
datasourceCount: resources.datasources.length,
|
|
101
|
+
pipeCount: resources.pipes.length,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
// Handle API result
|
|
105
|
+
if (body.result === "failed") {
|
|
106
|
+
return {
|
|
107
|
+
success: false,
|
|
108
|
+
result: "failed",
|
|
109
|
+
error: formatErrors(),
|
|
110
|
+
datasourceCount: resources.datasources.length,
|
|
111
|
+
pipeCount: resources.pipes.length,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
success: true,
|
|
116
|
+
result: body.result,
|
|
117
|
+
datasourceCount: resources.datasources.length,
|
|
118
|
+
pipeCount: resources.pipes.length,
|
|
119
|
+
buildId: body.build?.id,
|
|
120
|
+
pipes: {
|
|
121
|
+
changed: body.build?.changed_pipe_names ?? [],
|
|
122
|
+
created: body.build?.new_pipe_names ?? [],
|
|
123
|
+
deleted: body.build?.deleted_pipe_names ?? [],
|
|
124
|
+
},
|
|
125
|
+
datasources: {
|
|
126
|
+
changed: body.build?.changed_datasource_names ?? [],
|
|
127
|
+
created: body.build?.new_datasource_names ?? [],
|
|
128
|
+
deleted: body.build?.deleted_datasource_names ?? [],
|
|
129
|
+
},
|
|
130
|
+
// Keep deprecated fields for backwards compatibility
|
|
131
|
+
changedPipeNames: body.build?.changed_pipe_names ?? [],
|
|
132
|
+
newPipeNames: body.build?.new_pipe_names ?? [],
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=deploy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.js","sourceRoot":"","sources":["../../src/api/deploy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.test.d.ts","sourceRoot":"","sources":["../../src/api/deploy.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { describe, it, expect, beforeAll, afterEach, afterAll } from "vitest";
|
|
2
|
+
import { setupServer } from "msw/node";
|
|
3
|
+
import { http, HttpResponse } from "msw";
|
|
4
|
+
import { deployToMain } from "./deploy.js";
|
|
5
|
+
import { BASE_URL, createBuildSuccessResponse, createBuildFailureResponse, createBuildMultipleErrorsResponse, createNoChangesResponse, } from "../test/handlers.js";
|
|
6
|
+
const server = setupServer();
|
|
7
|
+
beforeAll(() => server.listen({ onUnhandledRequest: "error" }));
|
|
8
|
+
afterEach(() => server.resetHandlers());
|
|
9
|
+
afterAll(() => server.close());
|
|
10
|
+
describe("Deploy API", () => {
|
|
11
|
+
const config = {
|
|
12
|
+
baseUrl: BASE_URL,
|
|
13
|
+
token: "p.test-token",
|
|
14
|
+
};
|
|
15
|
+
const resources = {
|
|
16
|
+
datasources: [
|
|
17
|
+
{ name: "events", content: "SCHEMA > timestamp DateTime" },
|
|
18
|
+
],
|
|
19
|
+
pipes: [
|
|
20
|
+
{ name: "top_events", content: "NODE main\nSQL > SELECT * FROM events" },
|
|
21
|
+
],
|
|
22
|
+
};
|
|
23
|
+
describe("deployToMain", () => {
|
|
24
|
+
it("successfully deploys resources", async () => {
|
|
25
|
+
server.use(http.post(`${BASE_URL}/v1/deploy`, () => {
|
|
26
|
+
return HttpResponse.json(createBuildSuccessResponse({
|
|
27
|
+
buildId: "deploy-abc",
|
|
28
|
+
newPipes: ["top_events"],
|
|
29
|
+
newDatasources: ["events"],
|
|
30
|
+
}));
|
|
31
|
+
}));
|
|
32
|
+
const result = await deployToMain(config, resources);
|
|
33
|
+
expect(result.success).toBe(true);
|
|
34
|
+
expect(result.result).toBe("success");
|
|
35
|
+
expect(result.buildId).toBe("deploy-abc");
|
|
36
|
+
expect(result.datasourceCount).toBe(1);
|
|
37
|
+
expect(result.pipeCount).toBe(1);
|
|
38
|
+
expect(result.pipes?.created).toEqual(["top_events"]);
|
|
39
|
+
expect(result.datasources?.created).toEqual(["events"]);
|
|
40
|
+
});
|
|
41
|
+
it("handles no changes response", async () => {
|
|
42
|
+
server.use(http.post(`${BASE_URL}/v1/deploy`, () => {
|
|
43
|
+
return HttpResponse.json(createNoChangesResponse());
|
|
44
|
+
}));
|
|
45
|
+
const result = await deployToMain(config, resources);
|
|
46
|
+
expect(result.success).toBe(true);
|
|
47
|
+
expect(result.result).toBe("no_changes");
|
|
48
|
+
});
|
|
49
|
+
it("handles deploy failure with single error", async () => {
|
|
50
|
+
server.use(http.post(`${BASE_URL}/v1/deploy`, () => {
|
|
51
|
+
return HttpResponse.json(createBuildFailureResponse("Permission denied"), { status: 200 });
|
|
52
|
+
}));
|
|
53
|
+
const result = await deployToMain(config, resources);
|
|
54
|
+
expect(result.success).toBe(false);
|
|
55
|
+
expect(result.result).toBe("failed");
|
|
56
|
+
expect(result.error).toBe("Permission denied");
|
|
57
|
+
});
|
|
58
|
+
it("handles deploy failure with multiple errors", async () => {
|
|
59
|
+
server.use(http.post(`${BASE_URL}/v1/deploy`, () => {
|
|
60
|
+
return HttpResponse.json(createBuildMultipleErrorsResponse([
|
|
61
|
+
{ filename: "events.datasource", error: "Schema mismatch" },
|
|
62
|
+
{ error: "General error without filename" },
|
|
63
|
+
]), { status: 200 });
|
|
64
|
+
}));
|
|
65
|
+
const result = await deployToMain(config, resources);
|
|
66
|
+
expect(result.success).toBe(false);
|
|
67
|
+
expect(result.error).toContain("[events.datasource] Schema mismatch");
|
|
68
|
+
expect(result.error).toContain("General error without filename");
|
|
69
|
+
});
|
|
70
|
+
it("handles HTTP error responses", async () => {
|
|
71
|
+
server.use(http.post(`${BASE_URL}/v1/deploy`, () => {
|
|
72
|
+
return HttpResponse.json({ result: "failed", error: "Forbidden" }, { status: 403 });
|
|
73
|
+
}));
|
|
74
|
+
const result = await deployToMain(config, resources);
|
|
75
|
+
expect(result.success).toBe(false);
|
|
76
|
+
expect(result.error).toBe("Forbidden");
|
|
77
|
+
});
|
|
78
|
+
it("handles malformed JSON response", async () => {
|
|
79
|
+
server.use(http.post(`${BASE_URL}/v1/deploy`, () => {
|
|
80
|
+
return new HttpResponse("invalid json {", {
|
|
81
|
+
status: 200,
|
|
82
|
+
headers: { "Content-Type": "text/plain" },
|
|
83
|
+
});
|
|
84
|
+
}));
|
|
85
|
+
await expect(deployToMain(config, resources)).rejects.toThrow("Failed to parse response");
|
|
86
|
+
});
|
|
87
|
+
it("uses /v1/deploy endpoint (not /v1/build)", async () => {
|
|
88
|
+
let capturedUrl = null;
|
|
89
|
+
server.use(http.post(`${BASE_URL}/v1/deploy`, ({ request }) => {
|
|
90
|
+
capturedUrl = request.url;
|
|
91
|
+
return HttpResponse.json(createBuildSuccessResponse());
|
|
92
|
+
}));
|
|
93
|
+
await deployToMain(config, resources);
|
|
94
|
+
expect(capturedUrl).toBe(`${BASE_URL}/v1/deploy`);
|
|
95
|
+
});
|
|
96
|
+
it("tracks changed and deleted resources", async () => {
|
|
97
|
+
server.use(http.post(`${BASE_URL}/v1/deploy`, () => {
|
|
98
|
+
return HttpResponse.json(createBuildSuccessResponse({
|
|
99
|
+
changedPipes: ["top_events"],
|
|
100
|
+
deletedDatasources: ["old_ds"],
|
|
101
|
+
}));
|
|
102
|
+
}));
|
|
103
|
+
const result = await deployToMain(config, resources);
|
|
104
|
+
expect(result.pipes?.changed).toEqual(["top_events"]);
|
|
105
|
+
expect(result.datasources?.deleted).toEqual(["old_ds"]);
|
|
106
|
+
});
|
|
107
|
+
it("normalizes baseUrl with trailing slash", async () => {
|
|
108
|
+
let capturedUrl = null;
|
|
109
|
+
server.use(http.post(`${BASE_URL}/v1/deploy`, ({ request }) => {
|
|
110
|
+
capturedUrl = request.url;
|
|
111
|
+
return HttpResponse.json(createBuildSuccessResponse());
|
|
112
|
+
}));
|
|
113
|
+
await deployToMain({ ...config, baseUrl: `${BASE_URL}/` }, resources);
|
|
114
|
+
expect(capturedUrl).toBe(`${BASE_URL}/v1/deploy`);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
//# sourceMappingURL=deploy.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploy.test.js","sourceRoot":"","sources":["../../src/api/deploy.test.ts"],"names":[],"mappings":"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"}
|