@tinybirdco/sdk 0.0.29 → 0.0.30

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.
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Open Dashboard command - opens the Tinybird dashboard in the default browser
3
+ */
4
+ /**
5
+ * Environment options for opening dashboard
6
+ */
7
+ export type Environment = "cloud" | "local" | "branch";
8
+ /**
9
+ * Open dashboard command options
10
+ */
11
+ export interface OpenDashboardCommandOptions {
12
+ /** Working directory (defaults to cwd) */
13
+ cwd?: string;
14
+ /** Which environment to open: "cloud", "local", or "branch" */
15
+ environment?: Environment;
16
+ }
17
+ /**
18
+ * Result of the open dashboard command
19
+ */
20
+ export interface OpenDashboardCommandResult {
21
+ /** Whether the operation was successful */
22
+ success: boolean;
23
+ /** The URL that was opened */
24
+ url?: string;
25
+ /** Which environment was opened */
26
+ environment?: Environment;
27
+ /** Whether the browser was opened */
28
+ browserOpened?: boolean;
29
+ /** Error message if failed */
30
+ error?: string;
31
+ }
32
+ /**
33
+ * Run the open dashboard command
34
+ *
35
+ * @param options - Command options
36
+ * @returns Result with URL and status
37
+ */
38
+ export declare function runOpenDashboard(options?: OpenDashboardCommandOptions): Promise<OpenDashboardCommandResult>;
39
+ //# sourceMappingURL=open-dashboard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-dashboard.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/open-dashboard.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkBH;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEvD;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,0CAA0C;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,2CAA2C;IAC3C,OAAO,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,qCAAqC;IACrC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,0BAA0B,CAAC,CAqHrC"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Open Dashboard command - opens the Tinybird dashboard in the default browser
3
+ */
4
+ import { loadConfig } from "../config.js";
5
+ import { getWorkspace } from "../../api/workspaces.js";
6
+ import { getBranch } from "../../api/branches.js";
7
+ import { getDashboardUrl, getBranchDashboardUrl, getLocalDashboardUrl, } from "../../api/dashboard.js";
8
+ import { isLocalRunning, getLocalTokens, getOrCreateLocalWorkspace, getLocalWorkspaceName, } from "../../api/local.js";
9
+ import { openBrowser } from "../auth.js";
10
+ /**
11
+ * Run the open dashboard command
12
+ *
13
+ * @param options - Command options
14
+ * @returns Result with URL and status
15
+ */
16
+ export async function runOpenDashboard(options = {}) {
17
+ const cwd = options.cwd ?? process.cwd();
18
+ // Load config
19
+ let config;
20
+ try {
21
+ config = loadConfig(cwd);
22
+ }
23
+ catch (error) {
24
+ return {
25
+ success: false,
26
+ error: error.message,
27
+ };
28
+ }
29
+ // Determine environment: use option if provided, otherwise use devMode from config
30
+ // When devMode is "branch" but on main branch, default to "cloud"
31
+ let environment;
32
+ if (options.environment) {
33
+ environment = options.environment;
34
+ }
35
+ else if (config.devMode === "local") {
36
+ environment = "local";
37
+ }
38
+ else if (config.devMode === "branch" && !config.isMainBranch && config.tinybirdBranch) {
39
+ environment = "branch";
40
+ }
41
+ else {
42
+ environment = "cloud";
43
+ }
44
+ // Get workspace info (needed for all dashboard URLs)
45
+ let workspace;
46
+ try {
47
+ workspace = await getWorkspace({
48
+ baseUrl: config.baseUrl,
49
+ token: config.token,
50
+ });
51
+ }
52
+ catch (error) {
53
+ return {
54
+ success: false,
55
+ error: `Failed to get workspace info: ${error.message}`,
56
+ };
57
+ }
58
+ let url = null;
59
+ if (environment === "local") {
60
+ // Open local dashboard
61
+ const localRunning = await isLocalRunning();
62
+ if (!localRunning) {
63
+ return {
64
+ success: false,
65
+ error: "Tinybird local is not running. Start with: docker run -d -p 7181:7181 tinybirdco/tinybird-local",
66
+ };
67
+ }
68
+ try {
69
+ const tokens = await getLocalTokens();
70
+ // Determine workspace name: use authenticated workspace name on main branch,
71
+ // otherwise use branch name (for trunk-based development support)
72
+ let workspaceName;
73
+ if (config.isMainBranch || !config.tinybirdBranch) {
74
+ workspaceName = workspace.name;
75
+ }
76
+ else {
77
+ workspaceName = getLocalWorkspaceName(config.tinybirdBranch, config.cwd);
78
+ }
79
+ const { workspace: localWorkspace } = await getOrCreateLocalWorkspace(tokens, workspaceName);
80
+ url = getLocalDashboardUrl(localWorkspace.name);
81
+ }
82
+ catch (error) {
83
+ return {
84
+ success: false,
85
+ error: `Failed to get local workspace: ${error.message}`,
86
+ };
87
+ }
88
+ }
89
+ else if (environment === "branch") {
90
+ // Open branch dashboard
91
+ if (config.isMainBranch || !config.tinybirdBranch) {
92
+ return {
93
+ success: false,
94
+ error: "Cannot open branch dashboard: not on a feature branch.",
95
+ };
96
+ }
97
+ try {
98
+ const branch = await getBranch({ baseUrl: config.baseUrl, token: config.token }, config.tinybirdBranch);
99
+ url = getBranchDashboardUrl(config.baseUrl, workspace.name, branch.name);
100
+ }
101
+ catch (error) {
102
+ return {
103
+ success: false,
104
+ error: `Branch '${config.tinybirdBranch}' does not exist. Run 'tinybird build' to create it.`,
105
+ };
106
+ }
107
+ }
108
+ else {
109
+ // Open cloud (main workspace) dashboard
110
+ url = getDashboardUrl(config.baseUrl, workspace.name);
111
+ }
112
+ if (!url) {
113
+ return {
114
+ success: false,
115
+ error: "Could not generate dashboard URL for this configuration.",
116
+ };
117
+ }
118
+ // Open the browser
119
+ const browserOpened = await openBrowser(url);
120
+ return {
121
+ success: true,
122
+ url,
123
+ environment,
124
+ browserOpened,
125
+ };
126
+ }
127
+ //# sourceMappingURL=open-dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-dashboard.js","sourceRoot":"","sources":["../../../src/cli/commands/open-dashboard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=open-dashboard.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-dashboard.test.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/open-dashboard.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,373 @@
1
+ import { describe, it, expect, beforeEach, vi } from "vitest";
2
+ import { runOpenDashboard } from "./open-dashboard.js";
3
+ // Mock the config module
4
+ vi.mock("../config.js", () => ({
5
+ loadConfig: vi.fn(),
6
+ }));
7
+ // Mock the API modules
8
+ vi.mock("../../api/workspaces.js", () => ({
9
+ getWorkspace: vi.fn(),
10
+ }));
11
+ vi.mock("../../api/branches.js", () => ({
12
+ getBranch: vi.fn(),
13
+ }));
14
+ vi.mock("../../api/dashboard.js", () => ({
15
+ getDashboardUrl: vi.fn(),
16
+ getBranchDashboardUrl: vi.fn(),
17
+ getLocalDashboardUrl: vi.fn(),
18
+ }));
19
+ vi.mock("../../api/local.js", () => ({
20
+ isLocalRunning: vi.fn(),
21
+ getLocalTokens: vi.fn(),
22
+ getOrCreateLocalWorkspace: vi.fn(),
23
+ getLocalWorkspaceName: vi.fn(),
24
+ }));
25
+ vi.mock("../auth.js", () => ({
26
+ openBrowser: vi.fn(),
27
+ }));
28
+ // Import mocked functions
29
+ import { loadConfig } from "../config.js";
30
+ import { getWorkspace } from "../../api/workspaces.js";
31
+ import { getBranch } from "../../api/branches.js";
32
+ import { getDashboardUrl, getBranchDashboardUrl, getLocalDashboardUrl, } from "../../api/dashboard.js";
33
+ import { isLocalRunning, getLocalTokens, getOrCreateLocalWorkspace, getLocalWorkspaceName, } from "../../api/local.js";
34
+ import { openBrowser } from "../auth.js";
35
+ const mockedLoadConfig = vi.mocked(loadConfig);
36
+ const mockedGetWorkspace = vi.mocked(getWorkspace);
37
+ const mockedGetBranch = vi.mocked(getBranch);
38
+ const mockedGetDashboardUrl = vi.mocked(getDashboardUrl);
39
+ const mockedGetBranchDashboardUrl = vi.mocked(getBranchDashboardUrl);
40
+ const mockedGetLocalDashboardUrl = vi.mocked(getLocalDashboardUrl);
41
+ const mockedIsLocalRunning = vi.mocked(isLocalRunning);
42
+ const mockedGetLocalTokens = vi.mocked(getLocalTokens);
43
+ const mockedGetOrCreateLocalWorkspace = vi.mocked(getOrCreateLocalWorkspace);
44
+ const mockedGetLocalWorkspaceName = vi.mocked(getLocalWorkspaceName);
45
+ const mockedOpenBrowser = vi.mocked(openBrowser);
46
+ describe("Open Dashboard Command", () => {
47
+ beforeEach(() => {
48
+ vi.clearAllMocks();
49
+ mockedOpenBrowser.mockResolvedValue(true);
50
+ });
51
+ describe("config loading", () => {
52
+ it("returns error when config loading fails", async () => {
53
+ mockedLoadConfig.mockImplementation(() => {
54
+ throw new Error("No tinybird.json found");
55
+ });
56
+ const result = await runOpenDashboard();
57
+ expect(result.success).toBe(false);
58
+ expect(result.error).toContain("No tinybird.json found");
59
+ });
60
+ });
61
+ describe("cloud environment", () => {
62
+ const mockConfig = {
63
+ cwd: "/test/project",
64
+ configPath: "/test/project/tinybird.json",
65
+ devMode: "branch",
66
+ gitBranch: "main",
67
+ tinybirdBranch: null,
68
+ isMainBranch: true,
69
+ baseUrl: "https://api.tinybird.co",
70
+ token: "test-token",
71
+ include: [],
72
+ };
73
+ const mockWorkspace = {
74
+ id: "ws-123",
75
+ name: "test-workspace",
76
+ user_email: "user@example.com",
77
+ user_id: "user-123",
78
+ scope: "WORKSPACE",
79
+ main: null,
80
+ };
81
+ beforeEach(() => {
82
+ mockedLoadConfig.mockReturnValue(mockConfig);
83
+ mockedGetWorkspace.mockResolvedValue(mockWorkspace);
84
+ mockedGetDashboardUrl.mockReturnValue("https://cloud.tinybird.co/gcp/europe-west3/test-workspace");
85
+ });
86
+ it("opens cloud dashboard when environment is cloud", async () => {
87
+ const result = await runOpenDashboard({ environment: "cloud" });
88
+ expect(result.success).toBe(true);
89
+ expect(result.environment).toBe("cloud");
90
+ expect(result.url).toBe("https://cloud.tinybird.co/gcp/europe-west3/test-workspace");
91
+ expect(result.browserOpened).toBe(true);
92
+ expect(mockedOpenBrowser).toHaveBeenCalledWith("https://cloud.tinybird.co/gcp/europe-west3/test-workspace");
93
+ });
94
+ it("defaults to cloud when devMode is branch and on main branch", async () => {
95
+ const result = await runOpenDashboard();
96
+ expect(result.success).toBe(true);
97
+ expect(result.environment).toBe("cloud");
98
+ });
99
+ });
100
+ describe("branch environment", () => {
101
+ const mockConfig = {
102
+ cwd: "/test/project",
103
+ configPath: "/test/project/tinybird.json",
104
+ devMode: "branch",
105
+ gitBranch: "feature/test",
106
+ tinybirdBranch: "feature_test",
107
+ isMainBranch: false,
108
+ baseUrl: "https://api.tinybird.co",
109
+ token: "test-token",
110
+ include: [],
111
+ };
112
+ const mockWorkspace = {
113
+ id: "ws-123",
114
+ name: "test-workspace",
115
+ user_email: "user@example.com",
116
+ user_id: "user-123",
117
+ scope: "WORKSPACE",
118
+ main: null,
119
+ };
120
+ beforeEach(() => {
121
+ mockedLoadConfig.mockReturnValue(mockConfig);
122
+ mockedGetWorkspace.mockResolvedValue(mockWorkspace);
123
+ });
124
+ it("opens branch dashboard when environment is branch", async () => {
125
+ const mockBranch = {
126
+ id: "branch-123",
127
+ name: "feature_test",
128
+ token: "branch-token",
129
+ created_at: "2024-01-01",
130
+ };
131
+ mockedGetBranch.mockResolvedValue(mockBranch);
132
+ mockedGetBranchDashboardUrl.mockReturnValue("https://cloud.tinybird.co/gcp/europe-west3/test-workspace~feature_test");
133
+ const result = await runOpenDashboard({ environment: "branch" });
134
+ expect(result.success).toBe(true);
135
+ expect(result.environment).toBe("branch");
136
+ expect(result.url).toBe("https://cloud.tinybird.co/gcp/europe-west3/test-workspace~feature_test");
137
+ expect(mockedGetBranch).toHaveBeenCalledWith({ baseUrl: "https://api.tinybird.co", token: "test-token" }, "feature_test");
138
+ });
139
+ it("defaults to branch when devMode is branch and on feature branch", async () => {
140
+ const mockBranch = {
141
+ id: "branch-123",
142
+ name: "feature_test",
143
+ token: "branch-token",
144
+ created_at: "2024-01-01",
145
+ };
146
+ mockedGetBranch.mockResolvedValue(mockBranch);
147
+ mockedGetBranchDashboardUrl.mockReturnValue("https://cloud.tinybird.co/gcp/europe-west3/test-workspace~feature_test");
148
+ const result = await runOpenDashboard();
149
+ expect(result.success).toBe(true);
150
+ expect(result.environment).toBe("branch");
151
+ });
152
+ it("returns error when trying to open branch on main", async () => {
153
+ mockedLoadConfig.mockReturnValue({
154
+ ...mockConfig,
155
+ gitBranch: "main",
156
+ tinybirdBranch: null,
157
+ isMainBranch: true,
158
+ });
159
+ const result = await runOpenDashboard({ environment: "branch" });
160
+ expect(result.success).toBe(false);
161
+ expect(result.error).toContain("not on a feature branch");
162
+ });
163
+ it("returns error when branch does not exist", async () => {
164
+ mockedGetBranch.mockRejectedValue(new Error("Branch not found"));
165
+ const result = await runOpenDashboard({ environment: "branch" });
166
+ expect(result.success).toBe(false);
167
+ expect(result.error).toContain("does not exist");
168
+ expect(result.error).toContain("tinybird build");
169
+ });
170
+ });
171
+ describe("local environment", () => {
172
+ const mockConfig = {
173
+ cwd: "/test/project",
174
+ configPath: "/test/project/tinybird.json",
175
+ devMode: "local",
176
+ gitBranch: "feature/test",
177
+ tinybirdBranch: "feature_test",
178
+ isMainBranch: false,
179
+ baseUrl: "https://api.tinybird.co",
180
+ token: "test-token",
181
+ include: [],
182
+ };
183
+ const mockWorkspace = {
184
+ id: "ws-123",
185
+ name: "test-workspace",
186
+ user_email: "user@example.com",
187
+ user_id: "user-123",
188
+ scope: "WORKSPACE",
189
+ main: null,
190
+ };
191
+ beforeEach(() => {
192
+ mockedLoadConfig.mockReturnValue(mockConfig);
193
+ mockedGetWorkspace.mockResolvedValue(mockWorkspace);
194
+ });
195
+ it("opens local dashboard when environment is local and local is running", async () => {
196
+ mockedIsLocalRunning.mockResolvedValue(true);
197
+ mockedGetLocalTokens.mockResolvedValue({
198
+ user_token: "local-user-token",
199
+ admin_token: "local-admin-token",
200
+ workspace_admin_token: "local-ws-admin-token",
201
+ });
202
+ mockedGetLocalWorkspaceName.mockReturnValue("feature_test");
203
+ mockedGetOrCreateLocalWorkspace.mockResolvedValue({
204
+ workspace: {
205
+ id: "local-ws-123",
206
+ name: "feature_test",
207
+ token: "local-token",
208
+ },
209
+ wasCreated: false,
210
+ });
211
+ mockedGetLocalDashboardUrl.mockReturnValue("https://cloud.tinybird.co/local/7181/feature_test");
212
+ const result = await runOpenDashboard({ environment: "local" });
213
+ expect(result.success).toBe(true);
214
+ expect(result.environment).toBe("local");
215
+ expect(result.url).toBe("https://cloud.tinybird.co/local/7181/feature_test");
216
+ });
217
+ it("defaults to local when devMode is local", async () => {
218
+ mockedIsLocalRunning.mockResolvedValue(true);
219
+ mockedGetLocalTokens.mockResolvedValue({
220
+ user_token: "local-user-token",
221
+ admin_token: "local-admin-token",
222
+ workspace_admin_token: "local-ws-admin-token",
223
+ });
224
+ mockedGetLocalWorkspaceName.mockReturnValue("feature_test");
225
+ mockedGetOrCreateLocalWorkspace.mockResolvedValue({
226
+ workspace: {
227
+ id: "local-ws-123",
228
+ name: "feature_test",
229
+ token: "local-token",
230
+ },
231
+ wasCreated: false,
232
+ });
233
+ mockedGetLocalDashboardUrl.mockReturnValue("https://cloud.tinybird.co/local/7181/feature_test");
234
+ const result = await runOpenDashboard();
235
+ expect(result.success).toBe(true);
236
+ expect(result.environment).toBe("local");
237
+ });
238
+ it("returns error when local is not running", async () => {
239
+ mockedIsLocalRunning.mockResolvedValue(false);
240
+ const result = await runOpenDashboard({ environment: "local" });
241
+ expect(result.success).toBe(false);
242
+ expect(result.error).toContain("not running");
243
+ expect(result.error).toContain("docker run");
244
+ });
245
+ it("uses workspace name on main branch for local", async () => {
246
+ mockedLoadConfig.mockReturnValue({
247
+ ...mockConfig,
248
+ gitBranch: "main",
249
+ tinybirdBranch: null,
250
+ isMainBranch: true,
251
+ });
252
+ mockedIsLocalRunning.mockResolvedValue(true);
253
+ mockedGetLocalTokens.mockResolvedValue({
254
+ user_token: "local-user-token",
255
+ admin_token: "local-admin-token",
256
+ workspace_admin_token: "local-ws-admin-token",
257
+ });
258
+ mockedGetOrCreateLocalWorkspace.mockResolvedValue({
259
+ workspace: {
260
+ id: "local-ws-123",
261
+ name: "test-workspace",
262
+ token: "local-token",
263
+ },
264
+ wasCreated: false,
265
+ });
266
+ mockedGetLocalDashboardUrl.mockReturnValue("https://cloud.tinybird.co/local/7181/test-workspace");
267
+ const result = await runOpenDashboard({ environment: "local" });
268
+ expect(result.success).toBe(true);
269
+ expect(mockedGetOrCreateLocalWorkspace).toHaveBeenCalledWith(expect.anything(), "test-workspace");
270
+ });
271
+ });
272
+ describe("error handling", () => {
273
+ it("returns error when workspace fetch fails", async () => {
274
+ mockedLoadConfig.mockReturnValue({
275
+ cwd: "/test",
276
+ configPath: "/test/tinybird.json",
277
+ devMode: "branch",
278
+ gitBranch: null,
279
+ tinybirdBranch: null,
280
+ isMainBranch: true,
281
+ baseUrl: "https://api.tinybird.co",
282
+ token: "test-token",
283
+ include: [],
284
+ });
285
+ mockedGetWorkspace.mockRejectedValue(new Error("Unauthorized"));
286
+ const result = await runOpenDashboard({ environment: "cloud" });
287
+ expect(result.success).toBe(false);
288
+ expect(result.error).toContain("Failed to get workspace info");
289
+ expect(result.error).toContain("Unauthorized");
290
+ });
291
+ it("returns error when dashboard URL cannot be generated", async () => {
292
+ mockedLoadConfig.mockReturnValue({
293
+ cwd: "/test",
294
+ configPath: "/test/tinybird.json",
295
+ devMode: "branch",
296
+ gitBranch: null,
297
+ tinybirdBranch: null,
298
+ isMainBranch: true,
299
+ baseUrl: "https://api.tinybird.co",
300
+ token: "test-token",
301
+ include: [],
302
+ });
303
+ mockedGetWorkspace.mockResolvedValue({
304
+ id: "ws-123",
305
+ name: "test-workspace",
306
+ user_email: "user@example.com",
307
+ user_id: "user-123",
308
+ scope: "WORKSPACE",
309
+ main: null,
310
+ });
311
+ mockedGetDashboardUrl.mockReturnValue(null);
312
+ const result = await runOpenDashboard({ environment: "cloud" });
313
+ expect(result.success).toBe(false);
314
+ expect(result.error).toContain("Could not generate dashboard URL");
315
+ });
316
+ it("handles local workspace fetch error", async () => {
317
+ mockedLoadConfig.mockReturnValue({
318
+ cwd: "/test",
319
+ configPath: "/test/tinybird.json",
320
+ devMode: "local",
321
+ gitBranch: "feature/test",
322
+ tinybirdBranch: "feature_test",
323
+ isMainBranch: false,
324
+ baseUrl: "https://api.tinybird.co",
325
+ token: "test-token",
326
+ include: [],
327
+ });
328
+ mockedGetWorkspace.mockResolvedValue({
329
+ id: "ws-123",
330
+ name: "test-workspace",
331
+ user_email: "user@example.com",
332
+ user_id: "user-123",
333
+ scope: "WORKSPACE",
334
+ main: null,
335
+ });
336
+ mockedIsLocalRunning.mockResolvedValue(true);
337
+ mockedGetLocalTokens.mockRejectedValue(new Error("Connection refused"));
338
+ const result = await runOpenDashboard({ environment: "local" });
339
+ expect(result.success).toBe(false);
340
+ expect(result.error).toContain("Failed to get local workspace");
341
+ });
342
+ });
343
+ describe("browser opening", () => {
344
+ it("reports when browser failed to open", async () => {
345
+ mockedLoadConfig.mockReturnValue({
346
+ cwd: "/test",
347
+ configPath: "/test/tinybird.json",
348
+ devMode: "branch",
349
+ gitBranch: null,
350
+ tinybirdBranch: null,
351
+ isMainBranch: true,
352
+ baseUrl: "https://api.tinybird.co",
353
+ token: "test-token",
354
+ include: [],
355
+ });
356
+ mockedGetWorkspace.mockResolvedValue({
357
+ id: "ws-123",
358
+ name: "test-workspace",
359
+ user_email: "user@example.com",
360
+ user_id: "user-123",
361
+ scope: "WORKSPACE",
362
+ main: null,
363
+ });
364
+ mockedGetDashboardUrl.mockReturnValue("https://cloud.tinybird.co/gcp/europe-west3/test-workspace");
365
+ mockedOpenBrowser.mockResolvedValue(false);
366
+ const result = await runOpenDashboard({ environment: "cloud" });
367
+ expect(result.success).toBe(true);
368
+ expect(result.browserOpened).toBe(false);
369
+ expect(result.url).toBe("https://cloud.tinybird.co/gcp/europe-west3/test-workspace");
370
+ });
371
+ });
372
+ });
373
+ //# sourceMappingURL=open-dashboard.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-dashboard.test.js","sourceRoot":"","sources":["../../../src/cli/commands/open-dashboard.test.ts"],"names":[],"mappings":"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"}
package/dist/cli/index.js CHANGED
@@ -20,6 +20,8 @@ import { runDev } from "./commands/dev.js";
20
20
  import { runLogin } from "./commands/login.js";
