@topolo/sdk 0.11.9 → 0.11.10

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.
@@ -612,52 +612,58 @@ async function refreshCredentialIfNeeded(environment = selectedEnvironment(), op
612
612
  if (process.env[`${prefix}_API_KEY`] || process.env[`${prefix}_ACCESS_TOKEN`] || environment === "production" && process.env.TOPOLO_API_KEY || environment === "production" && process.env.TOPOLO_ACCESS_TOKEN) {
613
613
  return resolveCredential(environment);
614
614
  }
615
- const config = await readConfig();
616
- const profile = profileForEnvironment(config, environment);
617
- const cred = profile.credential;
618
- if (!cred || cred.kind !== "access_token") return cred ?? null;
619
- if (!cred.refreshToken || !profile.oauthClientId) return cred;
620
- const now = Math.floor(Date.now() / 1e3);
621
- if (!options.force && cred.expiresAt && cred.expiresAt - REFRESH_SKEW_SECONDS > now) return cred;
622
- const serviceUrls = resolveServiceUrls(profile.serviceUrls, environment);
623
- if (environment === "local" && !serviceUrls?.auth) {
624
- throw new TopoloSdkError(
625
- "environment_service_url_required",
626
- "Local Topolo credential refresh requires an explicit local Auth service origin."
627
- );
628
- }
629
- try {
630
- const oauth = new TopoloOAuth({
631
- serviceUrls
632
- });
633
- const tokens = await oauth.refreshToken({
634
- clientId: profile.oauthClientId,
635
- refreshToken: cred.refreshToken
636
- });
637
- const refreshed = {
638
- kind: "access_token",
639
- accessToken: tokens.access_token,
640
- ...tokens.refresh_token ? { refreshToken: tokens.refresh_token } : { refreshToken: cred.refreshToken },
641
- expiresAt: Math.floor(Date.now() / 1e3) + tokens.expires_in
642
- };
643
- const activeContext = profile.activeContext;
644
- const activeEntry = activeContext ? profile.contexts?.[activeContext] : void 0;
645
- const updated = activeContext && activeEntry ? writeProfileConfig(config, environment, {
646
- credential: refreshed,
647
- contexts: {
648
- ...profile.contexts ?? {},
649
- [activeContext]: {
650
- ...activeEntry,
651
- credential: refreshed,
652
- oauthClientId: activeEntry.oauthClientId ?? profile.oauthClientId
615
+ const observed = profileForEnvironment(await readConfig(), environment).credential;
616
+ return withConfigWriteLock(async () => {
617
+ const config = await readConfig();
618
+ const profile = profileForEnvironment(config, environment);
619
+ const cred = profile.credential;
620
+ if (!cred || cred.kind !== "access_token") return cred ?? null;
621
+ if (!cred.refreshToken || !profile.oauthClientId) return cred;
622
+ if (options.force && observed?.kind === "access_token" && observed.accessToken !== cred.accessToken) {
623
+ return cred;
624
+ }
625
+ const now = Math.floor(Date.now() / 1e3);
626
+ if (!options.force && cred.expiresAt && cred.expiresAt - REFRESH_SKEW_SECONDS > now) return cred;
627
+ const serviceUrls = resolveServiceUrls(profile.serviceUrls, environment);
628
+ if (environment === "local" && !serviceUrls?.auth) {
629
+ throw new TopoloSdkError(
630
+ "environment_service_url_required",
631
+ "Local Topolo credential refresh requires an explicit local Auth service origin."
632
+ );
633
+ }
634
+ try {
635
+ const oauth = new TopoloOAuth({
636
+ serviceUrls
637
+ });
638
+ const tokens = await oauth.refreshToken({
639
+ clientId: profile.oauthClientId,
640
+ refreshToken: cred.refreshToken
641
+ });
642
+ const refreshed = {
643
+ kind: "access_token",
644
+ accessToken: tokens.access_token,
645
+ ...tokens.refresh_token ? { refreshToken: tokens.refresh_token } : { refreshToken: cred.refreshToken },
646
+ expiresAt: Math.floor(Date.now() / 1e3) + tokens.expires_in
647
+ };
648
+ const activeContext = profile.activeContext;
649
+ const activeEntry = activeContext ? profile.contexts?.[activeContext] : void 0;
650
+ const updated = activeContext && activeEntry ? writeProfileConfig(config, environment, {
651
+ credential: refreshed,
652
+ contexts: {
653
+ ...profile.contexts ?? {},
654
+ [activeContext]: {
655
+ ...activeEntry,
656
+ credential: refreshed,
657
+ oauthClientId: activeEntry.oauthClientId ?? profile.oauthClientId
658
+ }
653
659
  }
654
- }
655
- }) : environment === "production" && !config.profiles?.production ? { ...config, credential: refreshed } : writeProfileConfig(config, environment, { credential: refreshed });
656
- await writeConfig(updated);
657
- return refreshed;
658
- } catch {
659
- return cred;
660
- }
660
+ }) : environment === "production" && !config.profiles?.production ? { ...config, credential: refreshed } : writeProfileConfig(config, environment, { credential: refreshed });
661
+ await writeConfig(updated);
662
+ return refreshed;
663
+ } catch {
664
+ return cred;
665
+ }
666
+ });
661
667
  }
662
668
  async function refreshContextCredentialIfNeeded(environment, key, options = {}) {
663
669
  return withConfigWriteLock(async () => {
@@ -565,52 +565,58 @@ async function refreshCredentialIfNeeded(environment = selectedEnvironment(), op
565
565
  if (process.env[`${prefix}_API_KEY`] || process.env[`${prefix}_ACCESS_TOKEN`] || environment === "production" && process.env.TOPOLO_API_KEY || environment === "production" && process.env.TOPOLO_ACCESS_TOKEN) {
566
566
  return resolveCredential(environment);
567
567
  }
568
- const config = await readConfig();
569
- const profile = profileForEnvironment(config, environment);
570
- const cred = profile.credential;
571
- if (!cred || cred.kind !== "access_token") return cred ?? null;
572
- if (!cred.refreshToken || !profile.oauthClientId) return cred;
573
- const now = Math.floor(Date.now() / 1e3);
574
- if (!options.force && cred.expiresAt && cred.expiresAt - REFRESH_SKEW_SECONDS > now) return cred;
575
- const serviceUrls = resolveServiceUrls(profile.serviceUrls, environment);
576
- if (environment === "local" && !serviceUrls?.auth) {
577
- throw new TopoloSdkError(
578
- "environment_service_url_required",
579
- "Local Topolo credential refresh requires an explicit local Auth service origin."
580
- );
581
- }
582
- try {
583
- const oauth = new TopoloOAuth({
584
- serviceUrls
585
- });
586
- const tokens = await oauth.refreshToken({
587
- clientId: profile.oauthClientId,
588
- refreshToken: cred.refreshToken
589
- });
590
- const refreshed = {
591
- kind: "access_token",
592
- accessToken: tokens.access_token,
593
- ...tokens.refresh_token ? { refreshToken: tokens.refresh_token } : { refreshToken: cred.refreshToken },
594
- expiresAt: Math.floor(Date.now() / 1e3) + tokens.expires_in
595
- };
596
- const activeContext = profile.activeContext;
597
- const activeEntry = activeContext ? profile.contexts?.[activeContext] : void 0;
598
- const updated = activeContext && activeEntry ? writeProfileConfig(config, environment, {
599
- credential: refreshed,
600
- contexts: {
601
- ...profile.contexts ?? {},
602
- [activeContext]: {
603
- ...activeEntry,
604
- credential: refreshed,
605
- oauthClientId: activeEntry.oauthClientId ?? profile.oauthClientId
568
+ const observed = profileForEnvironment(await readConfig(), environment).credential;
569
+ return withConfigWriteLock(async () => {
570
+ const config = await readConfig();
571
+ const profile = profileForEnvironment(config, environment);
572
+ const cred = profile.credential;
573
+ if (!cred || cred.kind !== "access_token") return cred ?? null;
574
+ if (!cred.refreshToken || !profile.oauthClientId) return cred;
575
+ if (options.force && observed?.kind === "access_token" && observed.accessToken !== cred.accessToken) {
576
+ return cred;
577
+ }
578
+ const now = Math.floor(Date.now() / 1e3);
579
+ if (!options.force && cred.expiresAt && cred.expiresAt - REFRESH_SKEW_SECONDS > now) return cred;
580
+ const serviceUrls = resolveServiceUrls(profile.serviceUrls, environment);
581
+ if (environment === "local" && !serviceUrls?.auth) {
582
+ throw new TopoloSdkError(
583
+ "environment_service_url_required",
584
+ "Local Topolo credential refresh requires an explicit local Auth service origin."
585
+ );
586
+ }
587
+ try {
588
+ const oauth = new TopoloOAuth({
589
+ serviceUrls
590
+ });
591
+ const tokens = await oauth.refreshToken({
592
+ clientId: profile.oauthClientId,
593
+ refreshToken: cred.refreshToken
594
+ });
595
+ const refreshed = {
596
+ kind: "access_token",
597
+ accessToken: tokens.access_token,
598
+ ...tokens.refresh_token ? { refreshToken: tokens.refresh_token } : { refreshToken: cred.refreshToken },
599
+ expiresAt: Math.floor(Date.now() / 1e3) + tokens.expires_in
600
+ };
601
+ const activeContext = profile.activeContext;
602
+ const activeEntry = activeContext ? profile.contexts?.[activeContext] : void 0;
603
+ const updated = activeContext && activeEntry ? writeProfileConfig(config, environment, {
604
+ credential: refreshed,
605
+ contexts: {
606
+ ...profile.contexts ?? {},
607
+ [activeContext]: {
608
+ ...activeEntry,
609
+ credential: refreshed,
610
+ oauthClientId: activeEntry.oauthClientId ?? profile.oauthClientId
611
+ }
606
612
  }
607
- }
608
- }) : environment === "production" && !config.profiles?.production ? { ...config, credential: refreshed } : writeProfileConfig(config, environment, { credential: refreshed });
609
- await writeConfig(updated);
610
- return refreshed;
611
- } catch {
612
- return cred;
613
- }
613
+ }) : environment === "production" && !config.profiles?.production ? { ...config, credential: refreshed } : writeProfileConfig(config, environment, { credential: refreshed });
614
+ await writeConfig(updated);
615
+ return refreshed;
616
+ } catch {
617
+ return cred;
618
+ }
619
+ });
614
620
  }
615
621
  async function refreshContextCredentialIfNeeded(environment, key, options = {}) {
616
622
  return withConfigWriteLock(async () => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@topolo/sdk",
3
- "version": "0.11.9",
4
- "topoloPublishedVersion": "0.11.9",
3
+ "version": "0.11.10",
4
+ "topoloPublishedVersion": "0.11.10",
5
5
  "description": "Typed client SDK for the Topolo platform. Used by TopoloCli, TopoloMCP, and third-party agents.",
6
6
  "license": "UNLICENSED",
7
7
  "author": "Topolo",