diff options
Diffstat (limited to 'packages/opencode/src/auth/index.ts')
| -rw-r--r-- | packages/opencode/src/auth/index.ts | 112 |
1 files changed, 2 insertions, 110 deletions
diff --git a/packages/opencode/src/auth/index.ts b/packages/opencode/src/auth/index.ts index 2a9fb6c19..9174745fd 100644 --- a/packages/opencode/src/auth/index.ts +++ b/packages/opencode/src/auth/index.ts @@ -1,110 +1,2 @@ -import path from "path" -import { Effect, Layer, Record, Result, Schema, ServiceMap } from "effect" -import { makeRuntime } from "@/effect/run-service" -import { zod } from "@/util/effect-zod" -import { Global } from "../global" -import { AppFileSystem } from "../filesystem" - -export const OAUTH_DUMMY_KEY = "opencode-oauth-dummy-key" - -const file = path.join(Global.Path.data, "auth.json") - -const fail = (message: string) => (cause: unknown) => new Auth.AuthError({ message, cause }) - -export namespace Auth { - export class Oauth extends Schema.Class<Oauth>("OAuth")({ - type: Schema.Literal("oauth"), - refresh: Schema.String, - access: Schema.String, - expires: Schema.Number, - accountId: Schema.optional(Schema.String), - enterpriseUrl: Schema.optional(Schema.String), - }) {} - - export class Api extends Schema.Class<Api>("ApiAuth")({ - type: Schema.Literal("api"), - key: Schema.String, - metadata: Schema.optional(Schema.Record(Schema.String, Schema.String)), - }) {} - - export class WellKnown extends Schema.Class<WellKnown>("WellKnownAuth")({ - type: Schema.Literal("wellknown"), - key: Schema.String, - token: Schema.String, - }) {} - - const _Info = Schema.Union([Oauth, Api, WellKnown]).annotate({ discriminator: "type", identifier: "Auth" }) - export const Info = Object.assign(_Info, { zod: zod(_Info) }) - export type Info = Schema.Schema.Type<typeof _Info> - - export class AuthError extends Schema.TaggedErrorClass<AuthError>()("AuthError", { - message: Schema.String, - cause: Schema.optional(Schema.Defect), - }) {} - - export interface Interface { - readonly get: (providerID: string) => Effect.Effect<Info | undefined, AuthError> - readonly all: () => Effect.Effect<Record<string, Info>, AuthError> - readonly set: (key: string, info: Info) => Effect.Effect<void, AuthError> - readonly remove: (key: string) => Effect.Effect<void, AuthError> - } - - export class Service extends ServiceMap.Service<Service, Interface>()("@opencode/Auth") {} - - export const layer = Layer.effect( - Service, - Effect.gen(function* () { - const fsys = yield* AppFileSystem.Service - const decode = Schema.decodeUnknownOption(Info) - - const all = Effect.fn("Auth.all")(function* () { - const data = (yield* fsys.readJson(file).pipe(Effect.orElseSucceed(() => ({})))) as Record<string, unknown> - return Record.filterMap(data, (value) => Result.fromOption(decode(value), () => undefined)) - }) - - const get = Effect.fn("Auth.get")(function* (providerID: string) { - return (yield* all())[providerID] - }) - - const set = Effect.fn("Auth.set")(function* (key: string, info: Info) { - const norm = key.replace(/\/+$/, "") - const data = yield* all() - if (norm !== key) delete data[key] - delete data[norm + "/"] - yield* fsys - .writeJson(file, { ...data, [norm]: info }, 0o600) - .pipe(Effect.mapError(fail("Failed to write auth data"))) - }) - - const remove = Effect.fn("Auth.remove")(function* (key: string) { - const norm = key.replace(/\/+$/, "") - const data = yield* all() - delete data[key] - delete data[norm] - yield* fsys.writeJson(file, data, 0o600).pipe(Effect.mapError(fail("Failed to write auth data"))) - }) - - return Service.of({ get, all, set, remove }) - }), - ) - - export const defaultLayer = layer.pipe(Layer.provide(AppFileSystem.defaultLayer)) - - const { runPromise } = makeRuntime(Service, defaultLayer) - - export async function get(providerID: string) { - return runPromise((service) => service.get(providerID)) - } - - export async function all(): Promise<Record<string, Info>> { - return runPromise((service) => service.all()) - } - - export async function set(key: string, info: Info) { - return runPromise((service) => service.set(key, info)) - } - - export async function remove(key: string) { - return runPromise((service) => service.remove(key)) - } -} +export * as Auth from "./auth" +export { OAUTH_DUMMY_KEY } from "./auth" |