21
21
  import { runBranchList, runBranchStatus, runBranchDelete, } from "./commands/branch.js";
22
22
  import { runClear } from "./commands/clear.js";
23
+ import { runInfo } from "./commands/info.js";
24
+ import { runOpenDashboard } from "./commands/open-dashboard.js";
23
25
  import { detectPackageManagerInstallCmd, detectPackageManagerRunCmd, hasTinybirdSdkDependency, } from "./utils/package-manager.js";
24
26
  import { output } from "./output.js";
25
27
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -140,6 +142,64 @@ function createCli() {
140
142
  console.log(` API Host: ${result.baseUrl}`);
141
143
  }
142
144
  });
145
+ // Info command
146
+ program
147
+ .command("info")
148
+ .description("Show information about the current project and workspace")
149
+ .option("--json", "Output as JSON")
150
+ .action(async (options) => {
151
+ const result = await runInfo({ json: options.json });
152
+ if (!result.success) {
153
+ console.error(`Error: ${result.error}`);
154
+ process.exit(1);
155
+ }
156
+ if (options.json) {
157
+ // JSON output
158
+ const jsonOutput = {
159
+ cloud: result.cloud,
160
+ local: result.local,
161
+ branch: result.branch,
162
+ project: result.project,
163
+ branches: result.branches,
164
+ };
165
+ console.log(JSON.stringify(jsonOutput, null, 2));
166
+ }
167
+ else {
168
+ // Human-readable output
169
+ output.showInfo({
170
+ cloud: result.cloud,
171
+ local: result.local,
172
+ branch: result.branch,
173
+ project: result.project,
174
+ });
175
+ }
176
+ });
177
+ // Open command
178
+ program
179
+ .command("open")
180
+ .description("Open the Tinybird dashboard in the default browser")
181
+ .option("-e, --env <env>", "Which environment to open: 'cloud', 'local', or 'branch'")
182
+ .action(async (options) => {
183
+ const validEnvs = ["cloud", "local", "branch"];
184
+ if (options.env && !validEnvs.includes(options.env)) {
185
+ console.error(`Error: Invalid environment '${options.env}'. Use one of: ${validEnvs.join(", ")}`);
186
+ process.exit(1);
187
+ }
188
+ const result = await runOpenDashboard({
189
+ environment: options.env,
190
+ });
191
+ if (!result.success) {
192
+ console.error(`Error: ${result.error}`);
193
+ process.exit(1);
194
+ }
195
+ console.log(`Opening ${result.environment} dashboard...`);
196
+ if (result.browserOpened) {
197
+ console.log(`Dashboard: ${result.url}`);
198
+ }
199
+ else {
200
+ console.log(`Could not open browser. Please visit: ${result.url}`);
201
+ }
202
+ });
143
203
  // Build command
144
204
  program
145
205
  .command("build")