@harars/opencode-switch-openai-auth-plugin 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -1
- package/dist/highlights-eq9cgrbb.scm +604 -0
- package/dist/highlights-ghv9g403.scm +205 -0
- package/dist/highlights-hk7bwhj4.scm +284 -0
- package/dist/highlights-r812a2qc.scm +150 -0
- package/dist/highlights-x6tmsnaa.scm +115 -0
- package/dist/index.js +922 -0
- package/dist/injections-73j83es3.scm +27 -0
- package/dist/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
- package/dist/tree-sitter-markdown-411r6y9b.wasm +0 -0
- package/dist/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
- package/dist/tree-sitter-typescript-zxjzwt75.wasm +0 -0
- package/dist/tree-sitter-zig-e78zbjpm.wasm +0 -0
- package/dist/tui.js +922 -0
- package/package.json +6 -5
- package/src/format.ts +0 -27
- package/src/index.ts +0 -1
- package/src/login.tsx +0 -297
- package/src/parse.ts +0 -73
- package/src/paths.ts +0 -27
- package/src/store.ts +0 -244
- package/src/tui.tsx +0 -194
- package/src/types.ts +0 -71
package/src/store.ts
DELETED
|
@@ -1,244 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs/promises"
|
|
2
|
-
import path from "node:path"
|
|
3
|
-
import type { OpenAIAuth, StoreEntry, StoreFile, StoreLoad, StoredAccount } from "./types"
|
|
4
|
-
import { authPath, storeDir, storePath } from "./paths"
|
|
5
|
-
import { clean, entryFromAuth, extractAccountId, extractEmail, fallback } from "./parse"
|
|
6
|
-
|
|
7
|
-
function obj(v: unknown) {
|
|
8
|
-
return v && typeof v === "object" ? (v as Record<string, unknown>) : undefined
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function text(v: unknown) {
|
|
12
|
-
return typeof v === "string" && v.trim() ? v : undefined
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
function num(v: unknown) {
|
|
16
|
-
return typeof v === "number" && Number.isFinite(v) ? v : undefined
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function validAuth(v: unknown): v is OpenAIAuth {
|
|
20
|
-
const item = obj(v)
|
|
21
|
-
if (!item) return false
|
|
22
|
-
if (item.type !== "oauth") return false
|
|
23
|
-
if (!text(item.refresh) || !text(item.access) || num(item.expires) === undefined) return false
|
|
24
|
-
if (item.accountId !== undefined && !text(item.accountId)) return false
|
|
25
|
-
if (item.enterpriseUrl !== undefined && !text(item.enterpriseUrl)) return false
|
|
26
|
-
return true
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function validEntry(id: string, v: unknown): v is StoreEntry {
|
|
30
|
-
const item = obj(v)
|
|
31
|
-
if (!item || item.key !== id) return false
|
|
32
|
-
if (item.email !== undefined && !text(item.email)) return false
|
|
33
|
-
if (item.accountId !== undefined && !text(item.accountId)) return false
|
|
34
|
-
if (item.plan !== undefined && !text(item.plan)) return false
|
|
35
|
-
if (num(item.savedAt) === undefined) return false
|
|
36
|
-
if (item.lastUsedAt !== undefined && num(item.lastUsedAt) === undefined) return false
|
|
37
|
-
return validAuth(item.auth)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
async function readJson(file: string) {
|
|
41
|
-
const data = Bun.file(file)
|
|
42
|
-
if (!(await data.exists())) return
|
|
43
|
-
const raw = (await data.text()).trim()
|
|
44
|
-
if (!raw) return
|
|
45
|
-
return JSON.parse(raw) as unknown
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
async function writeJson(file: string, value: unknown) {
|
|
49
|
-
await fs.mkdir(storeDir(), { recursive: true })
|
|
50
|
-
await Bun.write(file, `${JSON.stringify(value, null, 2)}\n`)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function hydrateAccount(id: string, item: StoreEntry): StoredAccount {
|
|
54
|
-
return {
|
|
55
|
-
...item,
|
|
56
|
-
id,
|
|
57
|
-
email: item.email || extractEmail(item.auth),
|
|
58
|
-
accountId: item.accountId || extractAccountId(item.auth),
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function normalizeEntries(entries: Record<string, unknown>) {
|
|
63
|
-
const normalized: Record<string, StoreEntry> = {}
|
|
64
|
-
let changed = false
|
|
65
|
-
|
|
66
|
-
for (const [id, value] of Object.entries(entries)) {
|
|
67
|
-
if (!validEntry(id, value)) {
|
|
68
|
-
const item = obj(value)
|
|
69
|
-
if (!item || !validAuth(item.auth)) {
|
|
70
|
-
changed = true
|
|
71
|
-
continue
|
|
72
|
-
}
|
|
73
|
-
const auth = clean(item.auth)
|
|
74
|
-
const nextKey = fallback(auth.refresh)
|
|
75
|
-
normalized[nextKey] = {
|
|
76
|
-
key: nextKey,
|
|
77
|
-
email: text(item.email) || extractEmail(auth),
|
|
78
|
-
accountId: text(item.accountId) || extractAccountId(auth),
|
|
79
|
-
plan: text(item.plan),
|
|
80
|
-
savedAt: num(item.savedAt) ?? Date.now(),
|
|
81
|
-
...(num(item.lastUsedAt) !== undefined ? { lastUsedAt: num(item.lastUsedAt) } : {}),
|
|
82
|
-
auth,
|
|
83
|
-
}
|
|
84
|
-
changed = true
|
|
85
|
-
continue
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const nextKey = fallback(value.auth.refresh)
|
|
89
|
-
if (nextKey !== id || value.key !== nextKey) changed = true
|
|
90
|
-
normalized[nextKey] = {
|
|
91
|
-
...value,
|
|
92
|
-
key: nextKey,
|
|
93
|
-
auth: clean(value.auth),
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
return { normalized, changed }
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export async function readCurrentAuth() {
|
|
101
|
-
const raw = await readJson(authPath())
|
|
102
|
-
const data = obj(raw)
|
|
103
|
-
if (!data) return
|
|
104
|
-
const auth = data.openai
|
|
105
|
-
if (!validAuth(auth)) return
|
|
106
|
-
return clean(auth)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export async function writeCurrentOpenAI(auth: OpenAIAuth) {
|
|
110
|
-
const raw = (await readJson(authPath())) ?? {}
|
|
111
|
-
const next = obj(raw) ?? {}
|
|
112
|
-
next.openai = clean(auth)
|
|
113
|
-
await fs.mkdir(path.dirname(authPath()), { recursive: true })
|
|
114
|
-
await Bun.write(authPath(), `${JSON.stringify(next, null, 2)}\n`)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export async function readStore(): Promise<StoreLoad> {
|
|
118
|
-
const raw = await readJson(storePath())
|
|
119
|
-
if (raw === undefined) return { ok: false, reason: "missing" }
|
|
120
|
-
const root = obj(raw)
|
|
121
|
-
const map = obj(root?.openai)
|
|
122
|
-
if (!root || root.version !== 1 || !map) return { ok: false, reason: "malformed" }
|
|
123
|
-
const { normalized, changed } = normalizeEntries(map)
|
|
124
|
-
if (changed) {
|
|
125
|
-
await writeStore({ version: 1, openai: normalized })
|
|
126
|
-
}
|
|
127
|
-
return {
|
|
128
|
-
ok: true,
|
|
129
|
-
store: {
|
|
130
|
-
version: 1,
|
|
131
|
-
openai: normalized,
|
|
132
|
-
},
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
export async function writeStore(store: StoreFile) {
|
|
137
|
-
await writeJson(storePath(), store)
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export async function readAllAccounts() {
|
|
141
|
-
const load = await readStore()
|
|
142
|
-
if (!load.ok) return load
|
|
143
|
-
return {
|
|
144
|
-
ok: true as const,
|
|
145
|
-
accounts: Object.entries(load.store.openai)
|
|
146
|
-
.filter(([id, item]) => validEntry(id, item))
|
|
147
|
-
.map(([id, item]) => hydrateAccount(id, item)),
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
export async function pruneInvalidAccounts() {
|
|
152
|
-
const load = await readStore()
|
|
153
|
-
if (!load.ok) return load
|
|
154
|
-
const next = Object.fromEntries(Object.entries(load.store.openai).filter(([id, item]) => validEntry(id, item)))
|
|
155
|
-
if (Object.keys(next).length !== Object.keys(load.store.openai).length) {
|
|
156
|
-
await writeStore({ version: 1, openai: next })
|
|
157
|
-
}
|
|
158
|
-
return {
|
|
159
|
-
ok: true as const,
|
|
160
|
-
accounts: Object.entries(next).map(([id, item]) => hydrateAccount(id, item)),
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
export async function currentAccountId() {
|
|
165
|
-
const auth = await readCurrentAuth()
|
|
166
|
-
if (!auth) return
|
|
167
|
-
return fallback(auth.refresh)
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
function match(list: StoredAccount[], auth: OpenAIAuth) {
|
|
171
|
-
return list.find((item) => {
|
|
172
|
-
if (item.auth.refresh === auth.refresh) return true
|
|
173
|
-
return item.id === fallback(auth.refresh)
|
|
174
|
-
})?.id
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
export async function upsertSavedAccount(auth: OpenAIAuth) {
|
|
178
|
-
const base = entryFromAuth(auth)
|
|
179
|
-
const load = await readStore()
|
|
180
|
-
const store = load.ok ? load.store : { version: 1 as const, openai: {} }
|
|
181
|
-
const list = Object.entries(store.openai)
|
|
182
|
-
const match = list.find(([id, item]) => {
|
|
183
|
-
if (!validEntry(id, item)) return false
|
|
184
|
-
return item.auth.refresh === auth.refresh || id === base.key
|
|
185
|
-
})
|
|
186
|
-
const prev = match?.[1]
|
|
187
|
-
const next: StoreEntry = {
|
|
188
|
-
...base,
|
|
189
|
-
savedAt: prev?.savedAt ?? base.savedAt,
|
|
190
|
-
lastUsedAt: prev?.lastUsedAt,
|
|
191
|
-
}
|
|
192
|
-
const out = Object.fromEntries(
|
|
193
|
-
list.filter(([id]) => id !== match?.[0]).filter(([id, item]) => validEntry(id, item)),
|
|
194
|
-
) as Record<string, StoreEntry>
|
|
195
|
-
out[next.key] = next
|
|
196
|
-
await writeStore({ version: 1, openai: out })
|
|
197
|
-
return { ...next, id: next.key }
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
function sort(list: StoredAccount[], cur?: string) {
|
|
201
|
-
return [...list].sort((a, b) => {
|
|
202
|
-
const ac = a.id === cur ? 1 : 0
|
|
203
|
-
const bc = b.id === cur ? 1 : 0
|
|
204
|
-
if (ac !== bc) return bc - ac
|
|
205
|
-
if ((b.lastUsedAt ?? 0) !== (a.lastUsedAt ?? 0)) return (b.lastUsedAt ?? 0) - (a.lastUsedAt ?? 0)
|
|
206
|
-
if (b.savedAt !== a.savedAt) return b.savedAt - a.savedAt
|
|
207
|
-
return (a.email || a.accountId || a.id).localeCompare(b.email || b.accountId || b.id)
|
|
208
|
-
})
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
export async function listAccounts() {
|
|
212
|
-
const load = await pruneInvalidAccounts()
|
|
213
|
-
if (!load.ok) return load
|
|
214
|
-
const auth = await readCurrentAuth()
|
|
215
|
-
const cur = auth ? match(load.accounts, auth) ?? fallback(auth.refresh) : undefined
|
|
216
|
-
return { ok: true as const, accounts: sort(load.accounts, cur), current: cur }
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
export async function switchAccount(id: string) {
|
|
220
|
-
const load = await readStore()
|
|
221
|
-
if (!load.ok) throw new Error("account store unavailable")
|
|
222
|
-
const item = load.store.openai[id]
|
|
223
|
-
if (!validEntry(id, item)) throw new Error("saved account not found")
|
|
224
|
-
await writeCurrentOpenAI(item.auth)
|
|
225
|
-
await writeStore({
|
|
226
|
-
version: 1,
|
|
227
|
-
openai: {
|
|
228
|
-
...load.store.openai,
|
|
229
|
-
[id]: {
|
|
230
|
-
...item,
|
|
231
|
-
lastUsedAt: Date.now(),
|
|
232
|
-
},
|
|
233
|
-
},
|
|
234
|
-
})
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
export async function deleteSavedAccount(id: string) {
|
|
238
|
-
const load = await readStore()
|
|
239
|
-
if (!load.ok) throw new Error("account store unavailable")
|
|
240
|
-
if (!(id in load.store.openai)) throw new Error("saved account not found")
|
|
241
|
-
const next = { ...load.store.openai }
|
|
242
|
-
delete next[id]
|
|
243
|
-
await writeStore({ version: 1, openai: next })
|
|
244
|
-
}
|
package/src/tui.tsx
DELETED
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
/** @jsxImportSource @opentui/solid */
|
|
2
|
-
import type { TuiCommand, TuiPlugin, TuiPluginModule } from "@opencode-ai/plugin/tui"
|
|
3
|
-
import { accountDescription, accountFooter, accountTitle, loginTitle, logoutTitle } from "./format"
|
|
4
|
-
import { hasLogin, loginOpenAI } from "./login"
|
|
5
|
-
import { deleteSavedAccount, listAccounts, switchAccount } from "./store"
|
|
6
|
-
import type { StoredAccount, SwitchAction, SwitchOption } from "./types"
|
|
7
|
-
|
|
8
|
-
let seq = 0
|
|
9
|
-
|
|
10
|
-
function frame(text: string) {
|
|
11
|
-
return (
|
|
12
|
-
<box paddingLeft={2} paddingRight={2} paddingTop={2} paddingBottom={2}>
|
|
13
|
-
<text>{text}</text>
|
|
14
|
-
</box>
|
|
15
|
-
)
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
async function pick(api: Parameters<TuiPlugin>[0], list: StoredAccount[]) {
|
|
19
|
-
return await new Promise<string | null>((resolve) => {
|
|
20
|
-
api.ui.dialog.replace(
|
|
21
|
-
() => (
|
|
22
|
-
<api.ui.DialogSelect
|
|
23
|
-
title="Remove saved account"
|
|
24
|
-
options={list.map((item) => ({
|
|
25
|
-
title: accountTitle(item),
|
|
26
|
-
value: item.id,
|
|
27
|
-
category: accountDescription(item, false),
|
|
28
|
-
}))}
|
|
29
|
-
onSelect={(item) => resolve(item.value)}
|
|
30
|
-
/>
|
|
31
|
-
),
|
|
32
|
-
() => resolve(null),
|
|
33
|
-
)
|
|
34
|
-
})
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async function confirm(api: Parameters<TuiPlugin>[0], title: string, message: string) {
|
|
38
|
-
return await new Promise<boolean>((resolve) => {
|
|
39
|
-
api.ui.dialog.replace(
|
|
40
|
-
() => (
|
|
41
|
-
<api.ui.DialogConfirm
|
|
42
|
-
title={title}
|
|
43
|
-
message={message}
|
|
44
|
-
onConfirm={() => resolve(true)}
|
|
45
|
-
onCancel={() => resolve(false)}
|
|
46
|
-
/>
|
|
47
|
-
),
|
|
48
|
-
() => resolve(false),
|
|
49
|
-
)
|
|
50
|
-
})
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
async function remove(api: Parameters<TuiPlugin>[0], list: StoredAccount[]) {
|
|
54
|
-
const id = await pick(api, list)
|
|
55
|
-
if (!id) return
|
|
56
|
-
const item = list.find((row) => row.id === id)
|
|
57
|
-
if (!item) return
|
|
58
|
-
const ok = await confirm(api, "Remove saved account", `Remove ${accountTitle(item)} from saved accounts?`)
|
|
59
|
-
if (!ok) return
|
|
60
|
-
try {
|
|
61
|
-
await deleteSavedAccount(id)
|
|
62
|
-
api.ui.toast({ variant: "success", message: "Saved account removed" })
|
|
63
|
-
} catch {
|
|
64
|
-
api.ui.toast({ variant: "error", message: "Failed to remove saved account" })
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function options(list: StoredAccount[], current: string | undefined, canLogin: boolean): SwitchOption[] {
|
|
69
|
-
const rows = list.map((item) => ({
|
|
70
|
-
title: accountTitle(item),
|
|
71
|
-
value: { type: "account", id: item.id } as SwitchAction,
|
|
72
|
-
description: accountDescription(item, item.id === current),
|
|
73
|
-
footer: accountFooter(item.id === current),
|
|
74
|
-
category: "Accounts",
|
|
75
|
-
}))
|
|
76
|
-
return [
|
|
77
|
-
...(canLogin ? [{ title: loginTitle(), value: { type: "login" } as SwitchAction }] : []),
|
|
78
|
-
...rows,
|
|
79
|
-
...(list.length
|
|
80
|
-
? [
|
|
81
|
-
{
|
|
82
|
-
title: logoutTitle(true),
|
|
83
|
-
value: { type: "logout" } as SwitchAction,
|
|
84
|
-
description: "Remove a saved account",
|
|
85
|
-
category: "Actions",
|
|
86
|
-
},
|
|
87
|
-
]
|
|
88
|
-
: []),
|
|
89
|
-
]
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
async function open(api: Parameters<TuiPlugin>[0]) {
|
|
93
|
-
const id = ++seq
|
|
94
|
-
api.ui.dialog.setSize("large")
|
|
95
|
-
api.ui.dialog.replace(() => frame("Loading accounts..."))
|
|
96
|
-
|
|
97
|
-
const [store, canLogin] = await Promise.all([listAccounts(), hasLogin(api)])
|
|
98
|
-
if (id !== seq) return
|
|
99
|
-
|
|
100
|
-
if (!store.ok && store.reason === "malformed") {
|
|
101
|
-
api.ui.toast({ variant: "error", message: "Failed to load account store" })
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const accounts = store.ok ? store.accounts : []
|
|
105
|
-
const current = store.ok ? store.current : undefined
|
|
106
|
-
const rows = options(accounts, current, canLogin)
|
|
107
|
-
|
|
108
|
-
if (!rows.length) {
|
|
109
|
-
api.ui.dialog.replace(() => frame("OpenAI login unavailable and no saved accounts found"))
|
|
110
|
-
return
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (!accounts.length && canLogin) {
|
|
114
|
-
api.ui.dialog.replace(() => (
|
|
115
|
-
<api.ui.DialogSelect
|
|
116
|
-
title="Switch OpenAI account"
|
|
117
|
-
options={rows}
|
|
118
|
-
placeholder="Search"
|
|
119
|
-
onSelect={(item) => void act(api, item.value, accounts)}
|
|
120
|
-
/>
|
|
121
|
-
))
|
|
122
|
-
return
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
api.ui.dialog.replace(() => (
|
|
126
|
-
<api.ui.DialogSelect
|
|
127
|
-
title="Switch OpenAI account"
|
|
128
|
-
options={rows}
|
|
129
|
-
placeholder="Search"
|
|
130
|
-
current={current ? ({ type: "account", id: current } as SwitchAction) : undefined}
|
|
131
|
-
onSelect={(item) => void act(api, item.value, accounts)}
|
|
132
|
-
/>
|
|
133
|
-
))
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
async function act(api: Parameters<TuiPlugin>[0], action: SwitchAction, list: StoredAccount[]) {
|
|
137
|
-
if (action.type === "login") {
|
|
138
|
-
const ok = await loginOpenAI(api)
|
|
139
|
-
if (ok) {
|
|
140
|
-
api.ui.toast({ variant: "success", message: "Account saved" })
|
|
141
|
-
await open(api)
|
|
142
|
-
}
|
|
143
|
-
return
|
|
144
|
-
}
|
|
145
|
-
if (action.type === "logout") {
|
|
146
|
-
await remove(api, list)
|
|
147
|
-
await open(api)
|
|
148
|
-
return
|
|
149
|
-
}
|
|
150
|
-
try {
|
|
151
|
-
await switchAccount(action.id)
|
|
152
|
-
} catch {
|
|
153
|
-
api.ui.toast({ variant: "error", message: "Failed to switch account" })
|
|
154
|
-
return
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
try {
|
|
158
|
-
const client = api.client as typeof api.client & {
|
|
159
|
-
sync?: { bootstrap?: () => Promise<void> }
|
|
160
|
-
}
|
|
161
|
-
if (typeof api.client.instance.dispose === "function") {
|
|
162
|
-
await api.client.instance.dispose()
|
|
163
|
-
}
|
|
164
|
-
if (typeof client.sync?.bootstrap === "function") {
|
|
165
|
-
await client.sync.bootstrap()
|
|
166
|
-
}
|
|
167
|
-
api.ui.toast({ variant: "success", message: "Switched OpenAI account" })
|
|
168
|
-
api.ui.dialog.clear()
|
|
169
|
-
} catch {
|
|
170
|
-
api.ui.toast({
|
|
171
|
-
variant: "warning",
|
|
172
|
-
message: "Account file was switched, but session refresh failed",
|
|
173
|
-
})
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
const tui: TuiPlugin = async (api) => {
|
|
178
|
-
api.command.register(() => [
|
|
179
|
-
{
|
|
180
|
-
title: "Switch OpenAI account",
|
|
181
|
-
value: "openai.switch",
|
|
182
|
-
description: "Login, switch, or remove saved OpenAI accounts",
|
|
183
|
-
slash: { name: "switch" },
|
|
184
|
-
onSelect: () => {
|
|
185
|
-
void open(api)
|
|
186
|
-
},
|
|
187
|
-
} satisfies TuiCommand,
|
|
188
|
-
])
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
export default {
|
|
192
|
-
id: "harars.switch-auth",
|
|
193
|
-
tui,
|
|
194
|
-
} satisfies TuiPluginModule & { id: string }
|
package/src/types.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
export type OpenAIAuth = {
|
|
2
|
-
type: "oauth"
|
|
3
|
-
refresh: string
|
|
4
|
-
access: string
|
|
5
|
-
expires: number
|
|
6
|
-
accountId?: string
|
|
7
|
-
enterpriseUrl?: string
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export type StoreEntry = {
|
|
11
|
-
key: string
|
|
12
|
-
email?: string
|
|
13
|
-
accountId?: string
|
|
14
|
-
plan?: string
|
|
15
|
-
savedAt: number
|
|
16
|
-
lastUsedAt?: number
|
|
17
|
-
auth: OpenAIAuth
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export type StoreFile = {
|
|
21
|
-
version: 1
|
|
22
|
-
openai: Record<string, StoreEntry>
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export type StoredAccount = StoreEntry & {
|
|
26
|
-
id: string
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export type SwitchAction =
|
|
30
|
-
| { type: "login" }
|
|
31
|
-
| { type: "account"; id: string }
|
|
32
|
-
| { type: "logout" }
|
|
33
|
-
|
|
34
|
-
export type SwitchOption = {
|
|
35
|
-
title: string
|
|
36
|
-
value: SwitchAction
|
|
37
|
-
description?: string
|
|
38
|
-
category?: string
|
|
39
|
-
footer?: string
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export type Claims = Record<string, unknown>
|
|
43
|
-
|
|
44
|
-
export type StoreLoad =
|
|
45
|
-
| { ok: true; store: StoreFile }
|
|
46
|
-
| { ok: false; reason: "malformed" | "missing" }
|
|
47
|
-
|
|
48
|
-
export type ProviderPrompt = {
|
|
49
|
-
type: "text" | "select"
|
|
50
|
-
key: string
|
|
51
|
-
message: string
|
|
52
|
-
placeholder?: string
|
|
53
|
-
options?: Array<{ label: string; value: string; hint?: string }>
|
|
54
|
-
when?: {
|
|
55
|
-
key: string
|
|
56
|
-
op: "eq" | "neq"
|
|
57
|
-
value: string
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export type ProviderMethod = {
|
|
62
|
-
type: "oauth" | "api"
|
|
63
|
-
label: string
|
|
64
|
-
prompts?: ProviderPrompt[]
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export type OAuthAuthz = {
|
|
68
|
-
url: string
|
|
69
|
-
method: "auto" | "code"
|
|
70
|
-
instructions: string
|
|
71
|
-
}
|