Skip to content

refactor(forges): bundle related ForgeAdapter members into capability objects#2887

Open
afonsojramos wants to merge 3 commits into
mainfrom
refactor-forge-adapter-oauth-app-validators
Open

refactor(forges): bundle related ForgeAdapter members into capability objects#2887
afonsojramos wants to merge 3 commits into
mainfrom
refactor-forge-adapter-oauth-app-validators

Conversation

@afonsojramos
Copy link
Copy Markdown
Member

@afonsojramos afonsojramos commented May 12, 2026

Summary

ForgeAdapter had grown a flat list of related-but-optional members (4 device-flow fields, 2 OAuth-app fields, 4 scope-check fields plus a supportsOAuthScopes: boolean flag), which made "does this forge support X?" a multi-property check and made it possible to half-implement a flow at the type level. Each commit groups one such cluster into a single optional capability bundle.

1. oauthScopes bundle

Replaces supportsOAuthScopes: boolean + the three always-required hasRequiredScopes / hasRecommendedScopes / hasAlternateScopes methods (which Gitea stubbed with () => true) with an optional oauthScopes?: { hasRequired, hasRecommended, hasAlternate }. Gitea drops the stubs entirely; oauthScopes === undefined is the "no scope concept" signal.

2. oauthWebApp bundle

Replaces flat performWebOAuth? + exchangeAuthCodeForToken? plus the previously-direct isValidClientId / getNewOAuthAppURL imports in LoginWithOAuthApp.tsx with oauthWebApp?: { performWebOAuth, exchangeAuthCodeForToken, validateClientId, getNewOAuthAppUrl }. The route now dispatches through getAdapter(forge).oauthWebApp?.*, and the "Create new OAuth App" button hides when the adapter doesn't expose the bundle.

3. deviceFlow bundle

Replaces flat deviceFlowAuthMethod? + startDeviceFlow? + pollDeviceFlow? with deviceFlow?: { authMethod, start, poll, getRevokeAccessUrl }. The new getRevokeAccessUrl is what previously synthesised a fake `Account` and shoved it through `openAccountSettings` in `LoginWithDeviceFlow.tsx`. The revoke-access hint now reads `adapter.displayName` and the bundle URL, and hides when the adapter doesn't expose a device-flow.

Call-site delta

Before: `if (adapter.startDeviceFlow && adapter.pollDeviceFlow && adapter.deviceFlowAuthMethod) { … }`
After: `if (adapter.deviceFlow) { … }` — TS narrows the whole bundle at once, and partial implementations are now impossible.

Test plan

  • `pnpm exec tsc --noEmit` — clean
  • `pnpm lint` — clean
  • `pnpm exec vitest --run` — 390 passes across affected suites (forges, App context, login routes, scopes helper)

@github-actions github-actions Bot added the refactor Refactoring of existing feature label May 12, 2026
@setchy
Copy link
Copy Markdown
Member

setchy commented May 12, 2026

Instead of ForgeAdapter being flat with many optional, but related functions needed an implementation... Could we encapsulate this differently?

ie: if a forge adapter implementats the OAuth flow then it needs to implement the 3-4 funds. Similarly for PATs and other "groupable" interface fns

@afonsojramos
Copy link
Copy Markdown
Member Author

oOoOoOo I like that 👀

@afonsojramos afonsojramos force-pushed the refactor-forge-adapter-oauth-app-validators branch from fc309d6 to 52b7b74 Compare May 12, 2026 02:20
@sonarqubecloud
Copy link
Copy Markdown

@afonsojramos
Copy link
Copy Markdown
Member Author

@setchy updated the PR btw

@afonsojramos afonsojramos changed the title refactor(forges): route OAuth-app validators through the adapter refactor(forges): bundle related ForgeAdapter members into capability objects May 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

refactor Refactoring of existing feature

Development

Successfully merging this pull request may close these issues.

2 participants