refactor(api): scope oauth operations by integration

This commit is contained in:
Dax Raad 2026-07-15 18:20:19 -04:00
commit a772767e9b
19 changed files with 404 additions and 303 deletions

View file

@ -46,7 +46,7 @@ const login = Effect.fn("cli.console.login.run")(function* (timeline: TimelineHo
yield* request(() => timeline.pending("Starting authorization..."))
const started = yield* request((signal) =>
client.integration.connect.oauth(
client.integration.oauth.connect(
{
integrationID,
methodID: method.id,
@ -59,8 +59,8 @@ const login = Effect.fn("cli.console.login.run")(function* (timeline: TimelineHo
const attempt = started.data
yield* Effect.addFinalizer(() =>
request(() =>
client.integration.attempt.cancel(
{ attemptID: attempt.attemptID, location },
client.integration.oauth.cancel(
{ integrationID, attemptID: attempt.attemptID, location },
{ signal: AbortSignal.timeout(5_000) },
),
).pipe(Effect.ignore),
@ -75,7 +75,7 @@ const login = Effect.fn("cli.console.login.run")(function* (timeline: TimelineHo
}).pipe(Effect.ignore)
yield* request(() => timeline.pending("Waiting for authorization..."))
const status = yield* waitForConsoleLogin(client, attempt.attemptID)
const status = yield* waitForConsoleLogin(client, integrationID, attempt.attemptID)
if (status.status === "failed") yield* Effect.fail(new Error(status.message))
if (status.status === "expired") yield* Effect.fail(new Error("Device code expired"))
@ -85,11 +85,12 @@ const login = Effect.fn("cli.console.login.run")(function* (timeline: TimelineHo
const waitForConsoleLogin = Effect.fn("cli.console.login.wait")(function* (
client: OpenCodeClient,
integrationID: string,
attemptID: string,
) {
while (true) {
const response = yield* request((signal) =>
client.integration.attempt.status({ attemptID, location }, { signal }),
client.integration.oauth.status({ integrationID, attemptID, location }, { signal }),
)
if (response.data.status !== "pending") return response.data
yield* Effect.sleep(500)

View file

@ -32,7 +32,7 @@ export default Runtime.handler(
return yield* Effect.fail(new Error(`MCP server "${input.name}" is not an OAuth-capable remote server`))
const started = yield* Effect.promise(() =>
client.integration.connect.oauth({ integrationID: integration.id, methodID: method.id, inputs: {}, location }),
client.integration.oauth.connect({ integrationID: integration.id, methodID: method.id, inputs: {}, location }),
)
const attempt = started.data
if (attempt.mode === "code")
@ -40,7 +40,7 @@ export default Runtime.handler(
process.stdout.write(attempt.instructions + EOL + attempt.url + EOL)
const result = yield* poll(client, attempt.attemptID)
const result = yield* poll(client, integration.id, attempt.attemptID)
if (result.status === "complete") {
process.stdout.write(`Authenticated with ${input.name}` + EOL)
return
@ -52,15 +52,16 @@ export default Runtime.handler(
const poll = (
client: OpenCodeClient,
integrationID: string,
attemptID: string,
): Effect.Effect<Exclude<IntegrationAttemptStatus, { status: "pending" }>> =>
Effect.gen(function* () {
const status = yield* Effect.promise(() => client.integration.attempt.status({ attemptID, location })).pipe(
Effect.map((result) => result.data),
)
const status = yield* Effect.promise(() =>
client.integration.oauth.status({ integrationID, attemptID, location }),
).pipe(Effect.map((result) => result.data))
if (status.status === "pending") {
yield* Effect.sleep("1 second")
return yield* poll(client, attemptID)
return yield* poll(client, integrationID, attemptID)
}
return status
})