@sequenceholdings/studio-cli 0.1.13 → 0.1.21
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 +258 -38
- package/dist/agents/apply-chunks.d.ts +13 -0
- package/dist/agents/apply-chunks.js +43 -0
- package/dist/agents/commands.d.ts +10 -0
- package/dist/agents/commands.js +218 -0
- package/dist/agents/scaffold.d.ts +2 -0
- package/dist/agents/scaffold.js +77 -0
- package/dist/agents/source.d.ts +18 -0
- package/dist/agents/source.js +121 -0
- package/dist/artifact/delegate.d.ts +2 -2
- package/dist/artifact/delegate.js +31 -73
- package/dist/atlas-client.js +52 -37
- package/dist/auth-cmds/commands.d.ts +1 -1
- package/dist/auth-cmds/commands.js +12 -7
- package/dist/auth.d.ts +104 -24
- package/dist/auth.js +456 -94
- package/dist/config.d.ts +3 -3
- package/dist/config.js +18 -13
- package/dist/env-catalog.js +13 -3
- package/dist/env-flags.d.ts +2 -0
- package/dist/env-flags.js +2 -0
- package/dist/env-registry.d.ts +27 -0
- package/dist/env-registry.js +204 -0
- package/dist/envs/commands.d.ts +1 -1
- package/dist/envs/commands.js +41 -3
- package/dist/file-lock.d.ts +5 -0
- package/dist/file-lock.js +187 -0
- package/dist/functions/commands.d.ts +10 -10
- package/dist/functions/commands.js +87 -53
- package/dist/functions/manifest.d.ts +1 -0
- package/dist/functions/manifest.js +36 -0
- package/dist/functions/source-selection.d.ts +24 -0
- package/dist/functions/source-selection.js +67 -0
- package/dist/login.d.ts +8 -3
- package/dist/login.js +46 -34
- package/dist/main.d.ts +3 -1
- package/dist/main.js +41 -12
- package/dist/orm/delegate.js +25 -7
- package/dist/pat-hints.js +2 -2
- package/dist/pipeline/commands.d.ts +58 -0
- package/dist/pipeline/commands.js +330 -0
- package/dist/pipeline/lifecycle.d.ts +58 -0
- package/dist/pipeline/lifecycle.js +348 -0
- package/dist/pipeline/pinning.d.ts +5 -0
- package/dist/pipeline/pinning.js +9 -0
- package/dist/pipeline/templates.d.ts +11 -0
- package/dist/pipeline/templates.js +166 -0
- package/dist/process/build.d.ts +4 -0
- package/dist/process/build.js +33 -2
- package/dist/process/codegen.js +19 -1
- package/dist/process/commands.js +97 -47
- package/dist/process/compiler-subprocess.d.ts +29 -0
- package/dist/process/compiler-subprocess.js +99 -0
- package/dist/process/compiler-worker.d.ts +1 -0
- package/dist/process/compiler-worker.js +38 -0
- package/dist/process/lint.d.ts +8 -0
- package/dist/process/lint.js +84 -29
- package/dist/process/repo-install.js +18 -2
- package/dist/repos/commands.d.ts +1 -1
- package/dist/repos/commands.js +17 -12
- package/dist/secrets/commands.d.ts +1 -1
- package/dist/secrets/commands.js +18 -18
- package/package.json +12 -5
package/dist/atlas-client.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* consistent across both Sequence CLIs. Token + baseUrl are passed in by
|
|
5
5
|
* the caller — this file knows nothing about token files or config TOMLs.
|
|
6
6
|
*/
|
|
7
|
+
import { authenticatedRequestUrl } from '@sequenceholdings/artifact-studio/deployment-validation';
|
|
7
8
|
import { PREVIEW_DOMAIN } from './preview.js';
|
|
8
9
|
const MAX_503_RETRIES = 5;
|
|
9
10
|
const DEFAULT_RETRY_AFTER_SECONDS = 2;
|
|
@@ -34,6 +35,18 @@ async function fetchWith503Retry(input, init) {
|
|
|
34
35
|
await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
|
|
35
36
|
}
|
|
36
37
|
}
|
|
38
|
+
async function authenticatedFetch({ baseUrl, init = {}, path, token, }) {
|
|
39
|
+
const url = authenticatedRequestUrl({ baseUrl, path });
|
|
40
|
+
return fetchWith503Retry(url, {
|
|
41
|
+
...init,
|
|
42
|
+
redirect: 'manual',
|
|
43
|
+
headers: {
|
|
44
|
+
...previewAccessHeaders(baseUrl),
|
|
45
|
+
...init.headers,
|
|
46
|
+
Authorization: `Bearer ${token}`,
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
37
50
|
function previewAccessHeaders(baseUrl) {
|
|
38
51
|
const secret = process.env.PREVIEW_ACCESS_HEADER?.trim();
|
|
39
52
|
if (!secret)
|
|
@@ -89,17 +102,13 @@ async function responseError(response, path) {
|
|
|
89
102
|
return new AtlasApiError(response.status, message, path, response.statusText, body);
|
|
90
103
|
}
|
|
91
104
|
export async function getJson({ baseUrl, token, path, }) {
|
|
92
|
-
const response = await
|
|
93
|
-
headers: { ...previewAccessHeaders(baseUrl), Authorization: `Bearer ${token}` },
|
|
94
|
-
});
|
|
105
|
+
const response = await authenticatedFetch({ baseUrl, token, path });
|
|
95
106
|
if (!response.ok)
|
|
96
107
|
throw await responseError(response, path);
|
|
97
108
|
return response.json();
|
|
98
109
|
}
|
|
99
110
|
export async function getJsonOr404({ baseUrl, token, path, }) {
|
|
100
|
-
const response = await
|
|
101
|
-
headers: { ...previewAccessHeaders(baseUrl), Authorization: `Bearer ${token}` },
|
|
102
|
-
});
|
|
111
|
+
const response = await authenticatedFetch({ baseUrl, token, path });
|
|
103
112
|
if (response.status === 404)
|
|
104
113
|
return null;
|
|
105
114
|
if (!response.ok)
|
|
@@ -107,56 +116,60 @@ export async function getJsonOr404({ baseUrl, token, path, }) {
|
|
|
107
116
|
return response.json();
|
|
108
117
|
}
|
|
109
118
|
export async function postJson({ baseUrl, token, path, body, }) {
|
|
110
|
-
const response = await
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
119
|
+
const response = await authenticatedFetch({
|
|
120
|
+
baseUrl,
|
|
121
|
+
token,
|
|
122
|
+
path,
|
|
123
|
+
init: {
|
|
124
|
+
method: 'POST',
|
|
125
|
+
headers: { 'Content-Type': 'application/json' },
|
|
126
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
116
127
|
},
|
|
117
|
-
body: body === undefined ? undefined : JSON.stringify(body),
|
|
118
128
|
});
|
|
119
129
|
if (!response.ok)
|
|
120
130
|
throw await responseError(response, path);
|
|
121
131
|
return response.json();
|
|
122
132
|
}
|
|
123
133
|
export async function putJson({ baseUrl, token, path, body, }) {
|
|
124
|
-
const response = await
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
134
|
+
const response = await authenticatedFetch({
|
|
135
|
+
baseUrl,
|
|
136
|
+
token,
|
|
137
|
+
path,
|
|
138
|
+
init: {
|
|
139
|
+
method: 'PUT',
|
|
140
|
+
headers: { 'Content-Type': 'application/json' },
|
|
141
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
130
142
|
},
|
|
131
|
-
body: body === undefined ? undefined : JSON.stringify(body),
|
|
132
143
|
});
|
|
133
144
|
if (!response.ok)
|
|
134
145
|
throw await responseError(response, path);
|
|
135
146
|
return response.json();
|
|
136
147
|
}
|
|
137
148
|
export async function patchJson({ baseUrl, token, path, body, }) {
|
|
138
|
-
const response = await
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
149
|
+
const response = await authenticatedFetch({
|
|
150
|
+
baseUrl,
|
|
151
|
+
token,
|
|
152
|
+
path,
|
|
153
|
+
init: {
|
|
154
|
+
method: 'PATCH',
|
|
155
|
+
headers: { 'Content-Type': 'application/json' },
|
|
156
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
144
157
|
},
|
|
145
|
-
body: body === undefined ? undefined : JSON.stringify(body),
|
|
146
158
|
});
|
|
147
159
|
if (!response.ok)
|
|
148
160
|
throw await responseError(response, path);
|
|
149
161
|
return response.json();
|
|
150
162
|
}
|
|
151
163
|
export async function deleteJson({ baseUrl, token, path, body, }) {
|
|
152
|
-
const response = await
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
164
|
+
const response = await authenticatedFetch({
|
|
165
|
+
baseUrl,
|
|
166
|
+
token,
|
|
167
|
+
path,
|
|
168
|
+
init: {
|
|
169
|
+
method: 'DELETE',
|
|
170
|
+
headers: { 'Content-Type': 'application/json' },
|
|
171
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
158
172
|
},
|
|
159
|
-
body: body === undefined ? undefined : JSON.stringify(body),
|
|
160
173
|
});
|
|
161
174
|
if (!response.ok)
|
|
162
175
|
throw await responseError(response, path);
|
|
@@ -164,9 +177,11 @@ export async function deleteJson({ baseUrl, token, path, body, }) {
|
|
|
164
177
|
}
|
|
165
178
|
/** DELETE for endpoints that return 204 with an empty body (deleteJson would choke on it). */
|
|
166
179
|
export async function deleteNoContent({ baseUrl, token, path, }) {
|
|
167
|
-
const response = await
|
|
168
|
-
|
|
169
|
-
|
|
180
|
+
const response = await authenticatedFetch({
|
|
181
|
+
baseUrl,
|
|
182
|
+
token,
|
|
183
|
+
path,
|
|
184
|
+
init: { method: 'DELETE' },
|
|
170
185
|
});
|
|
171
186
|
if (!response.ok)
|
|
172
187
|
throw await responseError(response, path);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ParsedArgs } from '../process/commands.js';
|
|
2
2
|
declare const PAT_SCOPES: readonly ["repo:read", "repo:write", "repo:admin"];
|
|
3
3
|
type PatScope = (typeof PAT_SCOPES)[number];
|
|
4
|
-
export declare const AUTH_USAGE = "usage:\n seq-studio auth pat create --name <n> [--scopes repo:read,repo:write]
|
|
4
|
+
export declare const AUTH_USAGE = "usage:\n seq-studio auth pat create --name <n> -e <env> [--scopes repo:read,repo:write]\n [--expires 7d|30d|90d|1y|never] [--store-credentials]\n seq-studio auth pat list -e <env>\n seq-studio auth pat revoke <id> -e <env> [--yes]\n\n Issue a personal access token for git clone / git push against the platform\n git service.\n\n Authenticate with `seq-studio login`, then run `auth pat create -e <env>`.\n Alternatively, open Atlas \u2192 Settings \u2192 Tokens:\n https://<atlas-host>/settings/tokens\n Sign in, create a token (repo:read / repo:write), copy once, then:\n export ATLAS_GIT_PAT=<token>\n\n On create the raw token is printed ONCE \u2014 store it; Atlas cannot re-show it.\n Git Basic auth: any username (e.g. git), PAT as the password.\n\n Flags: -e/--env <env> (required; see: seq-studio envs list)\n";
|
|
5
5
|
export declare function parsePatScopes(raw: string | undefined): PatScope[];
|
|
6
6
|
/**
|
|
7
7
|
* Map UI-style duration choices to an absolute ISO-8601 expiresAt, or undefined
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import { deleteNoContent, getJson, postJson } from '../atlas-client.js';
|
|
12
12
|
import { printCliError } from '../cli-errors.js';
|
|
13
|
+
import { REQUIRE_EXPLICIT_ENV_MESSAGE } from '../env-flags.js';
|
|
13
14
|
import { buildContext, clientOptions, flagBool, LOG, } from '../functions/commands.js';
|
|
14
15
|
import { readConfig } from '../config.js';
|
|
15
16
|
import { confirmYes } from '../prompt.js';
|
|
@@ -38,15 +39,15 @@ function stringFlag(flags, key) {
|
|
|
38
39
|
return value;
|
|
39
40
|
}
|
|
40
41
|
export const AUTH_USAGE = `usage:
|
|
41
|
-
seq-studio auth pat create --name <n> [--scopes repo:read,repo:write]
|
|
42
|
+
seq-studio auth pat create --name <n> -e <env> [--scopes repo:read,repo:write]
|
|
42
43
|
[--expires 7d|30d|90d|1y|never] [--store-credentials]
|
|
43
|
-
seq-studio auth pat list
|
|
44
|
-
seq-studio auth pat revoke <id>
|
|
44
|
+
seq-studio auth pat list -e <env>
|
|
45
|
+
seq-studio auth pat revoke <id> -e <env> [--yes]
|
|
45
46
|
|
|
46
47
|
Issue a personal access token for git clone / git push against the platform
|
|
47
48
|
git service.
|
|
48
49
|
|
|
49
|
-
Authenticate with \`seq-studio login\`, then run \`auth pat create
|
|
50
|
+
Authenticate with \`seq-studio login\`, then run \`auth pat create -e <env>\`.
|
|
50
51
|
Alternatively, open Atlas → Settings → Tokens:
|
|
51
52
|
https://<atlas-host>/settings/tokens
|
|
52
53
|
Sign in, create a token (repo:read / repo:write), copy once, then:
|
|
@@ -55,7 +56,7 @@ export const AUTH_USAGE = `usage:
|
|
|
55
56
|
On create the raw token is printed ONCE — store it; Atlas cannot re-show it.
|
|
56
57
|
Git Basic auth: any username (e.g. git), PAT as the password.
|
|
57
58
|
|
|
58
|
-
Flags: -e/--env <env>
|
|
59
|
+
Flags: -e/--env <env> (required; see: seq-studio envs list)
|
|
59
60
|
`;
|
|
60
61
|
async function authContext(args) {
|
|
61
62
|
if (args.flags.env === true || args.flags.e === true) {
|
|
@@ -66,6 +67,10 @@ async function authContext(args) {
|
|
|
66
67
|
}
|
|
67
68
|
catch (err) {
|
|
68
69
|
const message = err instanceof Error ? err.message : String(err);
|
|
70
|
+
// Missing `-e` is actionable on its own — don't bury it under login/PAT
|
|
71
|
+
// setup advice (that wrap is for real auth/token failures).
|
|
72
|
+
if (message === REQUIRE_EXPLICIT_ENV_MESSAGE)
|
|
73
|
+
throw err;
|
|
69
74
|
// buildContext failed before we know the env URL; offer CLI login and
|
|
70
75
|
// render the tokens-page URLs from the environments visible to this
|
|
71
76
|
// identity (third-party / OpCo developers only see their own hosts).
|
|
@@ -119,7 +124,7 @@ export function resolveExpiresAt(choice) {
|
|
|
119
124
|
export async function authPatCreateCommand(args) {
|
|
120
125
|
const name = stringFlag(args.flags, 'name');
|
|
121
126
|
if (!name) {
|
|
122
|
-
console.error('usage: seq-studio auth pat create --name <n> [--scopes ...]
|
|
127
|
+
console.error('usage: seq-studio auth pat create --name <n> -e <env> [--scopes ...]');
|
|
123
128
|
return 1;
|
|
124
129
|
}
|
|
125
130
|
if (name.length < 3) {
|
|
@@ -193,7 +198,7 @@ export async function authPatListCommand(args) {
|
|
|
193
198
|
export async function authPatRevokeCommand(args) {
|
|
194
199
|
const id = args.positional[0];
|
|
195
200
|
if (!id) {
|
|
196
|
-
console.error('usage: seq-studio auth pat revoke <id>
|
|
201
|
+
console.error('usage: seq-studio auth pat revoke <id> -e <env> [--yes]');
|
|
197
202
|
return 1;
|
|
198
203
|
}
|
|
199
204
|
const ctx = await authContext(args);
|
package/dist/auth.d.ts
CHANGED
|
@@ -5,27 +5,66 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Two token sources, in the SAME precedence order as seqapi's
|
|
7
7
|
* `get_access_token` (`shared/seqapi/seqapi/auth.py`):
|
|
8
|
-
* 1.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* 1. Cached user access token — read from the seqapi token file. When it
|
|
9
|
+
* expires, an interactive session performs a bounded PKCE login again.
|
|
10
|
+
* 2. M2M service account — Auth0 client-credentials grant when the realm's
|
|
11
|
+
* `AUTH0_M2M_CLIENT_SECRET` (or suffixed OpCo variant) is set. Used when
|
|
12
|
+
* no valid user session exists, or when `SEQAPI_AUTH_MODE=m2m` forces it.
|
|
11
13
|
* (M2M carries app scopes but NO user identity / workspace membership
|
|
12
14
|
* — see the `atlas-test-access` rule.)
|
|
13
|
-
* 2. Cached user token — read from the seqapi token file and refreshed
|
|
14
|
-
* via the Auth0 refresh-token grant when near expiry.
|
|
15
15
|
*
|
|
16
|
-
* Login
|
|
17
|
-
* `seqapi._save_tokens` exactly:
|
|
16
|
+
* Login writes the shared file. This mirrors `seqapi._save_tokens` exactly:
|
|
18
17
|
* same fields, same shape, same 0o600 permissions, atomic write via
|
|
19
|
-
* tmpfile + rename.
|
|
18
|
+
* tmpfile + rename. M2M tokens are cached in-process and also under the
|
|
19
|
+
* token file's `m2m` key so short-lived CLI processes reuse a grant.
|
|
20
20
|
*/
|
|
21
21
|
export declare const AUTH0_DOMAIN = "dev-n1t8ts403fp8oyxp.us.auth0.com";
|
|
22
22
|
export declare const AUTH0_CLIENT_ID = "GD9riCDWocfc66odpWBjwBiX43qqAX8r";
|
|
23
23
|
export declare const AUTH0_AUDIENCE = "https://api.studio.com";
|
|
24
|
+
/** The realm name the built-in Sequence environments' tokens live under —
|
|
25
|
+
* also the implicit realm of the legacy flat fields in tokens.json. */
|
|
26
|
+
export declare const SEQUENCE_REALM = "sequence";
|
|
27
|
+
export declare function isSequenceAuthEnvName(envName: string): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* One Auth0 login context. Mirrors seqapi's `AuthRealm`
|
|
30
|
+
* (`shared/seqapi/seqapi/config.py`): the Sequence realm is hard-coded;
|
|
31
|
+
* OpCo-environment realms are read from seqapi's config.json registry,
|
|
32
|
+
* written by `seq-studio envs add` or `seqapi env add` — both CLIs share one
|
|
33
|
+
* registry and one token file, so either can log in and the other picks the
|
|
34
|
+
* session up.
|
|
35
|
+
*/
|
|
36
|
+
export interface AuthRealm {
|
|
37
|
+
name: string;
|
|
38
|
+
domain: string;
|
|
39
|
+
clientId: string;
|
|
40
|
+
audience: string;
|
|
41
|
+
organization?: string;
|
|
42
|
+
m2mClientId?: string;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* A discovery response is not a trust anchor for the host that receives an
|
|
46
|
+
* M2M client secret. Even another valid *.auth0.com tenant is untrusted;
|
|
47
|
+
* additional Auth0 tenants/custom domains require an explicit code-reviewed
|
|
48
|
+
* allowlist entry.
|
|
49
|
+
*/
|
|
50
|
+
export declare function validateAuth0Domain(domain: string): string;
|
|
51
|
+
export declare const SEQUENCE_AUTH_REALM: AuthRealm;
|
|
24
52
|
export interface SeqapiTokens {
|
|
25
|
-
refresh_token?: string;
|
|
26
53
|
access_token?: string;
|
|
27
54
|
expires_at?: number;
|
|
28
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Resolve the auth realm for an environment name. Undefined, built-ins, and
|
|
58
|
+
* per-PR preview targets map to the shared Sequence realm. Preview URLs are
|
|
59
|
+
* constrained to Sequence's preview domain by the environment resolver. Every
|
|
60
|
+
* other explicit name must have a valid seqapi registry entry; otherwise fail
|
|
61
|
+
* closed so a shared Sequence bearer token can never be sent to a tenant URL.
|
|
62
|
+
*/
|
|
63
|
+
export declare function realmForEnv(envName?: string): Promise<AuthRealm>;
|
|
64
|
+
/** Env var(s) carrying a realm's M2M client secret — the Sequence realm keeps
|
|
65
|
+
* the legacy bare name; OpCo realms use a suffixed name so one shell can hold
|
|
66
|
+
* several credentials unambiguously. Mirrors seqapi's `_m2m_secret_env_names`. */
|
|
67
|
+
export declare function m2mSecretEnvName(realm: AuthRealm): string;
|
|
29
68
|
/**
|
|
30
69
|
* A configured M2M credential failed to mint a token. Typed so callers that
|
|
31
70
|
* normally swallow discovery errors (lazy catalog refresh) can still surface
|
|
@@ -38,38 +77,79 @@ export declare function seqapiTokenDir(): string;
|
|
|
38
77
|
export declare function seqapiTokenPath(): string;
|
|
39
78
|
export declare class NotLoggedInError extends Error {
|
|
40
79
|
readonly name = "NotLoggedInError";
|
|
41
|
-
constructor();
|
|
80
|
+
constructor(realmName?: string, reason?: string);
|
|
42
81
|
}
|
|
43
82
|
/**
|
|
44
|
-
* Return a valid access token
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
83
|
+
* Return a valid access token for an environment's auth realm.
|
|
84
|
+
*
|
|
85
|
+
* Precedence (default `SEQAPI_AUTH_MODE=auto`), matching seqapi:
|
|
86
|
+
* 1. Valid cached user access token
|
|
87
|
+
* 2. M2M client-credentials when the realm's secret env var is set
|
|
88
|
+
* 3. Bounded PKCE login when browser auto-login is enabled
|
|
89
|
+
*
|
|
90
|
+
* Set `SEQAPI_AUTH_MODE=m2m` to skip the user token. No `env` (or a built-in
|
|
91
|
+
* Sequence env) means the shared Sequence realm.
|
|
49
92
|
*/
|
|
50
|
-
export declare
|
|
93
|
+
export declare class UnsafeAuthTargetError extends Error {
|
|
94
|
+
}
|
|
95
|
+
export type AuthMode = 'm2m' | 'user';
|
|
96
|
+
export interface ResolvedAccessToken {
|
|
97
|
+
authMode: AuthMode;
|
|
98
|
+
token: string;
|
|
99
|
+
}
|
|
100
|
+
export declare function getAccessTokenWithMode(options?: {
|
|
101
|
+
/** Disable browser PKCE fallback for probe-only and other non-interactive callers. */
|
|
102
|
+
allowInteractiveLogin?: boolean;
|
|
103
|
+
env?: string;
|
|
104
|
+
targetUrl?: string;
|
|
105
|
+
}): Promise<ResolvedAccessToken>;
|
|
106
|
+
export declare function getAccessToken(options?: {
|
|
107
|
+
/** Disable browser PKCE fallback for probe-only and other non-interactive callers. */
|
|
108
|
+
allowInteractiveLogin?: boolean;
|
|
109
|
+
env?: string;
|
|
110
|
+
targetUrl?: string;
|
|
111
|
+
}): Promise<string>;
|
|
51
112
|
/**
|
|
52
113
|
* Try to load a token without throwing. Returns `null` for any error
|
|
53
114
|
* condition (missing file, parse error, no token fields). Used by
|
|
54
115
|
* `doctor` for non-fatal "are you logged in?" checks.
|
|
55
116
|
*/
|
|
56
|
-
export declare function
|
|
117
|
+
export declare function tryGetAccessTokenWithMode(options?: {
|
|
57
118
|
/**
|
|
58
119
|
* When the M2M secret is configured, failing to mint an M2M token should fail
|
|
59
120
|
* closed (avoid silently falling back to some other cached identity).
|
|
60
121
|
*/
|
|
61
122
|
failClosedForM2m?: boolean;
|
|
123
|
+
/** Environment name — selects the auth realm (default: Sequence). */
|
|
124
|
+
env?: string;
|
|
125
|
+
/** Resolved request origin — checked against the realm before returning credentials. */
|
|
126
|
+
targetUrl?: string;
|
|
127
|
+
}): Promise<ResolvedAccessToken | null>;
|
|
128
|
+
export declare function tryGetAccessToken(options?: {
|
|
129
|
+
failClosedForM2m?: boolean;
|
|
130
|
+
env?: string;
|
|
131
|
+
targetUrl?: string;
|
|
62
132
|
}): Promise<string | null>;
|
|
63
133
|
/**
|
|
64
|
-
*
|
|
65
|
-
* server
|
|
66
|
-
*
|
|
134
|
+
* Refuse to persist a token minted for another audience or Auth0
|
|
135
|
+
* organization. Auth0/server-side JWT verification remains authoritative;
|
|
136
|
+
* this local decode is only a cross-realm confusion check on a token received
|
|
137
|
+
* directly from the configured Auth0 tenant over TLS.
|
|
67
138
|
*/
|
|
139
|
+
export declare function verifyTokenMatchesRealm({ accessToken, realm, requireOrganization, }: {
|
|
140
|
+
accessToken: string;
|
|
141
|
+
realm: AuthRealm;
|
|
142
|
+
requireOrganization?: boolean;
|
|
143
|
+
}): void;
|
|
68
144
|
export declare function decodeJwtSub(token: string): string | null;
|
|
69
145
|
/**
|
|
70
146
|
* The Auth0 subject the CLI would authenticate as right now, without any
|
|
71
|
-
* network call
|
|
72
|
-
*
|
|
147
|
+
* network call. Matches token resolution precedence: a valid user session
|
|
148
|
+
* wins over an ambient M2M secret unless `SEQAPI_AUTH_MODE=m2m`.
|
|
73
149
|
*/
|
|
74
|
-
export declare function currentIdentitySubject(
|
|
75
|
-
|
|
150
|
+
export declare function currentIdentitySubject(options?: {
|
|
151
|
+
env?: string;
|
|
152
|
+
}): Promise<string | null>;
|
|
153
|
+
export declare function loadCachedUserTokens(realmName?: string): Promise<SeqapiTokens | null>;
|
|
154
|
+
export declare function saveTokens(tokens: SeqapiTokens, realmName?: string): Promise<void>;
|
|
155
|
+
export declare function deleteRealmTokens(realmName: string): Promise<void>;
|