diff --git a/src/client.test.ts b/src/client.test.ts index e8295f2..4f80e1d 100644 --- a/src/client.test.ts +++ b/src/client.test.ts @@ -10,4 +10,39 @@ describe("client", () => { }; await expect(Client.create(clientConfiguration)).rejects.toThrow(); }); + + test("connects using space id", async () => { + const clientConfiguration: ClientConfiguration = { + apiKey: process.env["OCTOPUS_API_KEY"] || "", + apiUri: process.env["OCTOPUS_HOST"] || "", + space: "Spaces-1", + autoConnect: true + }; + + const client = await Client.create(clientConfiguration); + expect(client.isConnected()).toBe(true); + }); + + test("connects using space name", async () => { + const clientConfiguration: ClientConfiguration = { + apiKey: process.env["OCTOPUS_API_KEY"] || "", + apiUri: process.env["OCTOPUS_HOST"] || "", + space: "Default", + autoConnect: true + }; + + const client = await Client.create(clientConfiguration); + expect(client.isConnected()).toBe(true); + }); + + test("throws with invalid space", async () => { + const clientConfiguration: ClientConfiguration = { + apiKey: process.env["OCTOPUS_API_KEY"] || "", + apiUri: process.env["OCTOPUS_HOST"] || "", + space: "NonExistent", + autoConnect: true + }; + + await expect(Client.create(clientConfiguration)).rejects.toThrow(); + }) }); diff --git a/src/client.ts b/src/client.ts index 0cb0a78..3a4d9c0 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1,4 +1,12 @@ -import type { GlobalRootLinks, OctopusError, RootResource, SpaceRootLinks, SpaceRootResource } from "@octopusdeploy/message-contracts"; +import type { + GlobalRootLinks, + PagingCollection, + OctopusError, + RootResource, + SpaceRootLinks, + SpaceResource, + SpaceRootResource, +} from "@octopusdeploy/message-contracts"; import ApiClient from "./apiClient"; import { ClientConfiguration, processConfiguration } from "./clientConfiguration"; import type { ClientErrorResponseDetails } from "./clientErrorResponseDetails"; @@ -39,7 +47,7 @@ export class Client { if (error instanceof Error) client.error("Could not connect", error); throw error; } - if (configuration.space !== null && configuration.space !== undefined) { + if (configuration.space !== undefined && configuration.space !== "") { try { await client.switchToSpace(configuration.space); } catch (error: unknown) { @@ -170,15 +178,27 @@ export class Client { return new Client(this.session, this.resolver, this.rootDocument, null, null, this.configuration); } - async switchToSpace(spaceId: string): Promise { + async switchToSpace(spaceIdOrName: string): Promise { if (this.rootDocument === null) { throw new Error( "Root document is null; this document is required for the API client. Please ensure that the API endpoint is accessible along with its root document." ); } - this.spaceId = spaceId; - this.spaceRootDocument = await this.get(this.rootDocument.Links["SpaceHome"], { spaceId: this.spaceId }); + const spaceList = await this.get>(this.rootDocument.Links["Spaces"]); + const uppercaseSpaceIdOrName = spaceIdOrName.toUpperCase(); + var spaceResources = spaceList.Items.filter( + (s: SpaceResource) => s.Name.toUpperCase() === uppercaseSpaceIdOrName || s.Id.toUpperCase() === uppercaseSpaceIdOrName + ); + + if (spaceResources.length == 1) { + const spaceResource = spaceResources[0]; + this.spaceId = spaceResource.Id; + this.spaceRootDocument = await this.get(spaceResource.Links["SpaceHome"]); + return; + } + + throw new Error(`Unable to uniquely identify a space using '${spaceIdOrName}'.`); } switchToSystem(): void { diff --git a/src/repository.ts b/src/repository.ts index 1a337e0..3c5d004 100644 --- a/src/repository.ts +++ b/src/repository.ts @@ -339,8 +339,8 @@ export class Repository implements OctopusSpaceRepository, OctopusSystemReposito return new Repository(this.client.forSystem()); } - switchToSpace(spaceId: string): Promise { - return this.client.switchToSpace(spaceId); + switchToSpace(spaceIdOrName: string): Promise { + return this.client.switchToSpace(spaceIdOrName); } switchToSystem(): void {