Skip to content

Commit

Permalink
prompt for workspace in db link (#11032)
Browse files Browse the repository at this point in the history
Co-authored-by: Chris Swithinbank <swithinbank@gmail.com>
  • Loading branch information
itsMapleLeaf and delucis authored May 21, 2024
1 parent 8daf2d4 commit b78e83f
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 14 deletions.
7 changes: 7 additions & 0 deletions .changeset/five-ties-raise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@astrojs/db": patch
---

Adds support for multiple Astro Studio workspaces (aka “Teams”) to the Astro DB CLI

Users who are members of a team workspace in Astro Studio can now choose between those and their personal workspace when runnning `astro db link`.
58 changes: 44 additions & 14 deletions packages/db/src/core/cli/commands/link/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,17 @@ export async function cmd() {
console.error(MISSING_SESSION_ID_ERROR);
process.exit(1);
}
const getWorkspaceIdAsync = getWorkspaceId().catch((err) => {
return err as Error;
});
await promptBegin();
const isLinkExisting = await promptLinkExisting();
if (isLinkExisting) {
const workspaceId = unwrapWorkspaceId(await getWorkspaceIdAsync);
const workspaceId = await promptWorkspace(sessionToken);
const existingProjectData = await promptExistingProjectName({ workspaceId });
return await linkProject(existingProjectData.id);
}

const isLinkNew = await promptLinkNew();
if (isLinkNew) {
const workspaceId = unwrapWorkspaceId(await getWorkspaceIdAsync);
const workspaceId = await promptWorkspace(sessionToken);
const newProjectName = await promptNewProjectName();
const newProjectRegion = await promptNewProjectRegion();
const spinner = ora('Creating new project...').start();
Expand All @@ -56,14 +53,14 @@ async function linkProject(id: string) {
console.info('Project linked.');
}

async function getWorkspaceId(): Promise<string> {
async function getWorkspaces(sessionToken: string) {
const linkUrl = new URL(getAstroStudioUrl() + '/api/cli/workspaces.list');
const response = await safeFetch(
linkUrl,
{
method: 'POST',
headers: {
Authorization: `Bearer ${await getSessionIdFromFile()}`,
Authorization: `Bearer ${sessionToken}`,
'Content-Type': 'application/json',
},
},
Expand All @@ -80,18 +77,40 @@ async function getWorkspaceId(): Promise<string> {
}
);

const { data, success } = (await response.json()) as Result<{ id: string }[]>;
const { data, success } = (await response.json()) as Result<{ id: string; name: string }[]>;
if (!success) {
throw new Error(`Failed to fetch user's workspace.`);
}
return data[0].id;
return data;
}

function unwrapWorkspaceId(workspaceId: string | Error): string {
if (typeof workspaceId !== 'string') {
console.error(workspaceId.message);
/**
* Get the workspace ID to link to.
* Prompts the user to choose if they have more than one workspace in Astro Studio.
* @returns A `Promise` for the workspace ID to use.
*/
async function promptWorkspace(sessionToken: string) {
const workspaces = await getWorkspaces(sessionToken);
if (workspaces.length === 0) {
console.error('No workspaces found.');
process.exit(1);
}

if (workspaces.length === 1) {
return workspaces[0].id;
}

const { workspaceId } = await prompts({
type: 'autocomplete',
name: 'workspaceId',
message: 'Select your workspace:',
limit: 5,
choices: workspaces.map((w) => ({ title: w.name, value: w.id })),
});
if (typeof workspaceId !== 'string') {
console.log('Canceled.');
process.exit(0);
}
return workspaceId;
}

Expand Down Expand Up @@ -164,7 +183,9 @@ export async function promptExistingProjectName({ workspaceId }: { workspaceId:
}
);

const { data, success } = (await response.json()) as Result<{ id: string; idName: string }[]>;
const { data, success } = (await response.json()) as Result<
{ id: string; name: string; idName: string }[]
>;
if (!success) {
console.error(`Failed to fetch projects.`);
process.exit(1);
Expand All @@ -174,7 +195,7 @@ export async function promptExistingProjectName({ workspaceId }: { workspaceId:
name: 'projectId',
message: 'What is your project name?',
limit: 5,
choices: data.map((p: any) => ({ title: p.name, value: p.id })),
choices: data.map((p) => ({ title: p.name, value: p.id })),
});
if (typeof projectId !== 'string') {
console.log('Canceled.');
Expand All @@ -201,6 +222,10 @@ export async function promptBegin(): Promise<void> {
}
}

/**
* Ask the user if they want to link to an existing Astro Studio project.
* @returns A `Promise` for the user’s answer: `true` if they answer yes, otherwise `false`.
*/
export async function promptLinkExisting(): Promise<boolean> {
// prompt
const { linkExisting } = await prompts({
Expand All @@ -212,6 +237,11 @@ export async function promptLinkExisting(): Promise<boolean> {
return !!linkExisting;
}

/**
* Ask the user if they want to link to a new Astro Studio Project.
* **Exits the process if they answer no.**
* @returns A `Promise` for the user’s answer: `true` if they answer yes.
*/
export async function promptLinkNew(): Promise<boolean> {
// prompt
const { linkNew } = await prompts({
Expand Down

0 comments on commit b78e83f

Please sign in to comment.