@tinybirdco/sdk 0.0.3 → 0.0.6
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 +87 -14
- package/dist/api/deploy.d.ts +41 -3
- package/dist/api/deploy.d.ts.map +1 -1
- package/dist/api/deploy.js +141 -19
- package/dist/api/deploy.js.map +1 -1
- package/dist/api/deploy.test.js +77 -29
- package/dist/api/deploy.test.js.map +1 -1
- package/dist/api/local.d.ts +92 -0
- package/dist/api/local.d.ts.map +1 -0
- package/dist/api/local.js +176 -0
- package/dist/api/local.js.map +1 -0
- package/dist/api/local.test.d.ts +2 -0
- package/dist/api/local.test.d.ts.map +1 -0
- package/dist/api/local.test.js +182 -0
- package/dist/api/local.test.js.map +1 -0
- package/dist/api/resources.d.ts +178 -0
- package/dist/api/resources.d.ts.map +1 -0
- package/dist/api/resources.js +244 -0
- package/dist/api/resources.js.map +1 -0
- package/dist/api/resources.test.d.ts +2 -0
- package/dist/api/resources.test.d.ts.map +1 -0
- package/dist/api/resources.test.js +255 -0
- package/dist/api/resources.test.js.map +1 -0
- package/dist/cli/commands/build.d.ts +6 -4
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +95 -47
- package/dist/cli/commands/build.js.map +1 -1
- package/dist/cli/commands/deploy.d.ts +39 -0
- package/dist/cli/commands/deploy.d.ts.map +1 -0
- package/dist/cli/commands/deploy.js +90 -0
- package/dist/cli/commands/deploy.js.map +1 -0
- package/dist/cli/commands/dev.d.ts +9 -2
- package/dist/cli/commands/dev.d.ts.map +1 -1
- package/dist/cli/commands/dev.js +60 -31
- package/dist/cli/commands/dev.js.map +1 -1
- package/dist/cli/commands/init.d.ts +24 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +174 -23
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/init.test.js +190 -30
- package/dist/cli/commands/init.test.js.map +1 -1
- package/dist/cli/config.d.ts +14 -0
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +7 -0
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/config.test.js +29 -0
- package/dist/cli/config.test.js.map +1 -1
- package/dist/cli/index.js +107 -11
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/utils/package-manager.d.ts +8 -0
- package/dist/cli/utils/package-manager.d.ts.map +1 -0
- package/dist/cli/utils/package-manager.js +45 -0
- package/dist/cli/utils/package-manager.js.map +1 -0
- package/dist/cli/utils/package-manager.test.d.ts +2 -0
- package/dist/cli/utils/package-manager.test.d.ts.map +1 -0
- package/dist/cli/utils/package-manager.test.js +85 -0
- package/dist/cli/utils/package-manager.test.js.map +1 -0
- package/dist/codegen/index.d.ts +39 -0
- package/dist/codegen/index.d.ts.map +1 -0
- package/dist/codegen/index.js +300 -0
- package/dist/codegen/index.js.map +1 -0
- package/dist/codegen/index.test.d.ts +2 -0
- package/dist/codegen/index.test.d.ts.map +1 -0
- package/dist/codegen/index.test.js +310 -0
- package/dist/codegen/index.test.js.map +1 -0
- package/dist/codegen/type-mapper.d.ts +20 -0
- package/dist/codegen/type-mapper.d.ts.map +1 -0
- package/dist/codegen/type-mapper.js +238 -0
- package/dist/codegen/type-mapper.js.map +1 -0
- package/dist/codegen/type-mapper.test.d.ts +2 -0
- package/dist/codegen/type-mapper.test.d.ts.map +1 -0
- package/dist/codegen/type-mapper.test.js +167 -0
- package/dist/codegen/type-mapper.test.js.map +1 -0
- package/dist/codegen/utils.d.ts +46 -0
- package/dist/codegen/utils.d.ts.map +1 -0
- package/dist/codegen/utils.js +141 -0
- package/dist/codegen/utils.js.map +1 -0
- package/dist/codegen/utils.test.d.ts +2 -0
- package/dist/codegen/utils.test.d.ts.map +1 -0
- package/dist/codegen/utils.test.js +178 -0
- package/dist/codegen/utils.test.js.map +1 -0
- package/dist/generator/index.d.ts +3 -0
- package/dist/generator/index.d.ts.map +1 -1
- package/dist/generator/index.js +17 -1
- package/dist/generator/index.js.map +1 -1
- package/dist/generator/index.test.js +104 -1
- package/dist/generator/index.test.js.map +1 -1
- package/dist/generator/loader.d.ts +15 -0
- package/dist/generator/loader.d.ts.map +1 -1
- package/dist/generator/loader.js +24 -0
- package/dist/generator/loader.js.map +1 -1
- package/dist/test/handlers.d.ts +49 -0
- package/dist/test/handlers.d.ts.map +1 -1
- package/dist/test/handlers.js +45 -0
- package/dist/test/handlers.js.map +1 -1
- package/package.json +4 -2
- package/src/api/deploy.test.ts +135 -34
- package/src/api/deploy.ts +203 -23
- package/src/api/local.test.ts +250 -0
- package/src/api/local.ts +270 -0
- package/src/api/resources.test.ts +332 -0
- package/src/api/resources.ts +554 -0
- package/src/cli/commands/build.ts +115 -53
- package/src/cli/commands/deploy.ts +126 -0
- package/src/cli/commands/dev.ts +81 -36
- package/src/cli/commands/init.test.ts +239 -30
- package/src/cli/commands/init.ts +243 -26
- package/src/cli/config.test.ts +47 -0
- package/src/cli/config.ts +20 -0
- package/src/cli/index.ts +120 -11
- package/src/cli/utils/package-manager.test.ts +118 -0
- package/src/cli/utils/package-manager.ts +44 -0
- package/src/codegen/index.test.ts +367 -0
- package/src/codegen/index.ts +379 -0
- package/src/codegen/type-mapper.test.ts +224 -0
- package/src/codegen/type-mapper.ts +265 -0
- package/src/codegen/utils.test.ts +221 -0
- package/src/codegen/utils.ts +174 -0
- package/src/generator/index.test.ts +121 -1
- package/src/generator/index.ts +19 -1
- package/src/generator/loader.ts +43 -0
- package/src/test/handlers.ts +58 -0
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Build command - generates and pushes resources to Tinybird
|
|
2
|
+
* Build command - generates and pushes resources to Tinybird branches
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import { loadConfig, type ResolvedConfig } from "../config.js";
|
|
5
|
+
import { loadConfig, LOCAL_BASE_URL, type ResolvedConfig, type DevMode } from "../config.js";
|
|
6
6
|
import { buildFromInclude, type BuildFromIncludeResult } from "../../generator/index.js";
|
|
7
7
|
import { buildToTinybird, type BuildApiResult } from "../../api/build.js";
|
|
8
|
-
import { deployToMain } from "../../api/deploy.js";
|
|
9
8
|
import { getOrCreateBranch } from "../../api/branches.js";
|
|
9
|
+
import {
|
|
10
|
+
getLocalTokens,
|
|
11
|
+
getOrCreateLocalWorkspace,
|
|
12
|
+
getLocalWorkspaceName,
|
|
13
|
+
LocalNotRunningError,
|
|
14
|
+
} from "../../api/local.js";
|
|
10
15
|
|
|
11
16
|
/**
|
|
12
17
|
* Build command options
|
|
@@ -18,8 +23,8 @@ export interface BuildCommandOptions {
|
|
|
18
23
|
dryRun?: boolean;
|
|
19
24
|
/** Override the token from config (used for branch tokens) */
|
|
20
25
|
tokenOverride?: string;
|
|
21
|
-
/**
|
|
22
|
-
|
|
26
|
+
/** Override the devMode from config */
|
|
27
|
+
devModeOverride?: DevMode;
|
|
23
28
|
}
|
|
24
29
|
|
|
25
30
|
/**
|
|
@@ -41,7 +46,8 @@ export interface BuildCommandResult {
|
|
|
41
46
|
/**
|
|
42
47
|
* Run the build command
|
|
43
48
|
*
|
|
44
|
-
*
|
|
49
|
+
* Builds resources and pushes to Tinybird branches (not main).
|
|
50
|
+
* Use runDeploy for deploying to production.
|
|
45
51
|
*
|
|
46
52
|
* @param options - Build options
|
|
47
53
|
* @returns Build command result
|
|
@@ -86,67 +92,123 @@ export async function runBuild(options: BuildCommandOptions = {}): Promise<Build
|
|
|
86
92
|
};
|
|
87
93
|
}
|
|
88
94
|
|
|
89
|
-
//
|
|
90
|
-
|
|
91
|
-
let effectiveToken = options.tokenOverride ?? config.token;
|
|
92
|
-
let useDeployEndpoint = options.useDeployEndpoint ?? config.isMainBranch;
|
|
93
|
-
|
|
94
|
-
// For feature branches, get or create the Tinybird branch and use its token
|
|
95
|
+
// Determine devMode
|
|
96
|
+
const devMode = options.devModeOverride ?? config.devMode;
|
|
95
97
|
const debug = !!process.env.TINYBIRD_DEBUG;
|
|
98
|
+
|
|
96
99
|
if (debug) {
|
|
97
|
-
console.log(`[debug]
|
|
98
|
-
console.log(`[debug] tinybirdBranch: ${config.tinybirdBranch}`);
|
|
99
|
-
console.log(`[debug] tokenOverride: ${!!options.tokenOverride}`);
|
|
100
|
+
console.log(`[debug] devMode: ${devMode}`);
|
|
100
101
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
102
|
+
|
|
103
|
+
let deployResult: BuildApiResult;
|
|
104
|
+
|
|
105
|
+
// Handle local mode
|
|
106
|
+
if (devMode === "local") {
|
|
105
107
|
try {
|
|
106
|
-
|
|
108
|
+
// Get tokens from local container
|
|
109
|
+
if (debug) {
|
|
110
|
+
console.log(`[debug] Getting local tokens from ${LOCAL_BASE_URL}/tokens`);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const localTokens = await getLocalTokens();
|
|
114
|
+
|
|
115
|
+
// Get or create workspace based on branch name
|
|
116
|
+
const workspaceName = getLocalWorkspaceName(config.tinybirdBranch, config.cwd);
|
|
117
|
+
if (debug) {
|
|
118
|
+
console.log(`[debug] Using local workspace: ${workspaceName}`);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const { workspace, wasCreated } = await getOrCreateLocalWorkspace(localTokens, workspaceName);
|
|
122
|
+
if (debug) {
|
|
123
|
+
console.log(`[debug] Workspace ${wasCreated ? "created" : "found"}: ${workspace.name}`);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Always use /v1/build for local (no deploy endpoint)
|
|
127
|
+
deployResult = await buildToTinybird(
|
|
107
128
|
{
|
|
108
|
-
baseUrl:
|
|
109
|
-
token:
|
|
129
|
+
baseUrl: LOCAL_BASE_URL,
|
|
130
|
+
token: workspace.token,
|
|
110
131
|
},
|
|
111
|
-
|
|
132
|
+
buildResult.resources
|
|
112
133
|
);
|
|
113
|
-
|
|
114
|
-
if (
|
|
134
|
+
} catch (error) {
|
|
135
|
+
if (error instanceof LocalNotRunningError) {
|
|
115
136
|
return {
|
|
116
137
|
success: false,
|
|
117
138
|
build: buildResult,
|
|
118
|
-
error:
|
|
139
|
+
error: error.message,
|
|
119
140
|
durationMs: Date.now() - startTime,
|
|
120
141
|
};
|
|
121
142
|
}
|
|
143
|
+
return {
|
|
144
|
+
success: false,
|
|
145
|
+
build: buildResult,
|
|
146
|
+
error: `Local build failed: ${(error as Error).message}`,
|
|
147
|
+
durationMs: Date.now() - startTime,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
// Branch mode (default)
|
|
152
|
+
// Prevent building to main - must use deploy command
|
|
153
|
+
// Skip this check if tokenOverride is provided (dev command passes branch token)
|
|
154
|
+
const isMainBranch = config.isMainBranch || !config.tinybirdBranch;
|
|
122
155
|
|
|
123
|
-
|
|
124
|
-
useDeployEndpoint = false; // Always use /v1/build for branches
|
|
125
|
-
if (debug) {
|
|
126
|
-
console.log(`[debug] Using branch token for branch: ${config.tinybirdBranch}`);
|
|
127
|
-
}
|
|
128
|
-
} catch (error) {
|
|
156
|
+
if (isMainBranch && !options.tokenOverride) {
|
|
129
157
|
return {
|
|
130
158
|
success: false,
|
|
131
159
|
build: buildResult,
|
|
132
|
-
error: `
|
|
160
|
+
error: `Cannot deploy to main workspace with 'build' command. Use 'tinybird deploy' to deploy to production, or switch to a feature branch.`,
|
|
133
161
|
durationMs: Date.now() - startTime,
|
|
134
162
|
};
|
|
135
163
|
}
|
|
136
|
-
}
|
|
137
164
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
)
|
|
149
|
-
|
|
165
|
+
if (debug) {
|
|
166
|
+
console.log(`[debug] isMainBranch: ${config.isMainBranch}`);
|
|
167
|
+
console.log(`[debug] tinybirdBranch: ${config.tinybirdBranch}`);
|
|
168
|
+
console.log(`[debug] tokenOverride: ${!!options.tokenOverride}`);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
let effectiveToken = options.tokenOverride ?? config.token;
|
|
172
|
+
|
|
173
|
+
// Get or create the Tinybird branch and use its token
|
|
174
|
+
if (!options.tokenOverride) {
|
|
175
|
+
if (debug) {
|
|
176
|
+
console.log(`[debug] Getting/creating Tinybird branch: ${config.tinybirdBranch}`);
|
|
177
|
+
}
|
|
178
|
+
try {
|
|
179
|
+
const tinybirdBranch = await getOrCreateBranch(
|
|
180
|
+
{
|
|
181
|
+
baseUrl: config.baseUrl,
|
|
182
|
+
token: config.token,
|
|
183
|
+
},
|
|
184
|
+
config.tinybirdBranch!
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
if (!tinybirdBranch.token) {
|
|
188
|
+
return {
|
|
189
|
+
success: false,
|
|
190
|
+
build: buildResult,
|
|
191
|
+
error: `Branch '${config.tinybirdBranch}' was created but no token was returned.`,
|
|
192
|
+
durationMs: Date.now() - startTime,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
effectiveToken = tinybirdBranch.token;
|
|
197
|
+
if (debug) {
|
|
198
|
+
console.log(`[debug] Using branch token for branch: ${config.tinybirdBranch}`);
|
|
199
|
+
}
|
|
200
|
+
} catch (error) {
|
|
201
|
+
return {
|
|
202
|
+
success: false,
|
|
203
|
+
build: buildResult,
|
|
204
|
+
error: `Failed to get/create branch: ${(error as Error).message}`,
|
|
205
|
+
durationMs: Date.now() - startTime,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
try {
|
|
211
|
+
// Always use /v1/build for branches
|
|
150
212
|
deployResult = await buildToTinybird(
|
|
151
213
|
{
|
|
152
214
|
baseUrl: config.baseUrl,
|
|
@@ -154,14 +216,14 @@ export async function runBuild(options: BuildCommandOptions = {}): Promise<Build
|
|
|
154
216
|
},
|
|
155
217
|
buildResult.resources
|
|
156
218
|
);
|
|
219
|
+
} catch (error) {
|
|
220
|
+
return {
|
|
221
|
+
success: false,
|
|
222
|
+
build: buildResult,
|
|
223
|
+
error: `Deploy failed: ${(error as Error).message}`,
|
|
224
|
+
durationMs: Date.now() - startTime,
|
|
225
|
+
};
|
|
157
226
|
}
|
|
158
|
-
} catch (error) {
|
|
159
|
-
return {
|
|
160
|
-
success: false,
|
|
161
|
-
build: buildResult,
|
|
162
|
-
error: `Deploy failed: ${(error as Error).message}`,
|
|
163
|
-
durationMs: Date.now() - startTime,
|
|
164
|
-
};
|
|
165
227
|
}
|
|
166
228
|
|
|
167
229
|
if (!deployResult.success) {
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deploy command - deploys resources to main Tinybird workspace
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { loadConfig, type ResolvedConfig } from "../config.js";
|
|
6
|
+
import { buildFromInclude, type BuildFromIncludeResult } from "../../generator/index.js";
|
|
7
|
+
import { deployToMain } from "../../api/deploy.js";
|
|
8
|
+
import type { BuildApiResult } from "../../api/build.js";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Deploy command options
|
|
12
|
+
*/
|
|
13
|
+
export interface DeployCommandOptions {
|
|
14
|
+
/** Working directory (defaults to cwd) */
|
|
15
|
+
cwd?: string;
|
|
16
|
+
/** Skip pushing to API (just generate) */
|
|
17
|
+
dryRun?: boolean;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Deploy command result
|
|
22
|
+
*/
|
|
23
|
+
export interface DeployCommandResult {
|
|
24
|
+
/** Whether the deploy was successful */
|
|
25
|
+
success: boolean;
|
|
26
|
+
/** Build result with generated resources */
|
|
27
|
+
build?: BuildFromIncludeResult;
|
|
28
|
+
/** Deploy API result (if not dry run) */
|
|
29
|
+
deploy?: BuildApiResult;
|
|
30
|
+
/** Error message if failed */
|
|
31
|
+
error?: string;
|
|
32
|
+
/** Duration in milliseconds */
|
|
33
|
+
durationMs: number;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Run the deploy command
|
|
38
|
+
*
|
|
39
|
+
* Builds resources and deploys to main Tinybird workspace (production).
|
|
40
|
+
*
|
|
41
|
+
* @param options - Deploy options
|
|
42
|
+
* @returns Deploy command result
|
|
43
|
+
*/
|
|
44
|
+
export async function runDeploy(options: DeployCommandOptions = {}): Promise<DeployCommandResult> {
|
|
45
|
+
const startTime = Date.now();
|
|
46
|
+
const cwd = options.cwd ?? process.cwd();
|
|
47
|
+
|
|
48
|
+
// Load config
|
|
49
|
+
let config: ResolvedConfig;
|
|
50
|
+
try {
|
|
51
|
+
config = loadConfig(cwd);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
return {
|
|
54
|
+
success: false,
|
|
55
|
+
error: (error as Error).message,
|
|
56
|
+
durationMs: Date.now() - startTime,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Build resources from include paths
|
|
61
|
+
let buildResult: BuildFromIncludeResult;
|
|
62
|
+
try {
|
|
63
|
+
buildResult = await buildFromInclude({
|
|
64
|
+
includePaths: config.include,
|
|
65
|
+
cwd: config.cwd,
|
|
66
|
+
});
|
|
67
|
+
} catch (error) {
|
|
68
|
+
return {
|
|
69
|
+
success: false,
|
|
70
|
+
error: `Build failed: ${(error as Error).message}`,
|
|
71
|
+
durationMs: Date.now() - startTime,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// If dry run, return without pushing
|
|
76
|
+
if (options.dryRun) {
|
|
77
|
+
return {
|
|
78
|
+
success: true,
|
|
79
|
+
build: buildResult,
|
|
80
|
+
durationMs: Date.now() - startTime,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const debug = !!process.env.TINYBIRD_DEBUG;
|
|
85
|
+
|
|
86
|
+
if (debug) {
|
|
87
|
+
console.log(`[debug] Deploying to main workspace`);
|
|
88
|
+
console.log(`[debug] baseUrl: ${config.baseUrl}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Deploy to main workspace using /v1/deploy endpoint
|
|
92
|
+
let deployResult: BuildApiResult;
|
|
93
|
+
try {
|
|
94
|
+
deployResult = await deployToMain(
|
|
95
|
+
{
|
|
96
|
+
baseUrl: config.baseUrl,
|
|
97
|
+
token: config.token,
|
|
98
|
+
},
|
|
99
|
+
buildResult.resources
|
|
100
|
+
);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
return {
|
|
103
|
+
success: false,
|
|
104
|
+
build: buildResult,
|
|
105
|
+
error: `Deploy failed: ${(error as Error).message}`,
|
|
106
|
+
durationMs: Date.now() - startTime,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (!deployResult.success) {
|
|
111
|
+
return {
|
|
112
|
+
success: false,
|
|
113
|
+
build: buildResult,
|
|
114
|
+
deploy: deployResult,
|
|
115
|
+
error: deployResult.error,
|
|
116
|
+
durationMs: Date.now() - startTime,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
success: true,
|
|
122
|
+
build: buildResult,
|
|
123
|
+
deploy: deployResult,
|
|
124
|
+
durationMs: Date.now() - startTime,
|
|
125
|
+
};
|
|
126
|
+
}
|
package/src/cli/commands/dev.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
import * as path from "path";
|
|
6
6
|
import { watch } from "chokidar";
|
|
7
|
-
import { loadConfig, configExists, findConfigFile, hasValidToken, updateConfig, type ResolvedConfig } from "../config.js";
|
|
7
|
+
import { loadConfig, configExists, findConfigFile, hasValidToken, updateConfig, LOCAL_BASE_URL, type ResolvedConfig, type DevMode } from "../config.js";
|
|
8
8
|
import { runBuild, type BuildCommandResult } from "./build.js";
|
|
9
9
|
import { getOrCreateBranch, type TinybirdBranch } from "../../api/branches.js";
|
|
10
10
|
import { browserLogin } from "../auth.js";
|
|
@@ -13,6 +13,12 @@ import {
|
|
|
13
13
|
validatePipeSchemas,
|
|
14
14
|
type SchemaValidationResult,
|
|
15
15
|
} from "../utils/schema-validation.js";
|
|
16
|
+
import {
|
|
17
|
+
getLocalTokens,
|
|
18
|
+
getOrCreateLocalWorkspace,
|
|
19
|
+
getLocalWorkspaceName,
|
|
20
|
+
type LocalWorkspace,
|
|
21
|
+
} from "../../api/local.js";
|
|
16
22
|
|
|
17
23
|
/**
|
|
18
24
|
* Login result info
|
|
@@ -44,6 +50,8 @@ export interface DevCommandOptions {
|
|
|
44
50
|
onLoginComplete?: (info: LoginInfo) => void;
|
|
45
51
|
/** Callback when schema validation completes */
|
|
46
52
|
onSchemaValidation?: (result: SchemaValidationResult) => void;
|
|
53
|
+
/** Override the devMode from config */
|
|
54
|
+
devModeOverride?: DevMode;
|
|
47
55
|
}
|
|
48
56
|
|
|
49
57
|
/**
|
|
@@ -54,10 +62,14 @@ export interface BranchReadyInfo {
|
|
|
54
62
|
gitBranch: string | null;
|
|
55
63
|
/** Whether we're on the main branch */
|
|
56
64
|
isMainBranch: boolean;
|
|
57
|
-
/** Tinybird branch info (null if on main) */
|
|
65
|
+
/** Tinybird branch info (null if on main or local mode) */
|
|
58
66
|
tinybirdBranch?: TinybirdBranch;
|
|
59
67
|
/** Whether the branch was newly created */
|
|
60
68
|
wasCreated?: boolean;
|
|
69
|
+
/** Whether using local mode */
|
|
70
|
+
isLocal?: boolean;
|
|
71
|
+
/** Local workspace info (only in local mode) */
|
|
72
|
+
localWorkspace?: LocalWorkspace;
|
|
61
73
|
}
|
|
62
74
|
|
|
63
75
|
/**
|
|
@@ -98,8 +110,19 @@ export async function runDev(options: DevCommandOptions = {}): Promise<DevContro
|
|
|
98
110
|
);
|
|
99
111
|
}
|
|
100
112
|
|
|
101
|
-
//
|
|
102
|
-
|
|
113
|
+
// Load config first to determine devMode
|
|
114
|
+
let config: ResolvedConfig;
|
|
115
|
+
try {
|
|
116
|
+
config = loadConfig(cwd);
|
|
117
|
+
} catch (error) {
|
|
118
|
+
throw error;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Determine devMode
|
|
122
|
+
const devMode = options.devModeOverride ?? config.devMode;
|
|
123
|
+
|
|
124
|
+
// Check if authentication is set up, if not trigger login (skip for local mode)
|
|
125
|
+
if (devMode !== "local" && !hasValidToken(cwd)) {
|
|
103
126
|
console.log("No authentication found. Starting login flow...\n");
|
|
104
127
|
|
|
105
128
|
const authResult = await browserLogin();
|
|
@@ -134,51 +157,72 @@ export async function runDev(options: DevCommandOptions = {}): Promise<DevContro
|
|
|
134
157
|
workspaceName: authResult.workspaceName,
|
|
135
158
|
userEmail: authResult.userEmail,
|
|
136
159
|
});
|
|
137
|
-
}
|
|
138
160
|
|
|
139
|
-
|
|
140
|
-
let config: ResolvedConfig;
|
|
141
|
-
try {
|
|
161
|
+
// Reload config after login
|
|
142
162
|
config = loadConfig(cwd);
|
|
143
|
-
} catch (error) {
|
|
144
|
-
throw error;
|
|
145
163
|
}
|
|
146
164
|
|
|
147
|
-
// Determine effective token based on
|
|
165
|
+
// Determine effective token and branch info based on devMode
|
|
148
166
|
let effectiveToken = config.token;
|
|
167
|
+
let effectiveBaseUrl = config.baseUrl;
|
|
149
168
|
let branchInfo: BranchReadyInfo = {
|
|
150
169
|
gitBranch: config.gitBranch,
|
|
151
170
|
isMainBranch: config.isMainBranch,
|
|
152
171
|
};
|
|
153
172
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
// Always fetch fresh from API to avoid stale cache issues
|
|
160
|
-
const tinybirdBranch = await getOrCreateBranch(
|
|
161
|
-
{
|
|
162
|
-
baseUrl: config.baseUrl,
|
|
163
|
-
token: config.token,
|
|
164
|
-
},
|
|
165
|
-
branchName
|
|
166
|
-
);
|
|
173
|
+
if (devMode === "local") {
|
|
174
|
+
// Local mode: get tokens from local container and set up workspace
|
|
175
|
+
const localTokens = await getLocalTokens();
|
|
176
|
+
const workspaceName = getLocalWorkspaceName(config.tinybirdBranch, config.cwd);
|
|
177
|
+
const { workspace, wasCreated } = await getOrCreateLocalWorkspace(localTokens, workspaceName);
|
|
167
178
|
|
|
168
|
-
|
|
179
|
+
effectiveToken = workspace.token;
|
|
180
|
+
effectiveBaseUrl = LOCAL_BASE_URL;
|
|
181
|
+
branchInfo = {
|
|
182
|
+
gitBranch: config.gitBranch,
|
|
183
|
+
isMainBranch: false, // Local mode always uses build, not deploy
|
|
184
|
+
isLocal: true,
|
|
185
|
+
localWorkspace: workspace,
|
|
186
|
+
wasCreated,
|
|
187
|
+
};
|
|
188
|
+
} else {
|
|
189
|
+
// Branch mode: use Tinybird cloud with branches
|
|
190
|
+
// Prevent dev mode on main branch - must use deploy command
|
|
191
|
+
if (config.isMainBranch || !config.tinybirdBranch) {
|
|
169
192
|
throw new Error(
|
|
170
|
-
`
|
|
171
|
-
`This may be an API issue.`
|
|
193
|
+
`Cannot use 'dev' command on main branch. Use 'tinybird deploy' to deploy to production, or switch to a feature branch.`
|
|
172
194
|
);
|
|
173
195
|
}
|
|
174
196
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
197
|
+
// Get or create the Tinybird branch
|
|
198
|
+
// Use tinybirdBranch (sanitized name) for Tinybird API, gitBranch for display
|
|
199
|
+
if (config.tinybirdBranch) {
|
|
200
|
+
const branchName = config.tinybirdBranch; // Sanitized name for Tinybird
|
|
201
|
+
|
|
202
|
+
// Always fetch fresh from API to avoid stale cache issues
|
|
203
|
+
const tinybirdBranch = await getOrCreateBranch(
|
|
204
|
+
{
|
|
205
|
+
baseUrl: config.baseUrl,
|
|
206
|
+
token: config.token,
|
|
207
|
+
},
|
|
208
|
+
branchName
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
if (!tinybirdBranch.token) {
|
|
212
|
+
throw new Error(
|
|
213
|
+
`Branch '${branchName}' was created but no token was returned. ` +
|
|
214
|
+
`This may be an API issue.`
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
effectiveToken = tinybirdBranch.token;
|
|
219
|
+
branchInfo = {
|
|
220
|
+
gitBranch: config.gitBranch, // Original git branch name for display
|
|
221
|
+
isMainBranch: false,
|
|
222
|
+
tinybirdBranch,
|
|
223
|
+
wasCreated: tinybirdBranch.wasCreated ?? false,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
182
226
|
}
|
|
183
227
|
|
|
184
228
|
// Notify about branch readiness
|
|
@@ -209,10 +253,11 @@ export async function runDev(options: DevCommandOptions = {}): Promise<DevContro
|
|
|
209
253
|
options.onBuildStart?.();
|
|
210
254
|
|
|
211
255
|
try {
|
|
256
|
+
// Always use runBuild - main branch is blocked at startup
|
|
212
257
|
const result = await runBuild({
|
|
213
258
|
cwd: config.cwd,
|
|
214
259
|
tokenOverride: effectiveToken,
|
|
215
|
-
|
|
260
|
+
devModeOverride: devMode,
|
|
216
261
|
});
|
|
217
262
|
options.onBuildComplete?.(result);
|
|
218
263
|
|
|
@@ -234,7 +279,7 @@ export async function runDev(options: DevCommandOptions = {}): Promise<DevContro
|
|
|
234
279
|
const validation = await validatePipeSchemas({
|
|
235
280
|
entities: result.build.entities,
|
|
236
281
|
pipeNames: changedPipes,
|
|
237
|
-
baseUrl:
|
|
282
|
+
baseUrl: effectiveBaseUrl,
|
|
238
283
|
token: effectiveToken,
|
|
239
284
|
});
|
|
240
285
|
|