( connection: ExecutorServerConnection, )
| 740 | key.startsWith("profile:") ? key.slice("profile:".length) : null; |
| 741 | |
| 742 | const refreshOAuthConnection = ( |
| 743 | connection: ExecutorServerConnection, |
| 744 | ): Effect.Effect<ExecutorServerConnection, never, FileSystem.FileSystem | PlatformPath.Path> => |
| 745 | Effect.gen(function* () { |
| 746 | const auth = connection.auth; |
| 747 | if (!auth || auth.kind !== "oauth") return connection; |
| 748 | const now = Math.floor(Date.now() / 1000); |
| 749 | if (auth.expiresAt && auth.expiresAt - now > OAUTH_REFRESH_SKEW_SECONDS) return connection; |
| 750 | // Destructure so the narrowed string types survive into the deferred |
| 751 | // `tryPromise` callback (where TS would otherwise re-widen the fields). |
| 752 | const { refreshToken, tokenEndpoint, clientId } = auth; |
| 753 | if (!refreshToken || !tokenEndpoint || !clientId) return connection; |
| 754 | |
| 755 | const refreshed = yield* Effect.tryPromise({ |
| 756 | try: () => refreshDeviceTokens({ tokenEndpoint, clientId, refreshToken }), |
| 757 | catch: toError, |
| 758 | // On a failed refresh, keep the existing token and let the eventual 401 |
| 759 | // surface, better than blocking the command on a transient hiccup. |
| 760 | }).pipe(Effect.option); |
| 761 | if (Option.isNone(refreshed)) return connection; |
| 762 | |
| 763 | const next = refreshed.value; |
| 764 | const nextConnection = normalizeExecutorServerConnection({ |
| 765 | ...connection, |
| 766 | auth: { |
| 767 | kind: "oauth", |
| 768 | accessToken: next.accessToken, |
| 769 | refreshToken: next.refreshToken ?? refreshToken, |
| 770 | ...(next.expiresAt ? { expiresAt: next.expiresAt } : {}), |
| 771 | tokenEndpoint, |
| 772 | clientId, |
| 773 | }, |
| 774 | }); |
| 775 | |
| 776 | const profileName = profileNameFromKey(connection.key); |
| 777 | if (profileName) { |
| 778 | yield* upsertCliServerConnectionProfile({ |
| 779 | name: profileName, |
| 780 | connection: nextConnection, |
| 781 | makeDefault: false, |
| 782 | }).pipe(Effect.ignore); |
| 783 | } |
| 784 | return nextConnection; |
| 785 | }); |
| 786 | |
| 787 | const resolveExecutorServerConnection = ( |
| 788 | target: ServerTarget, |
no test coverage detected