@seamapi/cli 0.19.0 → 0.21.0
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 +4 -4
- package/bin/cli.js +2 -2
- package/bin/cli.js.map +1 -1
- package/lib/auth/operations.d.ts +10 -21
- package/lib/auth/operations.js +30 -38
- package/lib/auth/operations.js.map +1 -1
- package/lib/auth/validate-token.js +1 -1
- package/lib/auth/validate-token.js.map +1 -1
- package/lib/blueprint/index.d.ts +1 -1
- package/lib/blueprint/index.js +2 -2
- package/lib/blueprint/index.js.map +1 -1
- package/lib/blueprint/source-remote.d.ts +2 -2
- package/lib/blueprint/source-remote.js +3 -3
- package/lib/blueprint/source-remote.js.map +1 -1
- package/lib/commands/local/login.js +3 -3
- package/lib/commands/local/login.js.map +1 -1
- package/lib/commands/local/{select-server.d.ts → select-endpoint.d.ts} +1 -1
- package/lib/commands/local/select-endpoint.js +27 -0
- package/lib/commands/local/select-endpoint.js.map +1 -0
- package/lib/commands/registry.js +2 -4
- package/lib/commands/registry.js.map +1 -1
- package/lib/context.d.ts +5 -5
- package/lib/context.js +9 -7
- package/lib/context.js.map +1 -1
- package/lib/env.d.ts +2 -2
- package/lib/env.js +2 -2
- package/lib/env.js.map +1 -1
- package/lib/http/client.js +2 -2
- package/lib/http/client.js.map +1 -1
- package/lib/interactions/endpoint-selection.d.ts +1 -0
- package/lib/interactions/endpoint-selection.js +21 -0
- package/lib/interactions/endpoint-selection.js.map +1 -0
- package/lib/interactions/index.d.ts +1 -1
- package/lib/interactions/index.js +1 -1
- package/lib/interactions/index.js.map +1 -1
- package/lib/interactions/login.js +2 -2
- package/lib/interactions/login.js.map +1 -1
- package/lib/interactions/workspace-id.js +1 -1
- package/lib/interactions/workspace-id.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/package.json +1 -1
- package/src/bin/cli.ts +2 -2
- package/src/lib/auth/operations.ts +34 -51
- package/src/lib/auth/validate-token.ts +1 -1
- package/src/lib/blueprint/index.ts +3 -3
- package/src/lib/blueprint/source-remote.ts +3 -3
- package/src/lib/commands/local/login.ts +3 -3
- package/src/lib/commands/local/select-endpoint.ts +30 -0
- package/src/lib/commands/registry.ts +2 -4
- package/src/lib/context.ts +17 -13
- package/src/lib/env.ts +2 -2
- package/src/lib/http/client.ts +2 -2
- package/src/lib/interactions/endpoint-selection.ts +24 -0
- package/src/lib/interactions/index.ts +1 -1
- package/src/lib/interactions/login.ts +2 -2
- package/src/lib/interactions/workspace-id.ts +1 -1
- package/src/lib/version.ts +1 -1
- package/lib/commands/local/config-set-fake-server.d.ts +0 -3
- package/lib/commands/local/config-set-fake-server.js +0 -20
- package/lib/commands/local/config-set-fake-server.js.map +0 -1
- package/lib/commands/local/select-server.js +0 -27
- package/lib/commands/local/select-server.js.map +0 -1
- package/lib/interactions/server-selection.d.ts +0 -1
- package/lib/interactions/server-selection.js +0 -36
- package/lib/interactions/server-selection.js.map +0 -1
- package/src/lib/commands/local/config-set-fake-server.ts +0 -21
- package/src/lib/commands/local/select-server.ts +0 -30
- package/src/lib/interactions/server-selection.ts +0 -45
package/lib/http/client.js
CHANGED
|
@@ -3,7 +3,7 @@ import { resolveAuth } from '../context.js';
|
|
|
3
3
|
import { tokenEnvVar, workspaceIdEnvVar } from '../env.js';
|
|
4
4
|
export const getSeam = async (auth = resolveAuth()) => {
|
|
5
5
|
const token = getRequiredToken(auth);
|
|
6
|
-
const options = { endpoint: auth.
|
|
6
|
+
const options = { endpoint: auth.endpoint };
|
|
7
7
|
if (isPersonalAccessToken(token)) {
|
|
8
8
|
return SeamHttp.fromPersonalAccessToken(token, getRequiredWorkspaceId(auth), options);
|
|
9
9
|
}
|
|
@@ -14,7 +14,7 @@ export const getSeam = async (auth = resolveAuth()) => {
|
|
|
14
14
|
};
|
|
15
15
|
export const getSeamMultiWorkspace = async (auth = resolveAuth()) => {
|
|
16
16
|
const token = getRequiredToken(auth);
|
|
17
|
-
const options = { endpoint: auth.
|
|
17
|
+
const options = { endpoint: auth.endpoint };
|
|
18
18
|
if (isPersonalAccessToken(token)) {
|
|
19
19
|
return SeamHttpWithoutWorkspace.fromPersonalAccessToken(token, options);
|
|
20
20
|
}
|
package/lib/http/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/lib/http/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,QAAQ,EACR,wBAAwB,GACzB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAoB,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAE3D,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,EAC1B,OAAoB,WAAW,EAAE,EACd,EAAE;IACrB,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;IAEpC,MAAM,OAAO,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/lib/http/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,QAAQ,EACR,wBAAwB,GACzB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAoB,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAA;AAE3D,MAAM,CAAC,MAAM,OAAO,GAAG,KAAK,EAC1B,OAAoB,WAAW,EAAE,EACd,EAAE;IACrB,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;IAEpC,MAAM,OAAO,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAA;IAE3C,IAAI,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,QAAQ,CAAC,uBAAuB,CACrC,KAAK,EACL,sBAAsB,CAAC,IAAI,CAAC,EAC5B,OAAO,CACR,CAAA;IACH,CAAC;IAED,IAAI,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,QAAQ,CAAC,uBAAuB,CACrC,KAAK,EACL,sBAAsB,CAAC,IAAI,CAAC,EAC5B,OAAO,CACR,CAAA;IACH,CAAC;IAED,OAAO,QAAQ,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;AAC5C,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EACxC,OAAoB,WAAW,EAAE,EACa,EAAE;IAChD,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAA;IACpC,MAAM,OAAO,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAA;IAE3C,IAAI,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,wBAAwB,CAAC,uBAAuB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IACzE,CAAC;IAED,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;AAC5B,CAAC,CAAA;AAED,MAAM,gBAAgB,GAAG,CAAC,IAAiB,EAAU,EAAE;IACrD,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAA;IAEtB,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,8CAA8C,WAAW,uBAAuB,CACjF,CAAA;IACH,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED,MAAM,sBAAsB,GAAG,CAAC,IAAiB,EAAU,EAAE;IAC3D,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAA;IAE5B,IAAI,WAAW,IAAI,IAAI,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,iEAAiE,iBAAiB,uBAAuB,CAC1G,CAAA;IACH,CAAC;IAED,OAAO,WAAW,CAAA;AACpB,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function interactForEndpointSelection(): Promise<void>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { assertMutable, selectEndpoint } from '../auth/operations.js';
|
|
2
|
+
import { getConfigStore } from '../config/index.js';
|
|
3
|
+
import { resolveAuth } from '../context.js';
|
|
4
|
+
import { getOutput } from '../output/get-output.js';
|
|
5
|
+
import { promptAutocomplete } from '../prompt.js';
|
|
6
|
+
export async function interactForEndpointSelection() {
|
|
7
|
+
const config = getConfigStore();
|
|
8
|
+
assertMutable(resolveAuth(config), 'endpoint', 'select an endpoint');
|
|
9
|
+
const endpoints = ['http://localhost:3020', 'https://connect.getseam.com'];
|
|
10
|
+
// Searchable, as selecting a device or a command is.
|
|
11
|
+
const endpoint = await promptAutocomplete({
|
|
12
|
+
message: 'Select an endpoint:',
|
|
13
|
+
choices: endpoints.map((endpoint) => ({
|
|
14
|
+
label: endpoint,
|
|
15
|
+
value: endpoint,
|
|
16
|
+
})),
|
|
17
|
+
});
|
|
18
|
+
selectEndpoint(endpoint, config);
|
|
19
|
+
getOutput().info(`Endpoint set to ${endpoint}`);
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=endpoint-selection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"endpoint-selection.js","sourceRoot":"","sources":["../../src/lib/interactions/endpoint-selection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,MAAM,CAAC,KAAK,UAAU,4BAA4B;IAChD,MAAM,MAAM,GAAG,cAAc,EAAE,CAAA;IAC/B,aAAa,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,oBAAoB,CAAC,CAAA;IAEpE,MAAM,SAAS,GAAG,CAAC,uBAAuB,EAAE,6BAA6B,CAAC,CAAA;IAE1E,qDAAqD;IACrD,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC;QACxC,OAAO,EAAE,qBAAqB;QAC9B,OAAO,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACpC,KAAK,EAAE,QAAQ;YACf,KAAK,EAAE,QAAQ;SAChB,CAAC,CAAC;KACJ,CAAC,CAAA;IAEF,cAAc,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IAChC,SAAS,EAAE,CAAC,IAAI,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAA;AACjD,CAAC"}
|
|
@@ -10,9 +10,9 @@ export * from './command-selection.js';
|
|
|
10
10
|
export * from './connected-account.js';
|
|
11
11
|
export * from './custom-metadata.js';
|
|
12
12
|
export * from './device.js';
|
|
13
|
+
export * from './endpoint-selection.js';
|
|
13
14
|
export * from './login.js';
|
|
14
15
|
export * from './resource.js';
|
|
15
|
-
export * from './server-selection.js';
|
|
16
16
|
export * from './timestamp.js';
|
|
17
17
|
export * from './use-remote-api-defs.js';
|
|
18
18
|
export * from './user-identity.js';
|
|
@@ -10,9 +10,9 @@ export * from './command-selection.js';
|
|
|
10
10
|
export * from './connected-account.js';
|
|
11
11
|
export * from './custom-metadata.js';
|
|
12
12
|
export * from './device.js';
|
|
13
|
+
export * from './endpoint-selection.js';
|
|
13
14
|
export * from './login.js';
|
|
14
15
|
export * from './resource.js';
|
|
15
|
-
export * from './server-selection.js';
|
|
16
16
|
export * from './timestamp.js';
|
|
17
17
|
export * from './use-remote-api-defs.js';
|
|
18
18
|
export * from './user-identity.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lib/interactions/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,0BAA0B,CAAA;AACxC,cAAc,YAAY,CAAA;AAC1B,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AACtC,cAAc,sBAAsB,CAAA;AACpC,cAAc,aAAa,CAAA;AAC3B,cAAc,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/lib/interactions/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,eAAe,CAAA;AAC7B,cAAc,0BAA0B,CAAA;AACxC,cAAc,YAAY,CAAA;AAC1B,cAAc,uBAAuB,CAAA;AACrC,cAAc,qBAAqB,CAAA;AACnC,cAAc,wBAAwB,CAAA;AACtC,cAAc,wBAAwB,CAAA;AACtC,cAAc,sBAAsB,CAAA;AACpC,cAAc,aAAa,CAAA;AAC3B,cAAc,yBAAyB,CAAA;AACvC,cAAc,YAAY,CAAA;AAC1B,cAAc,eAAe,CAAA;AAC7B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,0BAA0B,CAAA;AACxC,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA"}
|
|
@@ -14,8 +14,8 @@ export const interactForLogin = async () => {
|
|
|
14
14
|
const auth = resolveAuth(config);
|
|
15
15
|
// Refuse before prompting: nothing typed here could be stored.
|
|
16
16
|
assertMutable(auth, 'token', 'log in');
|
|
17
|
-
if (auth.
|
|
18
|
-
output.info(`You're using a local Seam Connect instance, you can enter the API Key to your local user, you can create a new user from:\n\n${auth.
|
|
17
|
+
if (auth.endpoint.includes('localhost')) {
|
|
18
|
+
output.info(`You're using a local Seam Connect instance, you can enter the API Key to your local user, you can create a new user from:\n\n${auth.endpoint}/admin/create_user_with_api_key`);
|
|
19
19
|
}
|
|
20
20
|
else {
|
|
21
21
|
output.info(`To login, navigate to the URL below and create a new Personal Access Token (PAT) and paste the PAT in the provided box:\n\nhttps://console.seam.co/settings/access-tokens\n\n`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/lib/interactions/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AACvE,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAE1D,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,IAAI,EAAE;IACzC,MAAM,MAAM,GAAG,cAAc,EAAE,CAAA;IAC/B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAA;IAEhC,+DAA+D;IAC/D,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAA;IAEtC,IAAI,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/lib/interactions/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;AACvE,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAClE,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE1C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AAE1D,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,IAAI,EAAE;IACzC,MAAM,MAAM,GAAG,cAAc,EAAE,CAAA;IAC/B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC,CAAA;IAEhC,+DAA+D;IAC/D,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAA;IAEtC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QACxC,MAAM,CAAC,IAAI,CACT,gIAAgI,IAAI,CAAC,QAAQ,iCAAiC,CAC/K,CAAA;IACH,CAAC;SAAM,CAAC;QACN,MAAM,CAAC,IAAI,CACT,+KAA+K,CAChL,CAAA;IACH,CAAC;IAED,MAAM,CAAC,IAAI,CACT,KAAK,CAAC,IAAI,CACR,mEAAmE,CACpE,CACF,CAAA;IAED,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC;QAC3B,OAAO,EAAE,wBAAwB;KAClC,CAAC,CAAA;IACF,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAA;IAExB,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAA;IACtC,CAAC;IAED,IAAI,qBAAqB,CAAC,KAAK,CAAC,EAAE,CAAC;QACjC,MAAM,sBAAsB,CAAC,KAAK,CAAC,CAAA;IACrC,CAAC;SAAM,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,WAAW,CAAC,uBAAuB,EAAE,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAA;IACxE,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CACb,4DAA4D,CAC7D,CAAA;IACH,CAAC;IAED,UAAU,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IACzB,MAAM,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAA;AAC1D,CAAC,CAAA"}
|
|
@@ -11,7 +11,7 @@ export const interactForWorkspaceId = async (personalAccessToken) => {
|
|
|
11
11
|
assertMutable(resolveAuth(config), 'workspaceId', 'select a workspace');
|
|
12
12
|
const seam = personalAccessToken
|
|
13
13
|
? SeamHttpWithoutWorkspace.fromPersonalAccessToken(personalAccessToken, {
|
|
14
|
-
endpoint: resolveAuth(config).
|
|
14
|
+
endpoint: resolveAuth(config).endpoint,
|
|
15
15
|
})
|
|
16
16
|
: await getSeamMultiWorkspace();
|
|
17
17
|
const workspaces = await withLoading('Fetching workspaces...', () => seam.workspaces.list());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-id.js","sourceRoot":"","sources":["../../src/lib/interactions/workspace-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AAEhE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,EAAE,mBAA4B,EAAE,EAAE;IAC3E,MAAM,MAAM,GAAG,cAAc,EAAE,CAAA;IAE/B,kEAAkE;IAClE,aAAa,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,oBAAoB,CAAC,CAAA;IAEvE,MAAM,IAAI,GAAG,mBAAmB;QAC9B,CAAC,CAAC,wBAAwB,CAAC,uBAAuB,CAAC,mBAAmB,EAAE;YACpE,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"workspace-id.js","sourceRoot":"","sources":["../../src/lib/interactions/workspace-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAA;AAEhE,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAC5C,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AAElD,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,EAAE,mBAA4B,EAAE,EAAE;IAC3E,MAAM,MAAM,GAAG,cAAc,EAAE,CAAA;IAE/B,kEAAkE;IAClE,aAAa,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,aAAa,EAAE,oBAAoB,CAAC,CAAA;IAEvE,MAAM,IAAI,GAAG,mBAAmB;QAC9B,CAAC,CAAC,wBAAwB,CAAC,uBAAuB,CAAC,mBAAmB,EAAE;YACpE,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,QAAQ;SACvC,CAAC;QACJ,CAAC,CAAC,MAAM,qBAAqB,EAAE,CAAA;IAEjC,MAAM,UAAU,GAAG,MAAM,WAAW,CAAC,wBAAwB,EAAE,GAAG,EAAE,CAClE,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CACvB,CAAA;IACD,yEAAyE;IACzE,wCAAwC;IACxC,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAAS;QACnD,OAAO,EAAE,qBAAqB;QAC9B,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,SAAc,EAAE,EAAE,CAAC,CAAC;YAC3C,KAAK,EAAE,SAAS,CAAC,IAAI;YACrB,KAAK,EAAE,SAAS,CAAC,YAAY;YAC7B,IAAI,EAAE,SAAS,CAAC,YAAY;SAC7B,CAAC,CAAC;KACJ,CAAC,CAAA;IAEF,eAAe,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IACpC,OAAO,WAAW,CAAA;AACpB,CAAC,CAAA"}
|
package/lib/version.d.ts
CHANGED
package/lib/version.js
CHANGED
package/package.json
CHANGED
package/src/bin/cli.ts
CHANGED
|
@@ -122,12 +122,12 @@ async function cli(args: ParsedArgs, argv: string[]) {
|
|
|
122
122
|
const localCommand = findLocalCommand(args._)
|
|
123
123
|
|
|
124
124
|
// Commands declared not to need a token bypass the login gate. A partial
|
|
125
|
-
// path keeps the historical rule: only login and select
|
|
125
|
+
// path keeps the historical rule: only login and select endpoint may be
|
|
126
126
|
// reached logged out.
|
|
127
127
|
const requiresAuth =
|
|
128
128
|
localCommand != null
|
|
129
129
|
? localCommand.requiresAuth
|
|
130
|
-
: !(args._[0] === 'login' || isEqual(args._, ['select', '
|
|
130
|
+
: !(args._[0] === 'login' || isEqual(args._, ['select', 'endpoint']))
|
|
131
131
|
|
|
132
132
|
if (requiresAuth && resolveAuth(config).token == null) {
|
|
133
133
|
output.error(`Not logged in. Please run "seam login" or set ${tokenEnvVar}`)
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { randomBytes } from 'node:crypto'
|
|
2
|
-
|
|
3
1
|
import { type ConfigStore, getConfigStore } from 'lib/config/index.js'
|
|
4
2
|
import { type AuthContext, resolveAuth } from 'lib/context.js'
|
|
5
3
|
import {
|
|
@@ -12,7 +10,7 @@ import {
|
|
|
12
10
|
import { validateToken } from './validate-token.js'
|
|
13
11
|
|
|
14
12
|
/** A stored auth setting an environment variable may override. */
|
|
15
|
-
export type AuthSetting = '
|
|
13
|
+
export type AuthSetting = 'endpoint' | 'token' | 'workspaceId'
|
|
16
14
|
|
|
17
15
|
/**
|
|
18
16
|
* Refuse to store a setting the environment overrides.
|
|
@@ -29,10 +27,10 @@ export const assertMutable = (
|
|
|
29
27
|
action: string,
|
|
30
28
|
): void => {
|
|
31
29
|
const { envVar, source, value } = {
|
|
32
|
-
|
|
30
|
+
endpoint: {
|
|
33
31
|
envVar: endpointEnvVar,
|
|
34
|
-
source: auth.
|
|
35
|
-
value: auth.
|
|
32
|
+
source: auth.endpointSource,
|
|
33
|
+
value: auth.endpoint,
|
|
36
34
|
},
|
|
37
35
|
token: { envVar: tokenEnvVar, source: auth.tokenSource, value: auth.token },
|
|
38
36
|
workspaceId: {
|
|
@@ -47,7 +45,7 @@ export const assertMutable = (
|
|
|
47
45
|
}
|
|
48
46
|
|
|
49
47
|
export interface LoginOptions {
|
|
50
|
-
|
|
48
|
+
endpoint?: string | undefined
|
|
51
49
|
token?: string | undefined
|
|
52
50
|
workspaceId?: string | undefined
|
|
53
51
|
}
|
|
@@ -55,13 +53,13 @@ export interface LoginOptions {
|
|
|
55
53
|
/**
|
|
56
54
|
* Store the given credentials, validating the token first.
|
|
57
55
|
*
|
|
58
|
-
* The token is stored under the
|
|
59
|
-
*
|
|
56
|
+
* The token is stored under the endpoint it will be used with, so a given
|
|
57
|
+
* endpoint is stored and re-resolved before the token key is derived.
|
|
60
58
|
*
|
|
61
59
|
* Validation reaches the network, so a test may inject its own `validate`.
|
|
62
60
|
*/
|
|
63
61
|
export const login = async (
|
|
64
|
-
{
|
|
62
|
+
{ endpoint, token, workspaceId }: LoginOptions,
|
|
65
63
|
config: ConfigStore = getConfigStore(),
|
|
66
64
|
validate: typeof validateToken = validateToken,
|
|
67
65
|
): Promise<void> => {
|
|
@@ -70,20 +68,19 @@ export const login = async (
|
|
|
70
68
|
// Nothing is stored while the environment overrides it, so refuse before
|
|
71
69
|
// storing anything rather than part way through.
|
|
72
70
|
assertMutable(auth, 'token', 'log in')
|
|
73
|
-
if (
|
|
71
|
+
if (endpoint != null) assertMutable(auth, 'endpoint', 'select an endpoint')
|
|
74
72
|
if (workspaceId != null) {
|
|
75
73
|
assertMutable(auth, 'workspaceId', 'select a workspace')
|
|
76
74
|
}
|
|
77
75
|
|
|
78
|
-
if (
|
|
79
|
-
|
|
80
|
-
config.delete('current_workspace_id')
|
|
76
|
+
if (endpoint != null) {
|
|
77
|
+
storeEndpoint(endpoint, config)
|
|
81
78
|
auth = resolveAuth(config)
|
|
82
79
|
}
|
|
83
80
|
|
|
84
81
|
if (token != null) {
|
|
85
82
|
await validate(token, workspaceId)
|
|
86
|
-
config.set(`${auth.
|
|
83
|
+
config.set(`${auth.endpoint}.pat`, token)
|
|
87
84
|
config.delete('current_workspace_id')
|
|
88
85
|
}
|
|
89
86
|
|
|
@@ -92,39 +89,38 @@ export const login = async (
|
|
|
92
89
|
}
|
|
93
90
|
}
|
|
94
91
|
|
|
95
|
-
/** Store the token for the current
|
|
92
|
+
/** Store the token for the current endpoint, e.g., one just prompted for. */
|
|
96
93
|
export const storeToken = (
|
|
97
94
|
token: string,
|
|
98
95
|
config: ConfigStore = getConfigStore(),
|
|
99
96
|
): void => {
|
|
100
97
|
const auth = resolveAuth(config)
|
|
101
98
|
assertMutable(auth, 'token', 'log in')
|
|
102
|
-
config.set(`${auth.
|
|
99
|
+
config.set(`${auth.endpoint}.pat`, token)
|
|
103
100
|
}
|
|
104
101
|
|
|
105
102
|
/** Remove the stored token and workspace selection. */
|
|
106
103
|
export const logout = (config: ConfigStore = getConfigStore()): void => {
|
|
107
104
|
const auth = resolveAuth(config)
|
|
108
105
|
assertMutable(auth, 'token', 'log out')
|
|
109
|
-
config.delete(`${auth.
|
|
110
|
-
// Configs written before tokens were stored per
|
|
106
|
+
config.delete(`${auth.endpoint}.pat`)
|
|
107
|
+
// Configs written before tokens were stored per endpoint may still hold an
|
|
111
108
|
// un-namespaced token, so drop that too.
|
|
112
109
|
config.delete('pat')
|
|
113
110
|
config.delete('current_workspace_id')
|
|
114
111
|
}
|
|
115
112
|
|
|
116
113
|
/**
|
|
117
|
-
* Store the
|
|
114
|
+
* Store the endpoint to make requests against.
|
|
118
115
|
*
|
|
119
|
-
* The workspace selection belongs to the previous
|
|
116
|
+
* The workspace selection belongs to the previous endpoint, so it is cleared.
|
|
120
117
|
*/
|
|
121
|
-
export const
|
|
122
|
-
|
|
118
|
+
export const selectEndpoint = (
|
|
119
|
+
endpoint: string,
|
|
123
120
|
config: ConfigStore = getConfigStore(),
|
|
124
121
|
): void => {
|
|
125
|
-
assertMutable(resolveAuth(config), '
|
|
126
|
-
|
|
127
|
-
config.delete('current_workspace_id')
|
|
122
|
+
assertMutable(resolveAuth(config), 'endpoint', 'select an endpoint')
|
|
123
|
+
storeEndpoint(endpoint, config)
|
|
128
124
|
}
|
|
129
125
|
|
|
130
126
|
/** Store the workspace requests are made against. */
|
|
@@ -136,34 +132,21 @@ export const selectWorkspace = (
|
|
|
136
132
|
config.set('current_workspace_id', workspaceId)
|
|
137
133
|
}
|
|
138
134
|
|
|
139
|
-
/**
|
|
140
|
-
* Point the CLI at a fake Seam Connect server and store the well-known
|
|
141
|
-
* token it accepts. Returns the generated server URL for reporting.
|
|
142
|
-
*/
|
|
143
|
-
export const selectFakeServer = ({
|
|
144
|
-
urlSeed = randomBytes(5).toString('hex'),
|
|
145
|
-
config = getConfigStore(),
|
|
146
|
-
}: {
|
|
147
|
-
urlSeed?: string
|
|
148
|
-
config?: ConfigStore
|
|
149
|
-
} = {}): { server: string; token: string } => {
|
|
150
|
-
const auth = resolveAuth(config)
|
|
151
|
-
assertMutable(auth, 'server', 'select a server')
|
|
152
|
-
assertMutable(auth, 'token', 'log in')
|
|
153
|
-
|
|
154
|
-
const server = `https://${urlSeed}.fakeseamconnect.seam.vc`
|
|
155
|
-
const token = 'seam_apikey1_token'
|
|
156
|
-
config.set('server', server)
|
|
157
|
-
config.set(`${server}.pat`, token)
|
|
158
|
-
config.delete('current_workspace_id')
|
|
159
|
-
|
|
160
|
-
return { server, token }
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/** Store whether API definitions come from the server instead of npm. */
|
|
135
|
+
/** Store whether API definitions come from the endpoint instead of npm. */
|
|
164
136
|
export const setUseRemoteApiDefs = (
|
|
165
137
|
useRemoteApiDefs: boolean,
|
|
166
138
|
config: ConfigStore = getConfigStore(),
|
|
167
139
|
): void => {
|
|
168
140
|
config.set('use_remote_api_defs', useRemoteApiDefs)
|
|
169
141
|
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Write the endpoint, dropping what belonged to the previous one: the
|
|
145
|
+
* workspace selection, and any value left under the legacy `server` key that
|
|
146
|
+
* {@link resolveAuth} would otherwise still fall back to.
|
|
147
|
+
*/
|
|
148
|
+
const storeEndpoint = (endpoint: string, config: ConfigStore): void => {
|
|
149
|
+
config.set('endpoint', endpoint)
|
|
150
|
+
config.delete('server')
|
|
151
|
+
config.delete('current_workspace_id')
|
|
152
|
+
}
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
import { resolveAuth } from 'lib/context.js'
|
|
9
9
|
|
|
10
10
|
export const validateToken = async (token: string, workspaceId?: string) => {
|
|
11
|
-
const options = { endpoint: resolveAuth().
|
|
11
|
+
const options = { endpoint: resolveAuth().endpoint }
|
|
12
12
|
|
|
13
13
|
if (isPersonalAccessToken(token)) {
|
|
14
14
|
const seam = workspaceId
|
|
@@ -7,7 +7,7 @@ export type ApiBlueprint = Blueprint
|
|
|
7
7
|
|
|
8
8
|
export interface GetApiBlueprintOptions {
|
|
9
9
|
/**
|
|
10
|
-
* Build from the OpenAPI document the configured
|
|
10
|
+
* Build from the OpenAPI document the configured endpoint is currently
|
|
11
11
|
* running, instead of the published npm types.
|
|
12
12
|
*/
|
|
13
13
|
useRemoteDefinitions?: boolean
|
|
@@ -19,8 +19,8 @@ export const getApiBlueprint = async ({
|
|
|
19
19
|
useRemoteDefinitions = false,
|
|
20
20
|
update = false,
|
|
21
21
|
}: GetApiBlueprintOptions = {}): Promise<ApiBlueprint> => {
|
|
22
|
-
// Remote definitions describe whatever the
|
|
23
|
-
// build them directly from
|
|
22
|
+
// Remote definitions describe whatever the endpoint is currently running, so
|
|
23
|
+
// build them directly from that endpoint's OpenAPI document.
|
|
24
24
|
if (useRemoteDefinitions) return await createRemoteBlueprint()
|
|
25
25
|
|
|
26
26
|
return await getBlueprint({ update })
|
|
@@ -3,15 +3,15 @@ import type { Blueprint } from '@seamapi/blueprint'
|
|
|
3
3
|
import { resolveAuth } from 'lib/context.js'
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
* Build a blueprint from the OpenAPI document the current
|
|
7
|
-
* describing exactly what that
|
|
6
|
+
* Build a blueprint from the OpenAPI document the current endpoint is running,
|
|
7
|
+
* describing exactly what that endpoint accepts rather than what is published.
|
|
8
8
|
*/
|
|
9
9
|
export const createRemoteBlueprint = async (): Promise<Blueprint> => {
|
|
10
10
|
const [{ createBlueprint }, { getOpenapiSchema }] = await Promise.all([
|
|
11
11
|
import('@seamapi/blueprint'),
|
|
12
12
|
import('@seamapi/http/connect'),
|
|
13
13
|
])
|
|
14
|
-
const openapi = await getOpenapiSchema(resolveAuth().
|
|
14
|
+
const openapi = await getOpenapiSchema(resolveAuth().endpoint)
|
|
15
15
|
|
|
16
16
|
return await createBlueprint({ openapi }, { omitUndocumented: true })
|
|
17
17
|
}
|
|
@@ -12,17 +12,17 @@ export const loginCommand: Command = {
|
|
|
12
12
|
description:
|
|
13
13
|
'Prompts for a personal access token unless one is passed with --token.',
|
|
14
14
|
flags: [
|
|
15
|
-
stringFlag('
|
|
15
|
+
stringFlag('endpoint', 'Seam API endpoint to log in to.'),
|
|
16
16
|
stringFlag('token', 'Personal access token to log in with.'),
|
|
17
17
|
stringFlag('workspace-id', 'Workspace to select after logging in.'),
|
|
18
18
|
],
|
|
19
19
|
},
|
|
20
20
|
requiresAuth: false,
|
|
21
21
|
execute: async ({ args }, ctx) => {
|
|
22
|
-
if (args['token'] || args['workspace_id'] || args['
|
|
22
|
+
if (args['token'] || args['workspace_id'] || args['endpoint']) {
|
|
23
23
|
await login(
|
|
24
24
|
{
|
|
25
|
-
|
|
25
|
+
endpoint: args['endpoint'] ? args['endpoint'] : undefined,
|
|
26
26
|
token: args['token'] ? String(args['token']).trim() : undefined,
|
|
27
27
|
workspaceId: args['workspace_id'] ? args['workspace_id'] : undefined,
|
|
28
28
|
},
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { assertMutable, selectEndpoint } from 'lib/auth/operations.js'
|
|
2
|
+
import type { Command } from 'lib/commands/registry.js'
|
|
3
|
+
import { stringFlag } from 'lib/commands/spec.js'
|
|
4
|
+
import { NonInteractiveError } from 'lib/errors.js'
|
|
5
|
+
import { interactForEndpointSelection } from 'lib/interactions/index.js'
|
|
6
|
+
|
|
7
|
+
export const selectEndpointCommand: Command = {
|
|
8
|
+
definition: {
|
|
9
|
+
path: ['select', 'endpoint'],
|
|
10
|
+
kind: 'cli',
|
|
11
|
+
title: 'Select the Seam API endpoint.',
|
|
12
|
+
description: '',
|
|
13
|
+
flags: [stringFlag('endpoint', 'Seam API endpoint to select.')],
|
|
14
|
+
},
|
|
15
|
+
requiresAuth: false,
|
|
16
|
+
execute: async ({ args }, ctx) => {
|
|
17
|
+
assertMutable(ctx.auth, 'endpoint', 'select an endpoint')
|
|
18
|
+
if (args['endpoint']) {
|
|
19
|
+
selectEndpoint(args['endpoint'], ctx.config)
|
|
20
|
+
return { kind: 'done' }
|
|
21
|
+
}
|
|
22
|
+
if (ctx.interactivity === 'non-interactive') {
|
|
23
|
+
throw new NonInteractiveError(
|
|
24
|
+
'Missing required parameter for select endpoint: --endpoint',
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
await interactForEndpointSelection()
|
|
28
|
+
return { kind: 'done' }
|
|
29
|
+
},
|
|
30
|
+
}
|
|
@@ -7,12 +7,11 @@ import type { CliContext } from 'lib/context.js'
|
|
|
7
7
|
import { executeApiCommand } from './api-command.js'
|
|
8
8
|
import { createCompletionCommands } from './local/completion.js'
|
|
9
9
|
import { configRevealLocationCommand } from './local/config-reveal-location.js'
|
|
10
|
-
import { configSetFakeServerCommand } from './local/config-set-fake-server.js'
|
|
11
10
|
import { configUseRemoteApiDefsCommand } from './local/config-use-remote-api-defs.js'
|
|
12
11
|
import { healthCommand } from './local/health.js'
|
|
13
12
|
import { loginCommand } from './local/login.js'
|
|
14
13
|
import { logoutCommand } from './local/logout.js'
|
|
15
|
-
import {
|
|
14
|
+
import { selectEndpointCommand } from './local/select-endpoint.js'
|
|
16
15
|
import { selectWorkspaceCommand } from './local/select-workspace.js'
|
|
17
16
|
import { wizardCommand } from './local/wizard.js'
|
|
18
17
|
import {
|
|
@@ -72,12 +71,11 @@ const completionCommands = createCompletionCommands(
|
|
|
72
71
|
export const localCommands: Command[] = [
|
|
73
72
|
...completionCommands,
|
|
74
73
|
configRevealLocationCommand,
|
|
75
|
-
configSetFakeServerCommand,
|
|
76
74
|
configUseRemoteApiDefsCommand,
|
|
77
75
|
healthCommand,
|
|
78
76
|
loginCommand,
|
|
79
77
|
logoutCommand,
|
|
80
|
-
|
|
78
|
+
selectEndpointCommand,
|
|
81
79
|
selectWorkspaceCommand,
|
|
82
80
|
wizardCommand,
|
|
83
81
|
]
|
package/src/lib/context.ts
CHANGED
|
@@ -9,21 +9,21 @@ import {
|
|
|
9
9
|
import type { SeamApi } from './http/api.js'
|
|
10
10
|
import type { Output } from './output/output.js'
|
|
11
11
|
|
|
12
|
-
export const
|
|
12
|
+
export const defaultEndpoint = 'https://connect.getseam.com'
|
|
13
13
|
|
|
14
14
|
/** Where a resolved value came from, e.g., to refuse writes the env shadows. */
|
|
15
15
|
export type ValueSource = 'env' | 'config' | 'default'
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
* The
|
|
18
|
+
* The endpoint, token, and workspace requests are made with.
|
|
19
19
|
*
|
|
20
20
|
* Resolved in one place so the precedence rule exists once: an environment
|
|
21
|
-
* variable wins over the stored value, and the
|
|
21
|
+
* variable wins over the stored value, and the endpoint falls back to Seam.
|
|
22
22
|
* The source tags say where each value came from.
|
|
23
23
|
*/
|
|
24
24
|
export interface AuthContext {
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
endpoint: string
|
|
26
|
+
endpointSource: ValueSource
|
|
27
27
|
token: string | null
|
|
28
28
|
tokenSource: Exclude<ValueSource, 'default'> | null
|
|
29
29
|
workspaceId: string | null
|
|
@@ -33,21 +33,25 @@ export interface AuthContext {
|
|
|
33
33
|
export const resolveAuth = (
|
|
34
34
|
config: ConfigStore = getConfigStore(),
|
|
35
35
|
): AuthContext => {
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
const envEndpoint = getEndpointFromEnv()
|
|
37
|
+
// Configs written before the endpoint was called one still hold it under
|
|
38
|
+
// `server`, so fall back to that key rather than silently resetting them.
|
|
39
|
+
const storedEndpoint = config.get('endpoint') ?? config.get('server')
|
|
40
|
+
const endpoint =
|
|
41
|
+
envEndpoint ?? (typeof storedEndpoint === 'string' ? storedEndpoint : null)
|
|
40
42
|
|
|
41
43
|
const envToken = getTokenFromEnv()
|
|
42
|
-
const storedToken = readString(
|
|
44
|
+
const storedToken = readString(
|
|
45
|
+
config.get(`${endpoint ?? defaultEndpoint}.pat`),
|
|
46
|
+
)
|
|
43
47
|
|
|
44
48
|
const envWorkspaceId = getWorkspaceIdFromEnv()
|
|
45
49
|
const storedWorkspaceId = readString(config.get('current_workspace_id'))
|
|
46
50
|
|
|
47
51
|
return {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
52
|
+
endpoint: endpoint ?? defaultEndpoint,
|
|
53
|
+
endpointSource:
|
|
54
|
+
envEndpoint != null ? 'env' : endpoint != null ? 'config' : 'default',
|
|
51
55
|
token: envToken ?? storedToken,
|
|
52
56
|
tokenSource:
|
|
53
57
|
envToken != null ? 'env' : storedToken != null ? 'config' : null,
|
package/src/lib/env.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Credentials and the
|
|
2
|
+
* Credentials and the endpoint may be given in the environment.
|
|
3
3
|
*
|
|
4
4
|
* Each variable overrides the corresponding stored value for as long as it
|
|
5
5
|
* is set, so any of them may be used per command or per shell. Commands that
|
|
@@ -12,7 +12,7 @@ export const tokenEnvVar = 'SEAM_CLI_TOKEN'
|
|
|
12
12
|
/** Overrides the workspace stored by `seam select workspace`. */
|
|
13
13
|
export const workspaceIdEnvVar = 'SEAM_CLI_WORKSPACE_ID'
|
|
14
14
|
|
|
15
|
-
/** Overrides the
|
|
15
|
+
/** Overrides the endpoint stored by `seam select endpoint`. */
|
|
16
16
|
export const endpointEnvVar = 'SEAM_CLI_ENDPOINT'
|
|
17
17
|
|
|
18
18
|
/** Every variable read here is declared on `ProcessEnv` in `env.d.ts`. */
|
package/src/lib/http/client.ts
CHANGED
|
@@ -13,7 +13,7 @@ export const getSeam = async (
|
|
|
13
13
|
): Promise<SeamHttp> => {
|
|
14
14
|
const token = getRequiredToken(auth)
|
|
15
15
|
|
|
16
|
-
const options = { endpoint: auth.
|
|
16
|
+
const options = { endpoint: auth.endpoint }
|
|
17
17
|
|
|
18
18
|
if (isPersonalAccessToken(token)) {
|
|
19
19
|
return SeamHttp.fromPersonalAccessToken(
|
|
@@ -38,7 +38,7 @@ export const getSeamMultiWorkspace = async (
|
|
|
38
38
|
auth: AuthContext = resolveAuth(),
|
|
39
39
|
): Promise<SeamHttpWithoutWorkspace | SeamHttp> => {
|
|
40
40
|
const token = getRequiredToken(auth)
|
|
41
|
-
const options = { endpoint: auth.
|
|
41
|
+
const options = { endpoint: auth.endpoint }
|
|
42
42
|
|
|
43
43
|
if (isPersonalAccessToken(token)) {
|
|
44
44
|
return SeamHttpWithoutWorkspace.fromPersonalAccessToken(token, options)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { assertMutable, selectEndpoint } from 'lib/auth/operations.js'
|
|
2
|
+
import { getConfigStore } from 'lib/config/index.js'
|
|
3
|
+
import { resolveAuth } from 'lib/context.js'
|
|
4
|
+
import { getOutput } from 'lib/output/get-output.js'
|
|
5
|
+
import { promptAutocomplete } from 'lib/prompt.js'
|
|
6
|
+
|
|
7
|
+
export async function interactForEndpointSelection() {
|
|
8
|
+
const config = getConfigStore()
|
|
9
|
+
assertMutable(resolveAuth(config), 'endpoint', 'select an endpoint')
|
|
10
|
+
|
|
11
|
+
const endpoints = ['http://localhost:3020', 'https://connect.getseam.com']
|
|
12
|
+
|
|
13
|
+
// Searchable, as selecting a device or a command is.
|
|
14
|
+
const endpoint = await promptAutocomplete({
|
|
15
|
+
message: 'Select an endpoint:',
|
|
16
|
+
choices: endpoints.map((endpoint) => ({
|
|
17
|
+
label: endpoint,
|
|
18
|
+
value: endpoint,
|
|
19
|
+
})),
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
selectEndpoint(endpoint, config)
|
|
23
|
+
getOutput().info(`Endpoint set to ${endpoint}`)
|
|
24
|
+
}
|
|
@@ -10,9 +10,9 @@ export * from './command-selection.js'
|
|
|
10
10
|
export * from './connected-account.js'
|
|
11
11
|
export * from './custom-metadata.js'
|
|
12
12
|
export * from './device.js'
|
|
13
|
+
export * from './endpoint-selection.js'
|
|
13
14
|
export * from './login.js'
|
|
14
15
|
export * from './resource.js'
|
|
15
|
-
export * from './server-selection.js'
|
|
16
16
|
export * from './timestamp.js'
|
|
17
17
|
export * from './use-remote-api-defs.js'
|
|
18
18
|
export * from './user-identity.js'
|
|
@@ -19,9 +19,9 @@ export const interactForLogin = async () => {
|
|
|
19
19
|
// Refuse before prompting: nothing typed here could be stored.
|
|
20
20
|
assertMutable(auth, 'token', 'log in')
|
|
21
21
|
|
|
22
|
-
if (auth.
|
|
22
|
+
if (auth.endpoint.includes('localhost')) {
|
|
23
23
|
output.info(
|
|
24
|
-
`You're using a local Seam Connect instance, you can enter the API Key to your local user, you can create a new user from:\n\n${auth.
|
|
24
|
+
`You're using a local Seam Connect instance, you can enter the API Key to your local user, you can create a new user from:\n\n${auth.endpoint}/admin/create_user_with_api_key`,
|
|
25
25
|
)
|
|
26
26
|
} else {
|
|
27
27
|
output.info(
|
|
@@ -15,7 +15,7 @@ export const interactForWorkspaceId = async (personalAccessToken?: string) => {
|
|
|
15
15
|
|
|
16
16
|
const seam = personalAccessToken
|
|
17
17
|
? SeamHttpWithoutWorkspace.fromPersonalAccessToken(personalAccessToken, {
|
|
18
|
-
endpoint: resolveAuth(config).
|
|
18
|
+
endpoint: resolveAuth(config).endpoint,
|
|
19
19
|
})
|
|
20
20
|
: await getSeamMultiWorkspace()
|
|
21
21
|
|