@topolo/cli 0.4.2 → 0.4.4

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.
Files changed (2) hide show
  1. package/dist/index.js +33 -11
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ import { platform as platform2 } from "os";
9
9
  import { createInterface } from "readline/promises";
10
10
  import { stdin as input } from "process";
11
11
 
12
- // ../../../topolo-platform/packages/topolo-sdk/dist/index.js
12
+ // ../topolo-sdk/dist/index.js
13
13
  function applyAuthHeaders(headers, credential) {
14
14
  if (credential.kind === "api_key") {
15
15
  headers.set("X-Api-Key", credential.apiKey);
@@ -3312,7 +3312,6 @@ var CrmModule = class {
3312
3312
  constructor(client) {
3313
3313
  this.client = client;
3314
3314
  }
3315
- client;
3316
3315
  async listContacts(options = {}) {
3317
3316
  const res = await this.client.request({
3318
3317
  service: "crm",
@@ -3358,7 +3357,6 @@ var IdentityModule = class {
3358
3357
  constructor(client) {
3359
3358
  this.client = client;
3360
3359
  }
3361
- client;
3362
3360
  /** Returns the resolved user, organization, and permission set for the
3363
3361
  * current credential. Equivalent to `TopoloClient.introspect()` — exposed
3364
3362
  * on this module for symmetry with the other domain modules. */
@@ -3453,7 +3451,7 @@ function createTopolo(options) {
3453
3451
  };
3454
3452
  }
3455
3453
 
3456
- // ../../../topolo-platform/packages/topolo-sdk/dist/node/credential-store.js
3454
+ // ../topolo-sdk/dist/node/credential-store.js
3457
3455
  import { mkdir, readFile, writeFile, chmod } from "fs/promises";
3458
3456
  import { existsSync } from "fs";
3459
3457
  import { homedir, platform } from "os";
@@ -3783,9 +3781,9 @@ async function refreshCredentialIfNeeded(environment = selectedEnvironment(), op
3783
3781
  const profile = profileForEnvironment(config, environment);
3784
3782
  const cred = profile.credential;
3785
3783
  if (!cred || cred.kind !== "access_token") return cred ?? null;
3786
- if (!cred.refreshToken || !cred.expiresAt || !profile.oauthClientId) return cred;
3784
+ if (!cred.refreshToken || !profile.oauthClientId) return cred;
3787
3785
  const now = Math.floor(Date.now() / 1e3);
3788
- if (!options.force && cred.expiresAt - REFRESH_SKEW_SECONDS > now) return cred;
3786
+ if (!options.force && cred.expiresAt && cred.expiresAt - REFRESH_SKEW_SECONDS > now) return cred;
3789
3787
  try {
3790
3788
  const oauth = new TopoloOAuth2({
3791
3789
  serviceUrls: resolveServiceUrls(profile.serviceUrls, environment)
@@ -11175,6 +11173,14 @@ function labelFor(ctx) {
11175
11173
  if (ctx.contextType === "personal") return "Personal";
11176
11174
  return ctx.organizationName || ctx.organizationSlug || ctx.organizationId || "organization";
11177
11175
  }
11176
+ function isAuthenticationFailure(error) {
11177
+ return error instanceof Error && error.code === "auth_error";
11178
+ }
11179
+ function hasSameAccessToken(left, right) {
11180
+ const leftCredential = left;
11181
+ const rightCredential = right;
11182
+ return leftCredential?.kind === "access_token" && rightCredential?.kind === "access_token" && leftCredential.accessToken === rightCredential.accessToken;
11183
+ }
11178
11184
  function registerContextCommand(program2) {
11179
11185
  const context = program2.command("context").description("Show and switch the active context (personal or an organization)");
11180
11186
  context.command("ls", { isDefault: true }).alias("list").description("List the contexts you can act in and which is active").option("--json", "Output JSON", true).option("--no-json", "Output human-readable text").action(async (opts) => {
@@ -11228,7 +11234,7 @@ function registerContextCommand(program2) {
11228
11234
  const config = await readConfig();
11229
11235
  const profile = profileForEnvironment(config, environment);
11230
11236
  const serviceUrls = resolvedProfileConfig(config, environment).serviceUrls;
11231
- const cred = await refreshCredentialIfNeeded(environment);
11237
+ let cred = await refreshCredentialIfNeeded(environment);
11232
11238
  if (!cred) {
11233
11239
  throw new Error("Not signed in. Run `topolo auth login` first.");
11234
11240
  }
@@ -11269,10 +11275,26 @@ function registerContextCommand(program2) {
11269
11275
  }
11270
11276
  const key = contextKey(resolved.contextType, resolved.organizationId);
11271
11277
  const existing = profile.contexts?.[key];
11272
- const newCredential = await exchangeForContext(cred, serviceUrls, {
11273
- type: resolved.contextType,
11274
- id: resolved.organizationId
11275
- });
11278
+ let newCredential;
11279
+ try {
11280
+ newCredential = await exchangeForContext(cred, serviceUrls, {
11281
+ type: resolved.contextType,
11282
+ id: resolved.organizationId
11283
+ });
11284
+ } catch (error) {
11285
+ if (!isAuthenticationFailure(error)) throw error;
11286
+ const refreshed = await refreshCredentialIfNeeded(environment, { force: true });
11287
+ if (!refreshed || hasSameAccessToken(cred, refreshed)) {
11288
+ throw new Error(
11289
+ `The active credential could not be refreshed. Run \`topolo --env ${environment} auth login\` to sign in again.`
11290
+ );
11291
+ }
11292
+ cred = refreshed;
11293
+ newCredential = await exchangeForContext(cred, serviceUrls, {
11294
+ type: resolved.contextType,
11295
+ id: resolved.organizationId
11296
+ });
11297
+ }
11276
11298
  resolved.credential = newCredential;
11277
11299
  resolved.oauthClientId = existing?.oauthClientId ?? profile.oauthClientId;
11278
11300
  const updated = writeContextCredential(await readConfig(), environment, resolved, true);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topolo/cli",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
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": {