100 lines
3.1 KiB
TypeScript
100 lines
3.1 KiB
TypeScript
/** PocketBase REST(与 payjsapi 同源实例 https://pocketbase.hackrobot.cn) */
|
||
|
||
export const POCKETBASE_URL = 'https://pocketbase.hackrobot.cn'
|
||
|
||
export type PbUserRecord = {
|
||
id: string
|
||
email?: string
|
||
name?: string
|
||
live_allowed?: boolean
|
||
[k: string]: unknown
|
||
}
|
||
|
||
export type PbAuthResponse = {
|
||
token: string
|
||
record: PbUserRecord
|
||
}
|
||
|
||
function joinPb(path: string): string {
|
||
const b = POCKETBASE_URL.replace(/\/$/, '')
|
||
const p = path.startsWith('/') ? path : `/${path}`
|
||
return `${b}${p}`
|
||
}
|
||
|
||
export async function pbAuthWithPassword(email: string, password: string): Promise<PbAuthResponse> {
|
||
const res = await fetch(joinPb('/api/collections/users/auth-with-password'), {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ identity: email.trim(), password }),
|
||
})
|
||
const data = (await res.json().catch(() => ({}))) as Record<string, unknown>
|
||
if (!res.ok) {
|
||
const msg =
|
||
typeof data.message === 'string'
|
||
? data.message
|
||
: typeof data.data === 'object' && data.data && typeof (data.data as { message?: string }).message === 'string'
|
||
? (data.data as { message: string }).message
|
||
: `登录失败 (${res.status})`
|
||
throw new Error(msg)
|
||
}
|
||
const token = String(data.token ?? '')
|
||
const record = data.record as PbUserRecord | undefined
|
||
if (!token || !record?.id) throw new Error('登录响应异常')
|
||
return { token, record }
|
||
}
|
||
|
||
export async function pbAuthRefresh(token: string): Promise<PbAuthResponse> {
|
||
const res = await fetch(joinPb('/api/collections/users/auth-refresh'), {
|
||
method: 'POST',
|
||
headers: { Authorization: `Bearer ${token.trim()}` },
|
||
})
|
||
const data = (await res.json().catch(() => ({}))) as Record<string, unknown>
|
||
if (!res.ok) {
|
||
throw new Error(typeof data.message === 'string' ? data.message : `刷新失败 (${res.status})`)
|
||
}
|
||
const newToken = String(data.token ?? '')
|
||
const record = data.record as PbUserRecord | undefined
|
||
if (!newToken || !record?.id) throw new Error('刷新响应异常')
|
||
return { token: newToken, record }
|
||
}
|
||
|
||
export function isLiveAllowed(record: PbUserRecord | null | undefined): boolean {
|
||
if (!record) return false
|
||
return record.live_allowed !== false
|
||
}
|
||
|
||
export type LiveSessionPayload = {
|
||
process: string
|
||
event: 'start' | 'restart' | 'stop'
|
||
machine: Record<string, unknown>
|
||
}
|
||
|
||
/** 需在 PocketBase 新建集合 `live_sessions`,见项目内说明 */
|
||
export async function pbCreateLiveSession(
|
||
token: string,
|
||
userId: string,
|
||
payload: LiveSessionPayload,
|
||
): Promise<void> {
|
||
const res = await fetch(joinPb('/api/collections/live_sessions/records'), {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
Authorization: `Bearer ${token.trim()}`,
|
||
},
|
||
body: JSON.stringify({
|
||
user: userId,
|
||
process: payload.process,
|
||
event: payload.event,
|
||
machine: payload.machine,
|
||
}),
|
||
})
|
||
if (!res.ok) {
|
||
const t = await res.text()
|
||
if (res.status === 404) {
|
||
console.warn('[live_sessions] 集合未创建或规则未放行:', t)
|
||
return
|
||
}
|
||
console.warn('[live_sessions] 写入失败:', res.status, t)
|
||
}
|
||
}
|