Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 18 additions & 8 deletions src/api/dashboard.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,18 +98,28 @@ describe("getBranchDashboardUrl", () => {
});

describe("getLocalDashboardUrl", () => {
it("generates local dashboard URL with default port", () => {
const result = getLocalDashboardUrl("my_local_workspace");
expect(result).toBe("https://cloud.tinybird.co/local/7181/my_local_workspace");
it("generates local dashboard URL with region info", () => {
const result = getLocalDashboardUrl("https://api.tinybird.co", "my_cloud_workspace", "my_local_workspace");
expect(result).toBe("https://cloud.tinybird.co/gcp/europe-west3/my_cloud_workspace~local~my_local_workspace");
});

it("generates local dashboard URL with custom port", () => {
const result = getLocalDashboardUrl("my_local_workspace", 8080);
expect(result).toBe("https://cloud.tinybird.co/local/8080/my_local_workspace");
it("generates local dashboard URL for US East GCP", () => {
const result = getLocalDashboardUrl("https://api.us-east.tinybird.co", "my_cloud_workspace", "feature_branch");
expect(result).toBe("https://cloud.tinybird.co/gcp/us-east4/my_cloud_workspace~local~feature_branch");
});

it("generates local dashboard URL for AWS", () => {
const result = getLocalDashboardUrl("https://api.us-west-2.aws.tinybird.co", "my_cloud_workspace", "feature_branch");
expect(result).toBe("https://cloud.tinybird.co/aws/us-west-2/my_cloud_workspace~local~feature_branch");
});

it("returns null for unknown regions", () => {
const result = getLocalDashboardUrl("https://api.unknown.tinybird.co", "my_cloud_workspace", "feature_branch");
expect(result).toBeNull();
});

it("handles workspace names with underscores", () => {
const result = getLocalDashboardUrl("dublin_feature_branch");
expect(result).toBe("https://cloud.tinybird.co/local/7181/dublin_feature_branch");
const result = getLocalDashboardUrl("https://api.tinybird.co", "tssdkgnzinit", "dublin_feature_branch");
expect(result).toBe("https://cloud.tinybird.co/gcp/europe-west3/tssdkgnzinit~local~dublin_feature_branch");
});
});
22 changes: 15 additions & 7 deletions src/api/dashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,16 +106,24 @@ export function getBranchDashboardUrl(
/**
* Generate a local Tinybird dashboard URL
*
* @param workspaceName - The local workspace name
* @param port - The local Tinybird port (default: 7181)
* @returns Local dashboard URL
* The URL follows the format: https://cloud.tinybird.co/{provider}/{region}/{cloudWorkspaceName}~local~{localWorkspaceName}
*
* @param apiUrl - The Tinybird API base URL (e.g., "https://api.tinybird.co")
* @param cloudWorkspaceName - The cloud workspace name (e.g., "tssdkgnzinit")
* @param localWorkspaceName - The local workspace/branch name (e.g., "rama_nuria")
* @returns Local dashboard URL or null if the API URL is not recognized
*
* @example
* ```ts
* getLocalDashboardUrl("my_local_workspace")
* // => "https://cloud.tinybird.co/local/7181/my_local_workspace"
* getLocalDashboardUrl("https://api.tinybird.co", "tssdkgnzinit", "rama_nuria")
* // => "https://cloud.tinybird.co/gcp/europe-west3/tssdkgnzinit~local~rama_nuria"
* ```
*/
export function getLocalDashboardUrl(workspaceName: string, port = 7181): string {
return `https://cloud.tinybird.co/local/${port}/${workspaceName}`;
export function getLocalDashboardUrl(apiUrl: string, cloudWorkspaceName: string, localWorkspaceName: string): string | null {
const regionInfo = parseApiUrl(apiUrl);
if (!regionInfo) {
return null;
}

return `https://cloud.tinybird.co/${regionInfo.provider}/${regionInfo.region}/${cloudWorkspaceName}~local~${localWorkspaceName}`;
}
15 changes: 9 additions & 6 deletions src/cli/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,16 +135,19 @@ export async function runBuild(options: BuildCommandOptions = {}): Promise<Build

const localTokens = await getLocalTokens();

// Always fetch the cloud workspace name for dashboard URL
const authenticatedWorkspace = await getWorkspace({
baseUrl: config.baseUrl,
token: config.token,
});
const cloudWorkspaceName = authenticatedWorkspace.name;

// Determine workspace name: use authenticated workspace name on main branch,
// otherwise use branch name (for trunk-based development support)
let workspaceName: string;
if (config.isMainBranch || !config.tinybirdBranch) {
// On main branch: use the authenticated workspace name
const authenticatedWorkspace = await getWorkspace({
baseUrl: config.baseUrl,
token: config.token,
});
workspaceName = authenticatedWorkspace.name;
workspaceName = cloudWorkspaceName;
if (debug) {
console.log(`[debug] Using authenticated workspace name: ${workspaceName}`);
}
Expand All @@ -165,7 +168,7 @@ export async function runBuild(options: BuildCommandOptions = {}): Promise<Build
gitBranch: config.gitBranch,
tinybirdBranch: workspaceName,
wasCreated,
dashboardUrl: getLocalDashboardUrl(workspaceName),
dashboardUrl: getLocalDashboardUrl(config.baseUrl, cloudWorkspaceName, workspaceName) ?? undefined,
isLocal: true,
};

Expand Down
15 changes: 9 additions & 6 deletions src/cli/commands/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,16 +193,19 @@ export async function runDev(
// Local mode: get tokens from local container and set up workspace
const localTokens = await getLocalTokens();

// Always fetch the cloud workspace name for dashboard URL
const authenticatedWorkspace = await getWorkspace({
baseUrl: config.baseUrl,
token: config.token,
});
const cloudWorkspaceName = authenticatedWorkspace.name;

// Determine workspace name: use authenticated workspace name on main branch,
// otherwise use branch name (for trunk-based development support)
let workspaceName: string;
if (config.isMainBranch || !config.tinybirdBranch) {
// On main branch: use the authenticated workspace name
const authenticatedWorkspace = await getWorkspace({
baseUrl: config.baseUrl,
token: config.token,
});
workspaceName = authenticatedWorkspace.name;
workspaceName = cloudWorkspaceName;
} else {
// On feature branch: use branch name
workspaceName = getLocalWorkspaceName(config.tinybirdBranch, config.cwd);
Expand All @@ -221,7 +224,7 @@ export async function runDev(
isLocal: true,
localWorkspace: workspace,
wasCreated,
dashboardUrl: getLocalDashboardUrl(workspace.name),
dashboardUrl: getLocalDashboardUrl(config.baseUrl, cloudWorkspaceName, workspace.name) ?? undefined,
};
} else {
// Branch mode: use Tinybird cloud with branches
Expand Down
2 changes: 1 addition & 1 deletion src/cli/commands/info.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ export async function runInfo(
workspaceName: localWorkspace.name,
workspaceId: localWorkspace.id,
apiHost: LOCAL_BASE_URL,
dashboardUrl: getLocalDashboardUrl(localWorkspace.name),
dashboardUrl: getLocalDashboardUrl(config.baseUrl, workspace.name, localWorkspace.name) ?? undefined,
token: localWorkspace.token,
};
} catch {
Expand Down
2 changes: 1 addition & 1 deletion src/cli/commands/open-dashboard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ export async function runOpenDashboard(
tokens,
workspaceName
);
url = getLocalDashboardUrl(localWorkspace.name);
url = getLocalDashboardUrl(config.baseUrl, workspace.name, localWorkspace.name);
} catch (error) {
return {
success: false,
Expand Down
4 changes: 2 additions & 2 deletions src/cli/output.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,9 @@ export function showBranchInfo(info: BranchDisplayInfo): void {
if (info.gitBranch) {
console.log(`» Git branch: ${info.gitBranch}`);
}
// Show local workspace
// Show local branch
const name = info.tinybirdBranch ?? "unknown";
console.log(`» Local workspace: ${name} ${status}`);
console.log(`» Tinybird Local branch: ${name} ${status}`);
// Show dashboard URL
if (info.dashboardUrl) {
console.log(colorize(` ↳ ${info.dashboardUrl}`, "gray"));
Expand Down
Loading