index.ts 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. import path from "path"
  2. import { Global } from "../global"
  3. import fs from "fs/promises"
  4. import z from "zod"
  5. export const OAUTH_DUMMY_KEY = "opencode-oauth-dummy-key"
  6. export namespace Auth {
  7. export const Oauth = z
  8. .object({
  9. type: z.literal("oauth"),
  10. refresh: z.string(),
  11. access: z.string(),
  12. expires: z.number(),
  13. accountId: z.string().optional(),
  14. enterpriseUrl: z.string().optional(),
  15. })
  16. .meta({ ref: "OAuth" })
  17. export const Api = z
  18. .object({
  19. type: z.literal("api"),
  20. key: z.string(),
  21. })
  22. .meta({ ref: "ApiAuth" })
  23. export const WellKnown = z
  24. .object({
  25. type: z.literal("wellknown"),
  26. key: z.string(),
  27. token: z.string(),
  28. })
  29. .meta({ ref: "WellKnownAuth" })
  30. export const Info = z.discriminatedUnion("type", [Oauth, Api, WellKnown]).meta({ ref: "Auth" })
  31. export type Info = z.infer<typeof Info>
  32. const filepath = path.join(Global.Path.data, "auth.json")
  33. export async function get(providerID: string) {
  34. const auth = await all()
  35. return auth[providerID]
  36. }
  37. export async function all(): Promise<Record<string, Info>> {
  38. const file = Bun.file(filepath)
  39. const data = await file.json().catch(() => ({}) as Record<string, unknown>)
  40. return Object.entries(data).reduce(
  41. (acc, [key, value]) => {
  42. const parsed = Info.safeParse(value)
  43. if (!parsed.success) return acc
  44. acc[key] = parsed.data
  45. return acc
  46. },
  47. {} as Record<string, Info>,
  48. )
  49. }
  50. export async function set(key: string, info: Info) {
  51. const file = Bun.file(filepath)
  52. const data = await all()
  53. await Bun.write(file, JSON.stringify({ ...data, [key]: info }, null, 2))
  54. await fs.chmod(file.name!, 0o600)
  55. }
  56. export async function remove(key: string) {
  57. const file = Bun.file(filepath)
  58. const data = await all()
  59. delete data[key]
  60. await Bun.write(file, JSON.stringify(data, null, 2))
  61. await fs.chmod(file.name!, 0o600)
  62. }
  63. }