diff options
| author | Kit Langton <[email protected]> | 2026-04-15 22:13:56 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-04-16 02:13:56 +0000 |
| commit | 710c81984aa38618ca7106b9521100a9964ae51d (patch) | |
| tree | 2c60f61113c5e1af8332c9d795eee9c6a864c904 | |
| parent | a1dbfb5967c564bd082c84a6fb8510208edde12f (diff) | |
| download | opencode-710c81984aa38618ca7106b9521100a9964ae51d.tar.gz opencode-710c81984aa38618ca7106b9521100a9964ae51d.zip | |
feat: unwrap uauth namespace to flat exports + barrel (#22699)
| -rw-r--r-- | packages/opencode/src/auth/auth.ts | 89 | ||||
| -rw-r--r-- | packages/opencode/src/auth/index.ts | 93 |
2 files changed, 91 insertions, 91 deletions
diff --git a/packages/opencode/src/auth/auth.ts b/packages/opencode/src/auth/auth.ts new file mode 100644 index 000000000..fb9d2b149 --- /dev/null +++ b/packages/opencode/src/auth/auth.ts @@ -0,0 +1,89 @@ +import path from "path" +import { Effect, Layer, Record, Result, Schema, Context } from "effect" +import { zod } from "@/util/effect-zod" +import { Global } from "../global" +import { AppFileSystem } from "@opencode-ai/shared/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 AuthError({ message, cause }) + +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 Context.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)) diff --git a/packages/opencode/src/auth/index.ts b/packages/opencode/src/auth/index.ts index b287ce551..9174745fd 100644 --- a/packages/opencode/src/auth/index.ts +++ b/packages/opencode/src/auth/index.ts @@ -1,91 +1,2 @@ -import path from "path" -import { Effect, Layer, Record, Result, Schema, Context } from "effect" -import { zod } from "@/util/effect-zod" -import { Global } from "../global" -import { AppFileSystem } from "@opencode-ai/shared/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 Context.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)) -} +export * as Auth from "./auth" +export { OAUTH_DUMMY_KEY } from "./auth" |
