@alter-ai/cli 0.9.1 → 0.9.2
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/dist/cli.js +251 -48
- package/npm-shrinkwrap.json +2 -2
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -33,7 +33,7 @@ import { join } from "path";
|
|
|
33
33
|
// package.json
|
|
34
34
|
var package_default = {
|
|
35
35
|
name: "@alter-ai/cli",
|
|
36
|
-
version: "0.9.
|
|
36
|
+
version: "0.9.2",
|
|
37
37
|
description: "Command-line interface for the Alter Vault dev portal \u2014 scripted dashboard automation.",
|
|
38
38
|
type: "module",
|
|
39
39
|
bin: {
|
|
@@ -80,7 +80,7 @@ var package_default = {
|
|
|
80
80
|
esbuild: "0.28.1"
|
|
81
81
|
},
|
|
82
82
|
devDependencies: {
|
|
83
|
-
"@alter-ai/alter-sdk": "workspace:0.
|
|
83
|
+
"@alter-ai/alter-sdk": "workspace:0.25.0",
|
|
84
84
|
"@alter-vault/shared-types": "workspace:0.0.1",
|
|
85
85
|
"@alter-vault/shared-utils": "workspace:0.0.1",
|
|
86
86
|
"@eslint/js": "9.39.4",
|
|
@@ -4743,7 +4743,14 @@ var AmbiguousGrantError = class extends BackendError {
|
|
|
4743
4743
|
// scoped to the caller's own accessible set. Retry with the chosen
|
|
4744
4744
|
// `grantId`.
|
|
4745
4745
|
candidates;
|
|
4746
|
-
|
|
4746
|
+
// True when more grants matched than the error body can carry. It bounds
|
|
4747
|
+
// EVERY disambiguator on this error — `candidates`, `accountIdentifiers`,
|
|
4748
|
+
// `appUserIds` and `grantIds` all come from the same capped set — so a
|
|
4749
|
+
// grant, account or user missing from any of them is not proof it does not
|
|
4750
|
+
// exist. Narrow the request or call `listGrants()` for the authoritative
|
|
4751
|
+
// set.
|
|
4752
|
+
candidatesTruncated;
|
|
4753
|
+
constructor(message, providerId, accountIdentifiers, accountWasProvided, appUserIds, details, grantIds, candidates, candidatesTruncated) {
|
|
4747
4754
|
super(message, details);
|
|
4748
4755
|
this.name = "AmbiguousGrantError";
|
|
4749
4756
|
this.providerId = providerId;
|
|
@@ -4752,6 +4759,7 @@ var AmbiguousGrantError = class extends BackendError {
|
|
|
4752
4759
|
this.appUserIds = appUserIds ?? [];
|
|
4753
4760
|
this.grantIds = grantIds ?? [];
|
|
4754
4761
|
this.candidates = candidates ?? [];
|
|
4762
|
+
this.candidatesTruncated = candidatesTruncated ?? false;
|
|
4755
4763
|
}
|
|
4756
4764
|
};
|
|
4757
4765
|
var NoDelegatedGrantError = class extends BackendError {
|
|
@@ -5724,6 +5732,14 @@ var ConnectSession = class {
|
|
|
5724
5732
|
* Python SDK's scope_constraint_warnings coercion (parity contract).
|
|
5725
5733
|
*/
|
|
5726
5734
|
scopeConstraintWarnings;
|
|
5735
|
+
/**
|
|
5736
|
+
* True when the session names exactly one provider: the hosted UI shows no
|
|
5737
|
+
* picker, confirmation screen or Alter-branded page, and the browser widget
|
|
5738
|
+
* can open the provider window straight from the application's click when
|
|
5739
|
+
* the value is passed through as `open({ direct })`. False on a malformed
|
|
5740
|
+
* wire value (informational, not load-bearing).
|
|
5741
|
+
*/
|
|
5742
|
+
direct;
|
|
5727
5743
|
constructor(data) {
|
|
5728
5744
|
_assertString(data.session_token, "session_token", "ConnectSession");
|
|
5729
5745
|
_assertString(data.connect_url, "connect_url", "ConnectSession");
|
|
@@ -5745,10 +5761,12 @@ var ConnectSession = class {
|
|
|
5745
5761
|
(w) => typeof w === "string"
|
|
5746
5762
|
) : []
|
|
5747
5763
|
);
|
|
5764
|
+
this.direct = data.direct === true;
|
|
5748
5765
|
Object.freeze(this);
|
|
5749
5766
|
}
|
|
5750
5767
|
toJSON() {
|
|
5751
5768
|
return {
|
|
5769
|
+
direct: this.direct,
|
|
5752
5770
|
session_token: this.sessionToken,
|
|
5753
5771
|
connect_url: this.connectUrl,
|
|
5754
5772
|
expires_in: this.expiresIn,
|
|
@@ -10180,7 +10198,7 @@ function _extractAdditionalCredentials(token) {
|
|
|
10180
10198
|
return _additionalCredsStore.get(token);
|
|
10181
10199
|
}
|
|
10182
10200
|
var _fetch;
|
|
10183
|
-
var SDK_VERSION = "0.
|
|
10201
|
+
var SDK_VERSION = "0.25.0";
|
|
10184
10202
|
var SDK_USER_AGENT = `alter-sdk-node/${SDK_VERSION}`;
|
|
10185
10203
|
function pyUnquote(s) {
|
|
10186
10204
|
if (!s.includes("%")) return s;
|
|
@@ -11682,7 +11700,11 @@ ${label}:${value}`;
|
|
|
11682
11700
|
appUserIds,
|
|
11683
11701
|
errorData,
|
|
11684
11702
|
grantIds,
|
|
11685
|
-
candidates
|
|
11703
|
+
candidates,
|
|
11704
|
+
// Absent on the wire means "complete" — only a real cap emits the
|
|
11705
|
+
// key, so a strict `=== true` keeps a stray falsy value from
|
|
11706
|
+
// reading as truncation.
|
|
11707
|
+
errorData.candidates_truncated === true
|
|
11686
11708
|
);
|
|
11687
11709
|
}
|
|
11688
11710
|
if (errorData.error === "sibling_label_conflict") {
|
|
@@ -16755,7 +16777,7 @@ var DEFAULT_BASE_URL = "https://backend.alterauth.com";
|
|
|
16755
16777
|
var PAT_API_PREFIX = "/api/v1/dev-portal";
|
|
16756
16778
|
var HTTP_ERROR_THRESHOLD = 400;
|
|
16757
16779
|
var DEFAULT_TIMEOUT_MS2 = 3e4;
|
|
16758
|
-
var CLI_VERSION = "0.9.
|
|
16780
|
+
var CLI_VERSION = "0.9.2";
|
|
16759
16781
|
var USER_AGENT = buildUserAgent();
|
|
16760
16782
|
function buildUserAgent() {
|
|
16761
16783
|
let osTag = "";
|
|
@@ -17740,6 +17762,13 @@ var AgentsNamespace2 = class {
|
|
|
17740
17762
|
return expectDict(body, "agents.undeprecate_key", 200);
|
|
17741
17763
|
}
|
|
17742
17764
|
};
|
|
17765
|
+
function isRedirectUriAliasSpec(value) {
|
|
17766
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
17767
|
+
return false;
|
|
17768
|
+
}
|
|
17769
|
+
const spec = value;
|
|
17770
|
+
return typeof spec.label === "string" && typeof spec.description === "string";
|
|
17771
|
+
}
|
|
17743
17772
|
function isSharedDevProviderEntry(value) {
|
|
17744
17773
|
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
17745
17774
|
return false;
|
|
@@ -17761,7 +17790,7 @@ function isProviderCatalogEntry(value) {
|
|
|
17761
17790
|
const v = value;
|
|
17762
17791
|
return typeof v.id === "string" && typeof v.name === "string" && typeof v.display_name === "string" && (v.category === null || typeof v.category === "string") && (v.supports_refresh === null || typeof v.supports_refresh === "boolean") && (v.supports_pkce === null || typeof v.supports_pkce === "boolean") && (v.available_environments === void 0 || Array.isArray(v.available_environments) && v.available_environments.every(
|
|
17763
17792
|
(environment) => environment === "production" || environment === "sandbox"
|
|
17764
|
-
)) && (v.scopes_configured_on_provider === void 0 || typeof v.scopes_configured_on_provider === "boolean") && v.available_scopes !== null && typeof v.available_scopes === "object" && !Array.isArray(v.available_scopes) && Object.values(v.available_scopes).every(
|
|
17793
|
+
)) && (v.scopes_configured_on_provider === void 0 || typeof v.scopes_configured_on_provider === "boolean") && (v.redirect_uri_alias === void 0 || v.redirect_uri_alias === null || isRedirectUriAliasSpec(v.redirect_uri_alias)) && v.available_scopes !== null && typeof v.available_scopes === "object" && !Array.isArray(v.available_scopes) && Object.values(v.available_scopes).every(
|
|
17765
17794
|
isProviderScopeCatalogEntry
|
|
17766
17795
|
) && (v.managed_credentials_available === void 0 || typeof v.managed_credentials_available === "boolean") && (v.managed_approved_scopes === void 0 || v.managed_approved_scopes === null || Array.isArray(v.managed_approved_scopes) && v.managed_approved_scopes.every(
|
|
17767
17796
|
(scope) => typeof scope === "string"
|
|
@@ -17856,7 +17885,8 @@ var ProvidersNamespace = class {
|
|
|
17856
17885
|
client_secret: options.client_secret,
|
|
17857
17886
|
environment: options.environment,
|
|
17858
17887
|
scopes: options.scopes,
|
|
17859
|
-
redirect_uris: options.redirect_uris
|
|
17888
|
+
redirect_uris: options.redirect_uris,
|
|
17889
|
+
redirect_uri_alias: options.redirect_uri_alias
|
|
17860
17890
|
});
|
|
17861
17891
|
const body = await this.#client._call(
|
|
17862
17892
|
"POST",
|
|
@@ -17893,6 +17923,7 @@ var ProvidersNamespace = class {
|
|
|
17893
17923
|
environment: options.environment,
|
|
17894
17924
|
scopes: options.scopes,
|
|
17895
17925
|
redirect_uris: options.redirect_uris,
|
|
17926
|
+
redirect_uri_alias: options.redirect_uri_alias,
|
|
17896
17927
|
status: options.status
|
|
17897
17928
|
});
|
|
17898
17929
|
const body = await this.#client._call(
|
|
@@ -20794,7 +20825,9 @@ function buildAgentsCommand() {
|
|
|
20794
20825
|
});
|
|
20795
20826
|
}
|
|
20796
20827
|
);
|
|
20797
|
-
agents.command("create").description(
|
|
20828
|
+
agents.command("create").description(
|
|
20829
|
+
"Create a managed agent (returns its first API key ONCE, in the api_key field)"
|
|
20830
|
+
).option(APP_FLAG, APP_TARGET_DESC).option(
|
|
20798
20831
|
"--name <name>",
|
|
20799
20832
|
"Agent name (stable identifier). Required unless --input is supplied."
|
|
20800
20833
|
).option("--display-name <name>", "Human-readable display name").option("--type <type>", "Type: agent|service (default: agent)", "agent").option(
|
|
@@ -21199,7 +21232,9 @@ function buildAgentsCommand() {
|
|
|
21199
21232
|
`);
|
|
21200
21233
|
});
|
|
21201
21234
|
});
|
|
21202
|
-
agents.command("mint-key").description(
|
|
21235
|
+
agents.command("mint-key").description(
|
|
21236
|
+
"Mint a fresh API key for the agent (plaintext returned ONCE, in the api_key field)"
|
|
21237
|
+
).option(APP_FLAG, APP_TARGET_DESC).requiredOption(
|
|
21203
21238
|
"--agent <agent-id>",
|
|
21204
21239
|
"Agent ID",
|
|
21205
21240
|
parseUuidArgument("--agent")
|
|
@@ -38281,7 +38316,25 @@ import { hostname as hostname3, platform as platform2 } from "os";
|
|
|
38281
38316
|
import { spawn } from "child_process";
|
|
38282
38317
|
var MIN_EPHEMERAL_PORT = 49152;
|
|
38283
38318
|
var MAX_EPHEMERAL_PORT = 65535;
|
|
38284
|
-
var LISTENER_TIMEOUT_MS =
|
|
38319
|
+
var LISTENER_TIMEOUT_MS = 6e5;
|
|
38320
|
+
function describeDeadline(ms) {
|
|
38321
|
+
if (ms >= 6e4 && ms % 6e4 === 0) {
|
|
38322
|
+
const minutes = ms / 6e4;
|
|
38323
|
+
return `${minutes} minute${minutes === 1 ? "" : "s"}`;
|
|
38324
|
+
}
|
|
38325
|
+
if (ms >= 1e3) {
|
|
38326
|
+
const seconds = Math.round(ms / 1e3);
|
|
38327
|
+
return `${seconds} second${seconds === 1 ? "" : "s"}`;
|
|
38328
|
+
}
|
|
38329
|
+
return `${ms} ms`;
|
|
38330
|
+
}
|
|
38331
|
+
var SELF_INSPECTION_SCOPE = "dashboard_pats:read";
|
|
38332
|
+
function withSelfInspectionScope(scopes) {
|
|
38333
|
+
if (scopes.includes(SELF_INSPECTION_SCOPE)) {
|
|
38334
|
+
return { scopes: [...scopes], added: false };
|
|
38335
|
+
}
|
|
38336
|
+
return { scopes: [...scopes, SELF_INSPECTION_SCOPE], added: true };
|
|
38337
|
+
}
|
|
38285
38338
|
var CALLBACK_STATE_PATTERN = /^[0-9a-f]{64}$/;
|
|
38286
38339
|
var DEFAULT_SCOPES = [
|
|
38287
38340
|
"dashboard_apps:read",
|
|
@@ -38359,7 +38412,9 @@ function pickEphemeralPort() {
|
|
|
38359
38412
|
}
|
|
38360
38413
|
async function runBrowserDance(options) {
|
|
38361
38414
|
const state = randomBytes2(32).toString("hex");
|
|
38362
|
-
const scopes
|
|
38415
|
+
const { scopes, added: addedSelfInspectionScope } = withSelfInspectionScope(
|
|
38416
|
+
options.scopes ?? DEFAULT_SCOPES
|
|
38417
|
+
);
|
|
38363
38418
|
const dashboardUrl = options.dashboardUrl ?? deriveDashboardUrl(options.baseUrl);
|
|
38364
38419
|
const openBrowser = options.openBrowser ?? defaultOpenBrowser;
|
|
38365
38420
|
const timeoutMs = options.timeoutMs ?? LISTENER_TIMEOUT_MS;
|
|
@@ -38414,7 +38469,7 @@ async function runBrowserDance(options) {
|
|
|
38414
38469
|
cleanupListener();
|
|
38415
38470
|
reject(
|
|
38416
38471
|
new Error(
|
|
38417
|
-
|
|
38472
|
+
`browser-dance timed out \u2014 operator did not complete the consent flow within ${describeDeadline(timeoutMs)}`
|
|
38418
38473
|
)
|
|
38419
38474
|
);
|
|
38420
38475
|
}, timeoutMs);
|
|
@@ -38572,9 +38627,15 @@ async function runBrowserDance(options) {
|
|
|
38572
38627
|
bindQuery = `&bind=cidr&cidr=${encodeURIComponent(options.cidrValue)}`;
|
|
38573
38628
|
}
|
|
38574
38629
|
const url2 = `${dashboardUrl}/cli-auth?port=${port}&state=${state}&scopes=${scopeQuery}&hostname=${encodeURIComponent(hostname3())}${bindQuery}`;
|
|
38630
|
+
if (addedSelfInspectionScope) {
|
|
38631
|
+
process.stderr.write(
|
|
38632
|
+
`alter: added ${SELF_INSPECTION_SCOPE} to the requested scopes \u2014 the CLI verifies the sign-in (and \`alter auth status\`) with it.
|
|
38633
|
+
`
|
|
38634
|
+
);
|
|
38635
|
+
}
|
|
38575
38636
|
process.stdout.write(
|
|
38576
38637
|
`alter: opening browser at ${dashboardUrl}/cli-auth
|
|
38577
|
-
(waiting up to
|
|
38638
|
+
(waiting up to ${describeDeadline(timeoutMs)} for you to approve)\u2026
|
|
38578
38639
|
`
|
|
38579
38640
|
);
|
|
38580
38641
|
openBrowser(url2);
|
|
@@ -39220,7 +39281,7 @@ function buildAuthCommand() {
|
|
|
39220
39281
|
"Override the dashboard URL used by the browser-dance flow. Defaults to the backend URL with the leftmost `backend.` subdomain swapped for `portal.`. Use this when the dashboard isn't at the regex-derivable host (e.g. staging / self-hosted setups). Must use https://."
|
|
39221
39282
|
).option(
|
|
39222
39283
|
"--scopes <list>",
|
|
39223
|
-
"Comma-separated scope list to request on the browser-dance consent page (e.g. 'dashboard_apps:read,dashboard_keys:write'). Defaults to the full read+write set across the CLI surface \u2014 enough for every non-destructive day-to-day command. Opt in to admin / delete tiers explicitly: 'dashboard_keys:admin' for runtime-key admin ops, 'dashboard_apps:admin' to archive/unarchive an app, and 'dashboard_apps:delete' for cascade-delete an app (note the Destructive-Action Policy keeps :delete as its own verb, separate from :admin \u2014 :admin does not grant the cascade). Each entry is validated client-side against the dashboard scope catalog \u2014 typos fail fast. Mutually exclusive with --token / --token-file / --token-stdin \u2014 pre-minted PATs have their scope set baked at mint time on the dashboard's Settings page; combining the flags is a usage error."
|
|
39284
|
+
"Comma-separated scope list to request on the browser-dance consent page (e.g. 'dashboard_apps:read,dashboard_keys:write'). Defaults to the full read+write set across the CLI surface \u2014 enough for every non-destructive day-to-day command. Opt in to admin / delete tiers explicitly: 'dashboard_keys:admin' for runtime-key admin ops, 'dashboard_apps:admin' to archive/unarchive an app, and 'dashboard_apps:delete' for cascade-delete an app (note the Destructive-Action Policy keeps :delete as its own verb, separate from :admin \u2014 :admin does not grant the cascade). The list REPLACES the default set, except that dashboard_pats:read is always added: the CLI verifies every sign-in (and `alter auth status`) with it, so a PAT without it cannot complete the login. Each entry is validated client-side against the dashboard scope catalog \u2014 typos fail fast. Mutually exclusive with --token / --token-file / --token-stdin \u2014 pre-minted PATs have their scope set baked at mint time on the dashboard's Settings page; combining the flags is a usage error."
|
|
39224
39285
|
).option(
|
|
39225
39286
|
"--no-bind-ip",
|
|
39226
39287
|
"Explicit opt-out of IP binding. This is now the DEFAULT for the browser-dance flow, so the flag is a no-op alias retained for scripts that pass it explicitly. The resulting PAT works from any source IP. Browser-dance flow only."
|
|
@@ -40965,7 +41026,9 @@ function buildKeysCommand() {
|
|
|
40965
41026
|
emit2(format, row);
|
|
40966
41027
|
});
|
|
40967
41028
|
});
|
|
40968
|
-
keys.command("mint").description(
|
|
41029
|
+
keys.command("mint").description(
|
|
41030
|
+
"Mint a new scoped key (plaintext returned ONCE, in the plain_key field \u2014 api_key is the key's metadata; capture it with --output json --fields plain_key or jq -r .plain_key)"
|
|
41031
|
+
).option(APP_FLAG, APP_TARGET_DESC).option(
|
|
40969
41032
|
"--name <name>",
|
|
40970
41033
|
"Display name. Required unless --input is supplied."
|
|
40971
41034
|
).option(
|
|
@@ -41027,7 +41090,7 @@ function buildKeysCommand() {
|
|
|
41027
41090
|
}
|
|
41028
41091
|
emit2(format, outcome2.result);
|
|
41029
41092
|
process.stderr.write(
|
|
41030
|
-
"alter: the
|
|
41093
|
+
"alter: the plain_key field above is the secret (api_key is metadata); it is shown ONCE and cannot be retrieved later.\n"
|
|
41031
41094
|
);
|
|
41032
41095
|
return;
|
|
41033
41096
|
}
|
|
@@ -41120,7 +41183,7 @@ function buildKeysCommand() {
|
|
|
41120
41183
|
}
|
|
41121
41184
|
emit2(format, outcome.result);
|
|
41122
41185
|
process.stderr.write(
|
|
41123
|
-
"alter: the
|
|
41186
|
+
"alter: the plain_key field above is the secret (api_key is metadata); it is shown ONCE and cannot be retrieved later.\n"
|
|
41124
41187
|
);
|
|
41125
41188
|
}
|
|
41126
41189
|
);
|
|
@@ -41137,7 +41200,7 @@ function buildKeysCommand() {
|
|
|
41137
41200
|
});
|
|
41138
41201
|
});
|
|
41139
41202
|
keys.command("rotate").description(
|
|
41140
|
-
"Rotate a key (new plaintext returned ONCE; old key enters grace until revoke). The app-key successor receives the organization's current finite default TTL. Requires dashboard_keys:write scope."
|
|
41203
|
+
"Rotate a key (new plaintext returned ONCE, in the new_plain_key field; old key enters grace until revoke). The app-key successor receives the organization's current finite default TTL. Requires dashboard_keys:write scope."
|
|
41141
41204
|
).option(APP_FLAG, APP_TARGET_DESC).requiredOption("--key <key-id>", "Key ID", parseUuidArgument("--key")).option(
|
|
41142
41205
|
"--scopes <list>",
|
|
41143
41206
|
"Optional new scope set (defaults to the key's current scopes)"
|
|
@@ -41162,7 +41225,7 @@ function buildKeysCommand() {
|
|
|
41162
41225
|
});
|
|
41163
41226
|
emit2(format, result);
|
|
41164
41227
|
process.stderr.write(
|
|
41165
|
-
"alter: the new
|
|
41228
|
+
"alter: the new_plain_key field above is the new secret (new_api_key is metadata); it is shown ONCE and cannot be retrieved later.\n"
|
|
41166
41229
|
);
|
|
41167
41230
|
});
|
|
41168
41231
|
}
|
|
@@ -41171,7 +41234,7 @@ function buildKeysCommand() {
|
|
|
41171
41234
|
"Revoke a key immediately (cascades to derived keys). Requires dashboard_keys:admin scope."
|
|
41172
41235
|
).option(APP_FLAG, APP_TARGET_DESC).requiredOption("--key <key-id>", "Key ID", parseUuidArgument("--key")).option(
|
|
41173
41236
|
"--force",
|
|
41174
|
-
"Override the last-active-key guard (revoking an agent
|
|
41237
|
+
"Override the last-active-key guard (revoking the last active key on an app or an agent leaves whatever authenticates with it broken until a fresh key is minted)"
|
|
41175
41238
|
).option("--yes", "Skip the interactive y/N prompt").action(
|
|
41176
41239
|
async (options) => {
|
|
41177
41240
|
const resolvedAppId = await resolveAppOrExit(options.app);
|
|
@@ -42099,10 +42162,20 @@ var SECRET_COLUMNS = [
|
|
|
42099
42162
|
{ label: "CREATED", get: (s) => s.created_at },
|
|
42100
42163
|
{ label: "UPDATED", get: (s) => s.updated_at ?? "\u2014" }
|
|
42101
42164
|
];
|
|
42165
|
+
var DEPTH_COLUMN = {
|
|
42166
|
+
label: "DEPTH",
|
|
42167
|
+
get: (g) => g.depth == null ? "?" : String(g.depth)
|
|
42168
|
+
};
|
|
42169
|
+
var PARENT_COLUMN = {
|
|
42170
|
+
label: "PARENT",
|
|
42171
|
+
get: (g) => g.parent_grant_id === void 0 ? "?" : g.parent_grant_id ?? "\u2014",
|
|
42172
|
+
maxWidth: 36
|
|
42173
|
+
};
|
|
42102
42174
|
var GRANT_COLUMNS2 = [
|
|
42103
42175
|
{ label: "GRANT_ID", get: (g) => g.grant_id, maxWidth: 36 },
|
|
42104
42176
|
{ label: "PRINCIPAL", get: (g) => g.principal_type },
|
|
42105
42177
|
{ label: "LABEL", get: (g) => g.label ?? "\u2014", maxWidth: 24 },
|
|
42178
|
+
DEPTH_COLUMN,
|
|
42106
42179
|
{ label: "STATUS", get: (g) => g.status },
|
|
42107
42180
|
{ label: "CREATED", get: (g) => g.created_at },
|
|
42108
42181
|
{
|
|
@@ -42114,6 +42187,9 @@ var GRANT_COLUMNS2 = [
|
|
|
42114
42187
|
get: (g) => g.grant_expires_at ?? "\u2014"
|
|
42115
42188
|
}
|
|
42116
42189
|
];
|
|
42190
|
+
var AGENT_GRANT_COLUMNS = GRANT_COLUMNS2.flatMap(
|
|
42191
|
+
(col) => col === DEPTH_COLUMN ? [col, PARENT_COLUMN] : [col]
|
|
42192
|
+
);
|
|
42117
42193
|
var USER_COLUMNS = [
|
|
42118
42194
|
{ label: "ID", get: (u) => u.id, maxWidth: 36 },
|
|
42119
42195
|
{ label: "EMAIL", get: (u) => u.email ?? "\u2014" },
|
|
@@ -42190,7 +42266,9 @@ function buildGrantsSubcommand() {
|
|
|
42190
42266
|
label: isOptionalString,
|
|
42191
42267
|
created_at: isString,
|
|
42192
42268
|
expires_at: isOptionalString,
|
|
42193
|
-
grant_expires_at: isAbsentOrOptionalString
|
|
42269
|
+
grant_expires_at: isAbsentOrOptionalString,
|
|
42270
|
+
parent_grant_id: isAbsentOrOptionalString,
|
|
42271
|
+
depth: isAbsentOrOptionalNumber
|
|
42194
42272
|
},
|
|
42195
42273
|
"managed-secrets.grants.list"
|
|
42196
42274
|
);
|
|
@@ -42238,11 +42316,14 @@ function buildGrantsSubcommand() {
|
|
|
42238
42316
|
label: isOptionalString,
|
|
42239
42317
|
created_at: isString,
|
|
42240
42318
|
expires_at: isOptionalString,
|
|
42241
|
-
grant_expires_at: isAbsentOrOptionalString
|
|
42319
|
+
grant_expires_at: isAbsentOrOptionalString,
|
|
42320
|
+
// Rendered through ``AGENT_GRANT_COLUMNS`` (adds PARENT).
|
|
42321
|
+
parent_grant_id: isAbsentOrOptionalString,
|
|
42322
|
+
depth: isAbsentOrOptionalNumber
|
|
42242
42323
|
},
|
|
42243
42324
|
"managed-secrets.grants.list-for-agent"
|
|
42244
42325
|
);
|
|
42245
|
-
emit2(format, rows,
|
|
42326
|
+
emit2(format, rows, AGENT_GRANT_COLUMNS);
|
|
42246
42327
|
});
|
|
42247
42328
|
}
|
|
42248
42329
|
);
|
|
@@ -43726,7 +43807,9 @@ function buildIdentityProvidersCommand() {
|
|
|
43726
43807
|
const webhook = idp.command("webhook").description(
|
|
43727
43808
|
"Manage an identity provider's webhook integration (requires dashboard_identity_providers:webhooks)"
|
|
43728
43809
|
);
|
|
43729
|
-
webhook.command("enable").description(
|
|
43810
|
+
webhook.command("enable").description(
|
|
43811
|
+
"Enable webhook integration (returns the signing secret ONCE, in the webhook_secret field)"
|
|
43812
|
+
).option(APP_FLAG, APP_TARGET_DESC).requiredOption(
|
|
43730
43813
|
"--provider <provider-id>",
|
|
43731
43814
|
"Identity provider ID",
|
|
43732
43815
|
parseUuidArgument("--provider")
|
|
@@ -43758,7 +43841,7 @@ function buildIdentityProvidersCommand() {
|
|
|
43758
43841
|
emit2(format, row);
|
|
43759
43842
|
if (typeof row["webhook_secret"] === "string") {
|
|
43760
43843
|
process.stderr.write(
|
|
43761
|
-
"alter: the webhook_secret above is shown ONCE and cannot be retrieved later.\n"
|
|
43844
|
+
"alter: the webhook_secret field above is shown ONCE and cannot be retrieved later.\n"
|
|
43762
43845
|
);
|
|
43763
43846
|
}
|
|
43764
43847
|
return null;
|
|
@@ -43878,7 +43961,7 @@ alter: re-run with --force --confirm <issuer-host> to revoke those grants and di
|
|
|
43878
43961
|
}
|
|
43879
43962
|
);
|
|
43880
43963
|
webhook.command("rotate").description(
|
|
43881
|
-
"Rotate the webhook signing secret (invalidates the previous; returns the new one ONCE)"
|
|
43964
|
+
"Rotate the webhook signing secret (invalidates the previous; returns the new one ONCE, in the webhook_secret field)"
|
|
43882
43965
|
).option(APP_FLAG, APP_TARGET_DESC).requiredOption(
|
|
43883
43966
|
"--provider <provider-id>",
|
|
43884
43967
|
"Identity provider ID",
|
|
@@ -43926,7 +44009,7 @@ alter: re-run with --force --confirm <issuer-host> to revoke those grants and di
|
|
|
43926
44009
|
emit2(format, row);
|
|
43927
44010
|
if (typeof row["webhook_secret"] === "string") {
|
|
43928
44011
|
process.stderr.write(
|
|
43929
|
-
"alter: the webhook_secret above is shown ONCE and cannot be retrieved later.\n"
|
|
44012
|
+
"alter: the webhook_secret field above is shown ONCE and cannot be retrieved later.\n"
|
|
43930
44013
|
);
|
|
43931
44014
|
}
|
|
43932
44015
|
return null;
|
|
@@ -45327,8 +45410,12 @@ function buildPolicyCommand() {
|
|
|
45327
45410
|
import { Command as Command20 } from "commander";
|
|
45328
45411
|
var CREDENTIAL_SOURCES = ["custom", "shared_dev"];
|
|
45329
45412
|
var PROVIDER_ENVIRONMENTS = ["production", "sandbox"];
|
|
45330
|
-
async function providerCatalogError(client, providerId, environment, credentialSource, scopes,
|
|
45331
|
-
|
|
45413
|
+
async function providerCatalogError(client, providerId, environment, credentialSource, scopes, options = {}) {
|
|
45414
|
+
const create = options.create === true;
|
|
45415
|
+
const redirectUriAlias = options.redirectUriAlias;
|
|
45416
|
+
const readStoredProvider = options.readStoredProvider;
|
|
45417
|
+
const switchesToCustom = !create && credentialSource === "custom" && readStoredProvider !== void 0;
|
|
45418
|
+
if (environment === void 0 && scopes === void 0 && redirectUriAlias === void 0 && !create && !switchesToCustom) {
|
|
45332
45419
|
return null;
|
|
45333
45420
|
}
|
|
45334
45421
|
if (!providerId) {
|
|
@@ -45350,6 +45437,23 @@ async function providerCatalogError(client, providerId, environment, credentialS
|
|
|
45350
45437
|
if (environment !== void 0 && credentialSource === "shared_dev" && environment !== "production") {
|
|
45351
45438
|
return "alter: --credential-source shared_dev only supports --environment production; use custom sandbox credentials\n";
|
|
45352
45439
|
}
|
|
45440
|
+
const aliasSpec = provider.redirect_uri_alias ?? null;
|
|
45441
|
+
const aliasError = redirectUriAliasError(
|
|
45442
|
+
providerId,
|
|
45443
|
+
aliasSpec,
|
|
45444
|
+
credentialSource,
|
|
45445
|
+
redirectUriAlias,
|
|
45446
|
+
create
|
|
45447
|
+
);
|
|
45448
|
+
if (aliasError !== null) return aliasError;
|
|
45449
|
+
if (switchesToCustom && readStoredProvider !== void 0 && aliasSpec !== null && redirectUriAlias === void 0) {
|
|
45450
|
+
const storedAliasError = await redirectUriAliasStoredStateError(
|
|
45451
|
+
readStoredProvider,
|
|
45452
|
+
providerId,
|
|
45453
|
+
aliasSpec
|
|
45454
|
+
);
|
|
45455
|
+
if (storedAliasError !== null) return storedAliasError;
|
|
45456
|
+
}
|
|
45353
45457
|
const availableScopes = provider.available_scopes ?? {};
|
|
45354
45458
|
if (Object.keys(availableScopes).length === 0) {
|
|
45355
45459
|
if (scopes !== void 0 && scopes.length > 0) {
|
|
@@ -45359,7 +45463,7 @@ async function providerCatalogError(client, providerId, environment, credentialS
|
|
|
45359
45463
|
}
|
|
45360
45464
|
return null;
|
|
45361
45465
|
}
|
|
45362
|
-
if (
|
|
45466
|
+
if (create && scopes === void 0) {
|
|
45363
45467
|
return `alter: provider '${providerId}' requires at least one scope (pass --scopes, or "scopes" in --input)
|
|
45364
45468
|
`;
|
|
45365
45469
|
}
|
|
@@ -45390,6 +45494,41 @@ async function providerCatalogError(client, providerId, environment, credentialS
|
|
|
45390
45494
|
}
|
|
45391
45495
|
return null;
|
|
45392
45496
|
}
|
|
45497
|
+
function redirectUriAliasError(providerId, spec, credentialSource, redirectUriAlias, create) {
|
|
45498
|
+
if (spec === null) {
|
|
45499
|
+
return redirectUriAlias === void 0 ? null : `alter: --redirect-uri-alias is not used by ${providerId}
|
|
45500
|
+
`;
|
|
45501
|
+
}
|
|
45502
|
+
if (redirectUriAlias !== void 0 && credentialSource === "shared_dev") {
|
|
45503
|
+
return `alter: --redirect-uri-alias is only accepted with --credential-source custom (Alter-managed credentials carry their own ${spec.label})
|
|
45504
|
+
`;
|
|
45505
|
+
}
|
|
45506
|
+
const custom3 = credentialSource === void 0 || credentialSource === "custom";
|
|
45507
|
+
if (create && custom3 && redirectUriAlias === void 0) {
|
|
45508
|
+
return redirectUriAliasRequiredError(providerId, spec);
|
|
45509
|
+
}
|
|
45510
|
+
return null;
|
|
45511
|
+
}
|
|
45512
|
+
function redirectUriAliasRequiredError(providerId, spec) {
|
|
45513
|
+
return `alter: ${providerId} requires --redirect-uri-alias (${spec.label}): ${spec.description} (pass --redirect-uri-alias, or "redirect_uri_alias" in --input)
|
|
45514
|
+
`;
|
|
45515
|
+
}
|
|
45516
|
+
async function redirectUriAliasStoredStateError(readStoredProvider, providerId, spec) {
|
|
45517
|
+
let current;
|
|
45518
|
+
try {
|
|
45519
|
+
const row = await readStoredProvider();
|
|
45520
|
+
if (row === null || typeof row !== "object") return null;
|
|
45521
|
+
current = row;
|
|
45522
|
+
} catch {
|
|
45523
|
+
return null;
|
|
45524
|
+
}
|
|
45525
|
+
const storedSource = typeof current.credential_source === "string" ? current.credential_source : "custom";
|
|
45526
|
+
const storedAlias = typeof current.redirect_uri_alias === "string" ? current.redirect_uri_alias.trim() : "";
|
|
45527
|
+
if (storedSource === "shared_dev" || storedAlias.length === 0) {
|
|
45528
|
+
return redirectUriAliasRequiredError(providerId, spec);
|
|
45529
|
+
}
|
|
45530
|
+
return null;
|
|
45531
|
+
}
|
|
45393
45532
|
function storedProviderReader(client, appId, providerId) {
|
|
45394
45533
|
let pending2 = null;
|
|
45395
45534
|
return () => pending2 ??= client.providers.get(appId, providerId);
|
|
@@ -45475,6 +45614,16 @@ var PROVIDER_COLUMNS = [
|
|
|
45475
45614
|
// between test money and real money.
|
|
45476
45615
|
{ label: "ENV", get: (p) => p.environment ?? "production" },
|
|
45477
45616
|
{ label: "SCOPES", get: (p) => p.scopes.join(",") || "\u2014", maxWidth: 40 },
|
|
45617
|
+
// The provider-issued redirect name (eBay's RuName). Its provider-side
|
|
45618
|
+
// label is on ``list-catalog``'s REDIRECT ALIAS column. Wide enough for a
|
|
45619
|
+
// real RuName (``<user>-<app>-<title>-<token>``, ~40–60 chars) to print
|
|
45620
|
+
// untruncated — an operator copies this column back into a provider
|
|
45621
|
+
// console, so a clipped value is worse than none.
|
|
45622
|
+
{
|
|
45623
|
+
label: "REDIRECT ALIAS",
|
|
45624
|
+
get: (p) => p.redirect_uri_alias ?? "\u2014",
|
|
45625
|
+
maxWidth: 60
|
|
45626
|
+
},
|
|
45478
45627
|
{ label: "GRANTS", get: (p) => String(p.grants_count) },
|
|
45479
45628
|
{ label: "STATUS", get: (p) => p.status },
|
|
45480
45629
|
{
|
|
@@ -45558,6 +45707,22 @@ function collectRedirectUris(value, previous = []) {
|
|
|
45558
45707
|
const next = value.split(",").map((s) => s.trim()).filter(Boolean);
|
|
45559
45708
|
return [...previous, ...next];
|
|
45560
45709
|
}
|
|
45710
|
+
function validateRedirectUriAliasOrExit(raw, source = "--redirect-uri-alias") {
|
|
45711
|
+
if (raw === void 0) return void 0;
|
|
45712
|
+
const value = raw.trim();
|
|
45713
|
+
if (value.length === 0) {
|
|
45714
|
+
process.stderr.write(`alter: ${source} requires a non-empty value
|
|
45715
|
+
`);
|
|
45716
|
+
process.exit(EXIT_USAGE);
|
|
45717
|
+
}
|
|
45718
|
+
if (value.length > 255) {
|
|
45719
|
+
process.stderr.write(`alter: ${source} must be at most 255 characters
|
|
45720
|
+
`);
|
|
45721
|
+
process.exit(EXIT_USAGE);
|
|
45722
|
+
}
|
|
45723
|
+
return value;
|
|
45724
|
+
}
|
|
45725
|
+
var INPUT_ALIAS_SOURCE = '"redirect_uri_alias" in --input';
|
|
45561
45726
|
function surfaceProviderResponse(row) {
|
|
45562
45727
|
if (typeof row !== "object" || row === null) return;
|
|
45563
45728
|
const r = row;
|
|
@@ -45627,6 +45792,7 @@ function buildProvidersCommand() {
|
|
|
45627
45792
|
// "production" — defeating the tolerance this line exists for.
|
|
45628
45793
|
environment: isAbsentOrOptionalString,
|
|
45629
45794
|
scopes: (v) => Array.isArray(v),
|
|
45795
|
+
redirect_uri_alias: isAbsentOrOptionalString,
|
|
45630
45796
|
status: isString,
|
|
45631
45797
|
grants_count: (v) => typeof v === "number"
|
|
45632
45798
|
},
|
|
@@ -45675,6 +45841,13 @@ function buildProvidersCommand() {
|
|
|
45675
45841
|
get: (p) => p.managed_approved_scopes === void 0 ? "?" : p.managed_approved_scopes === null ? "\u2014" : p.managed_approved_scopes.join(",") || "(none)",
|
|
45676
45842
|
maxWidth: 36
|
|
45677
45843
|
},
|
|
45844
|
+
// Providers that take a provider-issued NAME as redirect_uri
|
|
45845
|
+
// instead of the callback URL show its label (eBay: RuName) —
|
|
45846
|
+
// ``create`` then requires ``--redirect-uri-alias``.
|
|
45847
|
+
{
|
|
45848
|
+
label: "REDIRECT ALIAS",
|
|
45849
|
+
get: (p) => p.redirect_uri_alias?.label ?? "\u2014"
|
|
45850
|
+
},
|
|
45678
45851
|
{ label: "STATUS", get: (p) => p.status }
|
|
45679
45852
|
]);
|
|
45680
45853
|
});
|
|
@@ -45703,9 +45876,12 @@ function buildProvidersCommand() {
|
|
|
45703
45876
|
"--redirect-uri <uri>",
|
|
45704
45877
|
"Add a redirect URI. Repeat the flag (``--redirect-uri A --redirect-uri B``) or pass a comma-separated list (``--redirect-uri A,B``); both forms accumulate.",
|
|
45705
45878
|
collectRedirectUris
|
|
45879
|
+
).option(
|
|
45880
|
+
"--redirect-uri-alias <name>",
|
|
45881
|
+
"The provider-issued redirect name sent as redirect_uri in place of the callback URL \u2014 required for providers that use one (eBay's RuName); see `alter providers list-catalog`."
|
|
45706
45882
|
).option(
|
|
45707
45883
|
"--input <path>",
|
|
45708
|
-
"JSON wire body from file (@/path/to/body.json) or stdin (-). Mirrors ``gh api --input``. Replaces the per-field flags (``--provider``, ``--credential-source``, ``--client-id``, ``--client-secret``, ``--environment``, ``--scopes``, ``--redirect-uri``); the body is sent to ``POST /apps/<app>/providers`` verbatim. If both --input and per-field flags are supplied, --input wins and the per-field flags are ignored (with a warning)."
|
|
45884
|
+
"JSON wire body from file (@/path/to/body.json) or stdin (-). Mirrors ``gh api --input``. Replaces the per-field flags (``--provider``, ``--credential-source``, ``--client-id``, ``--client-secret``, ``--environment``, ``--scopes``, ``--redirect-uri``, ``--redirect-uri-alias``); the body is sent to ``POST /apps/<app>/providers`` verbatim. If both --input and per-field flags are supplied, --input wins and the per-field flags are ignored (with a warning)."
|
|
45709
45885
|
).option(
|
|
45710
45886
|
"--output <format>",
|
|
45711
45887
|
"Output format: json|jsonl|table (default: json)",
|
|
@@ -45723,7 +45899,8 @@ function buildProvidersCommand() {
|
|
|
45723
45899
|
"clientSecret",
|
|
45724
45900
|
"environment",
|
|
45725
45901
|
"scopes",
|
|
45726
|
-
"redirectUri"
|
|
45902
|
+
"redirectUri",
|
|
45903
|
+
"redirectUriAlias"
|
|
45727
45904
|
].filter((k) => {
|
|
45728
45905
|
if (k === "credentialSource")
|
|
45729
45906
|
return options.credentialSource !== "custom";
|
|
@@ -45732,6 +45909,10 @@ function buildProvidersCommand() {
|
|
|
45732
45909
|
return options[k] !== void 0;
|
|
45733
45910
|
});
|
|
45734
45911
|
warnInputOverridesPerFieldFlags(perField.map(optionKeyToFlag));
|
|
45912
|
+
const bodyRedirectUriAlias = validateRedirectUriAliasOrExit(
|
|
45913
|
+
inputBodyString(body, "redirect_uri_alias"),
|
|
45914
|
+
INPUT_ALIAS_SOURCE
|
|
45915
|
+
);
|
|
45735
45916
|
const inputPreflightError = await withClient(
|
|
45736
45917
|
async (client) => {
|
|
45737
45918
|
const bodyEnvironment = inputBodyString(body, "environment");
|
|
@@ -45741,7 +45922,7 @@ function buildProvidersCommand() {
|
|
|
45741
45922
|
bodyEnvironment,
|
|
45742
45923
|
inputBodyString(body, "credential_source"),
|
|
45743
45924
|
inputBodyStringArray(body, "scopes"),
|
|
45744
|
-
true
|
|
45925
|
+
{ create: true, redirectUriAlias: bodyRedirectUriAlias }
|
|
45745
45926
|
);
|
|
45746
45927
|
if (catalogError !== null) return catalogError;
|
|
45747
45928
|
const availabilityError = await sharedDevAvailabilityError(
|
|
@@ -45810,6 +45991,9 @@ function buildProvidersCommand() {
|
|
|
45810
45991
|
validateUrlOrExit("--redirect-uri", uri);
|
|
45811
45992
|
}
|
|
45812
45993
|
const redirects = options.redirectUri && options.redirectUri.length > 0 ? options.redirectUri : void 0;
|
|
45994
|
+
const redirectUriAlias = validateRedirectUriAliasOrExit(
|
|
45995
|
+
options.redirectUriAlias
|
|
45996
|
+
);
|
|
45813
45997
|
const environmentPreflightError = await withClient(
|
|
45814
45998
|
async (client) => {
|
|
45815
45999
|
const catalogError = await providerCatalogError(
|
|
@@ -45818,7 +46002,7 @@ function buildProvidersCommand() {
|
|
|
45818
46002
|
environment,
|
|
45819
46003
|
credentialSource,
|
|
45820
46004
|
scopes,
|
|
45821
|
-
true
|
|
46005
|
+
{ create: true, redirectUriAlias }
|
|
45822
46006
|
);
|
|
45823
46007
|
if (catalogError !== null) return catalogError;
|
|
45824
46008
|
const availabilityError = await sharedDevAvailabilityError(
|
|
@@ -45837,7 +46021,8 @@ function buildProvidersCommand() {
|
|
|
45837
46021
|
// Scopeless provider with --scopes omitted: the dashboard's
|
|
45838
46022
|
// exact wire body for these providers is ``scopes: []``.
|
|
45839
46023
|
scopes: scopes ?? [],
|
|
45840
|
-
redirect_uris: redirects
|
|
46024
|
+
redirect_uris: redirects,
|
|
46025
|
+
redirect_uri_alias: redirectUriAlias
|
|
45841
46026
|
});
|
|
45842
46027
|
surfaceProviderResponse(row);
|
|
45843
46028
|
emit2(format, row);
|
|
@@ -45871,6 +46056,7 @@ function buildProvidersCommand() {
|
|
|
45871
46056
|
credential_source: isOptionalString,
|
|
45872
46057
|
environment: isAbsentOrOptionalString,
|
|
45873
46058
|
scopes: (v) => Array.isArray(v),
|
|
46059
|
+
redirect_uri_alias: isAbsentOrOptionalString,
|
|
45874
46060
|
status: isString,
|
|
45875
46061
|
grants_count: (v) => typeof v === "number"
|
|
45876
46062
|
},
|
|
@@ -45898,6 +46084,9 @@ function buildProvidersCommand() {
|
|
|
45898
46084
|
"--redirect-uri <uri>",
|
|
45899
46085
|
"Replace redirect URIs. Repeat the flag or pass a comma-separated list; both forms accumulate.",
|
|
45900
46086
|
collectRedirectUris
|
|
46087
|
+
).option(
|
|
46088
|
+
"--redirect-uri-alias <name>",
|
|
46089
|
+
"Replace the provider-issued redirect name sent as redirect_uri in place of the callback URL (eBay's RuName). Accepted only for providers that use one; see `alter providers list-catalog`."
|
|
45901
46090
|
).option(
|
|
45902
46091
|
"--status <status>",
|
|
45903
46092
|
"New status: active | disabled (rejected at the CLI if not exactly one of the two values)"
|
|
@@ -45927,24 +46116,33 @@ function buildProvidersCommand() {
|
|
|
45927
46116
|
"environment",
|
|
45928
46117
|
"scopes",
|
|
45929
46118
|
"redirectUri",
|
|
46119
|
+
"redirectUriAlias",
|
|
45930
46120
|
"status"
|
|
45931
46121
|
].filter((k) => options[k] !== void 0);
|
|
45932
46122
|
warnInputOverridesPerFieldFlags(perField.map(optionKeyToFlag));
|
|
46123
|
+
const bodyRedirectUriAlias = validateRedirectUriAliasOrExit(
|
|
46124
|
+
inputBodyString(body, "redirect_uri_alias"),
|
|
46125
|
+
INPUT_ALIAS_SOURCE
|
|
46126
|
+
);
|
|
45933
46127
|
const inputPreflightError = await withClient(
|
|
45934
46128
|
async (client) => {
|
|
46129
|
+
const readStoredProvider = storedProviderReader(
|
|
46130
|
+
client,
|
|
46131
|
+
appId,
|
|
46132
|
+
options.provider
|
|
46133
|
+
);
|
|
45935
46134
|
const catalogError = await providerCatalogError(
|
|
45936
46135
|
client,
|
|
45937
46136
|
options.provider,
|
|
45938
46137
|
inputBodyString(body, "environment"),
|
|
45939
46138
|
inputBodyString(body, "credential_source"),
|
|
45940
|
-
inputBodyStringArray(body, "scopes")
|
|
46139
|
+
inputBodyStringArray(body, "scopes"),
|
|
46140
|
+
{
|
|
46141
|
+
redirectUriAlias: bodyRedirectUriAlias,
|
|
46142
|
+
readStoredProvider
|
|
46143
|
+
}
|
|
45941
46144
|
);
|
|
45942
46145
|
if (catalogError !== null) return catalogError;
|
|
45943
|
-
const readStoredProvider = storedProviderReader(
|
|
45944
|
-
client,
|
|
45945
|
-
appId,
|
|
45946
|
-
options.provider
|
|
45947
|
-
);
|
|
45948
46146
|
const storedStateError = await sharedDevStoredStateError(
|
|
45949
46147
|
readStoredProvider,
|
|
45950
46148
|
options.provider,
|
|
@@ -46006,21 +46204,25 @@ function buildProvidersCommand() {
|
|
|
46006
46204
|
validateUrlOrExit("--redirect-uri", uri);
|
|
46007
46205
|
}
|
|
46008
46206
|
const redirects = options.redirectUri && options.redirectUri.length > 0 ? options.redirectUri : void 0;
|
|
46207
|
+
const redirectUriAlias = validateRedirectUriAliasOrExit(
|
|
46208
|
+
options.redirectUriAlias
|
|
46209
|
+
);
|
|
46009
46210
|
const updatePreflightError = await withClient(
|
|
46010
46211
|
async (client) => {
|
|
46212
|
+
const readStoredProvider = storedProviderReader(
|
|
46213
|
+
client,
|
|
46214
|
+
appId,
|
|
46215
|
+
options.provider
|
|
46216
|
+
);
|
|
46011
46217
|
const catalogError = await providerCatalogError(
|
|
46012
46218
|
client,
|
|
46013
46219
|
options.provider,
|
|
46014
46220
|
environment,
|
|
46015
46221
|
credentialSource,
|
|
46016
|
-
scopes
|
|
46222
|
+
scopes,
|
|
46223
|
+
{ redirectUriAlias, readStoredProvider }
|
|
46017
46224
|
);
|
|
46018
46225
|
if (catalogError !== null) return catalogError;
|
|
46019
|
-
const readStoredProvider = storedProviderReader(
|
|
46020
|
-
client,
|
|
46021
|
-
appId,
|
|
46022
|
-
options.provider
|
|
46023
|
-
);
|
|
46024
46226
|
const storedStateError = await sharedDevStoredStateError(
|
|
46025
46227
|
readStoredProvider,
|
|
46026
46228
|
options.provider,
|
|
@@ -46044,6 +46246,7 @@ function buildProvidersCommand() {
|
|
|
46044
46246
|
...options.skipPreflight ? { skip_preflight: true } : {},
|
|
46045
46247
|
scopes,
|
|
46046
46248
|
redirect_uris: redirects,
|
|
46249
|
+
redirect_uri_alias: redirectUriAlias,
|
|
46047
46250
|
status: providerStatus
|
|
46048
46251
|
});
|
|
46049
46252
|
surfaceProviderResponse(row);
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alter-ai/cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@alter-ai/cli",
|
|
9
|
-
"version": "0.9.
|
|
9
|
+
"version": "0.9.2",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"commander": "12.1.0",
|
|
12
12
|
"posthog-node": "4.18.0"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alter-ai/cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.2",
|
|
4
4
|
"description": "Command-line interface for the Alter Vault dev portal — scripted dashboard automation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"esbuild": "0.28.1"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
|
-
"@alter-ai/alter-sdk": "workspace:0.
|
|
50
|
+
"@alter-ai/alter-sdk": "workspace:0.25.0",
|
|
51
51
|
"@alter-vault/shared-types": "workspace:0.0.1",
|
|
52
52
|
"@alter-vault/shared-utils": "workspace:0.0.1",
|
|
53
53
|
"@eslint/js": "9.39.4",
|