@topolo/cli 0.4.0 → 0.4.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/index.js +10 -46
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3819,46 +3819,6 @@ async function refreshCredentialIfNeeded(environment = selectedEnvironment(), op
|
|
|
3819
3819
|
return cred;
|
|
3820
3820
|
}
|
|
3821
3821
|
}
|
|
3822
|
-
async function refreshContextCredentialIfNeeded(environment, key, options = {}) {
|
|
3823
|
-
const config = await readConfig();
|
|
3824
|
-
const profile = profileForEnvironment(config, environment);
|
|
3825
|
-
const context = profile.contexts?.[key];
|
|
3826
|
-
const credential = context?.credential;
|
|
3827
|
-
if (!credential || credential.kind !== "access_token") return credential ?? null;
|
|
3828
|
-
const oauthClientId = context.oauthClientId ?? profile.oauthClientId;
|
|
3829
|
-
if (!credential.refreshToken || !credential.expiresAt || !oauthClientId) return credential;
|
|
3830
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
3831
|
-
if (!options.force && credential.expiresAt - REFRESH_SKEW_SECONDS > now) return credential;
|
|
3832
|
-
try {
|
|
3833
|
-
const oauth = new TopoloOAuth2({
|
|
3834
|
-
serviceUrls: resolveServiceUrls(profile.serviceUrls, environment)
|
|
3835
|
-
});
|
|
3836
|
-
const tokens = await oauth.refreshToken({
|
|
3837
|
-
clientId: oauthClientId,
|
|
3838
|
-
refreshToken: credential.refreshToken
|
|
3839
|
-
});
|
|
3840
|
-
const refreshed = {
|
|
3841
|
-
kind: "access_token",
|
|
3842
|
-
accessToken: tokens.access_token,
|
|
3843
|
-
...tokens.refresh_token ? { refreshToken: tokens.refresh_token } : { refreshToken: credential.refreshToken },
|
|
3844
|
-
expiresAt: Math.floor(Date.now() / 1e3) + tokens.expires_in
|
|
3845
|
-
};
|
|
3846
|
-
await writeConfig(writeProfileConfig(config, environment, {
|
|
3847
|
-
...profile.activeContext === key ? { credential: refreshed } : {},
|
|
3848
|
-
contexts: {
|
|
3849
|
-
...profile.contexts ?? {},
|
|
3850
|
-
[key]: {
|
|
3851
|
-
...context,
|
|
3852
|
-
credential: refreshed,
|
|
3853
|
-
oauthClientId
|
|
3854
|
-
}
|
|
3855
|
-
}
|
|
3856
|
-
}));
|
|
3857
|
-
return refreshed;
|
|
3858
|
-
} catch {
|
|
3859
|
-
return credential;
|
|
3860
|
-
}
|
|
3861
|
-
}
|
|
3862
3822
|
function resolveAgentName(configAgentName) {
|
|
3863
3823
|
return process.env.TOPOLO_AGENT_NAME ?? configAgentName;
|
|
3864
3824
|
}
|
|
@@ -4010,7 +3970,7 @@ var CLI_VERSION = readCliVersion();
|
|
|
4010
3970
|
// src/commands/auth.ts
|
|
4011
3971
|
function registerAuthCommands(program2) {
|
|
4012
3972
|
const auth = program2.command("auth").description("Manage Topolo credentials");
|
|
4013
|
-
auth.command("login").description("Authenticate with Topolo via OAuth device flow (default) or store an API key").option("--api-key <key>", "Store an API key directly, skipping the OAuth flow").option("--client-id <id>", "OAuth client_id (or set TOPOLO_CLI_CLIENT_ID)").option("--scope <scope>", "Scopes to request (space-separated)").option("--json", "Output JSON").option("--no-json", "Output human-readable text").action(
|
|
3973
|
+
auth.command("login").description("Authenticate with Topolo via OAuth device flow (default) or store an API key").option("--api-key <key>", "Store an API key directly, skipping the OAuth flow").option("--client-id <id>", "OAuth client_id (or set TOPOLO_CLI_CLIENT_ID)").option("--scope <scope>", "Scopes to request (space-separated)").option("--no-browser", "Print the approval URL without opening a browser").option("--json", "Output JSON").option("--no-json", "Output human-readable text").action(
|
|
4014
3974
|
async (opts) => {
|
|
4015
3975
|
const mode = resolveOutputMode(opts.json);
|
|
4016
3976
|
const environment = selectedEnvironment();
|
|
@@ -4039,7 +3999,13 @@ Visit ${apiKeyIssuanceUrl(environment)} to mint one, or configure an OAuth clien
|
|
|
4039
3999
|
await storeApiKey(apiKey, environment, mode);
|
|
4040
4000
|
return;
|
|
4041
4001
|
}
|
|
4042
|
-
await runDeviceFlow({
|
|
4002
|
+
await runDeviceFlow({
|
|
4003
|
+
clientId,
|
|
4004
|
+
environment,
|
|
4005
|
+
scope: opts.scope,
|
|
4006
|
+
mode,
|
|
4007
|
+
openBrowser: opts.browser !== false
|
|
4008
|
+
});
|
|
4043
4009
|
} catch (err) {
|
|
4044
4010
|
fail(err, mode);
|
|
4045
4011
|
}
|
|
@@ -4113,7 +4079,7 @@ async function runDeviceFlow(options) {
|
|
|
4113
4079
|
});
|
|
4114
4080
|
const verifyUrl = start.verification_uri_complete ?? start.verification_uri;
|
|
4115
4081
|
const expiresMin = Math.round(start.expires_in / 60);
|
|
4116
|
-
const opened = options.mode === "pretty" ? tryOpenBrowser(verifyUrl) : false;
|
|
4082
|
+
const opened = options.mode === "pretty" && options.openBrowser ? tryOpenBrowser(verifyUrl) : false;
|
|
4117
4083
|
if (options.mode === "pretty") {
|
|
4118
4084
|
process.stderr.write(
|
|
4119
4085
|
`
|
|
@@ -11268,7 +11234,6 @@ function registerContextCommand(program2) {
|
|
|
11268
11234
|
}
|
|
11269
11235
|
const wantPersonal = /^(personal|me)$/i.test(target.trim());
|
|
11270
11236
|
let resolved;
|
|
11271
|
-
let exchangeCredential = cred;
|
|
11272
11237
|
const needle = target.trim().toLowerCase();
|
|
11273
11238
|
const storedEntry = Object.entries(profile.contexts ?? {}).find(([, candidate]) => {
|
|
11274
11239
|
if (wantPersonal) return candidate.contextType === "personal";
|
|
@@ -11276,7 +11241,6 @@ function registerContextCommand(program2) {
|
|
|
11276
11241
|
});
|
|
11277
11242
|
const storedContext = storedEntry?.[1];
|
|
11278
11243
|
if (storedEntry && storedContext?.credential) {
|
|
11279
|
-
exchangeCredential = await refreshContextCredentialIfNeeded(environment, storedEntry[0]) ?? storedContext.credential;
|
|
11280
11244
|
resolved = {
|
|
11281
11245
|
contextType: storedContext.contextType,
|
|
11282
11246
|
organizationId: storedContext.organizationId,
|
|
@@ -11305,7 +11269,7 @@ function registerContextCommand(program2) {
|
|
|
11305
11269
|
}
|
|
11306
11270
|
const key = contextKey(resolved.contextType, resolved.organizationId);
|
|
11307
11271
|
const existing = profile.contexts?.[key];
|
|
11308
|
-
const newCredential = await exchangeForContext(
|
|
11272
|
+
const newCredential = await exchangeForContext(cred, serviceUrls, {
|
|
11309
11273
|
type: resolved.contextType,
|
|
11310
11274
|
id: resolved.organizationId
|
|
11311
11275
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@topolo/cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Command-line interface for Topolo developers, operators, and agents, with internal first-party scaffolding available under the topolo platform namespace.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|