Files
smart-home-tablet/lib/tools/_http.ts
Cosmo 7b5f76576f
All checks were successful
Deploy / deploy (push) Successful in 1m25s
refactor: tool plugin registry - each tool in separate file
2026-04-30 20:58:11 +00:00

55 lines
1.6 KiB
TypeScript

/**
* Shared HTTP helpers for tool executors.
* Calls loopback tablet API routes with Bearer + x-voice-internal headers.
*/
export class ToolHttpError extends Error {
constructor(public status: number, public body: string) {
super(`tool_http_${status}`)
}
}
const baseUrl = () => `http://localhost:${process.env.PORT || '3000'}`
export function headers(): Record<string, string> {
const key = process.env.VOICE_API_KEY || ''
return {
Authorization: `Bearer ${key}`,
'x-voice-internal': key,
'Content-Type': 'application/json',
}
}
export async function tabletGet(path: string, params?: Record<string, string>): Promise<any> {
const url = new URL(`${baseUrl()}${path}`)
if (params) {
for (const [k, v] of Object.entries(params)) {
if (v !== undefined && v !== '') url.searchParams.set(k, v)
}
}
const r = await fetch(url, { headers: headers(), cache: 'no-store' })
if (!r.ok) throw new ToolHttpError(r.status, await r.text().catch(() => ''))
return r.json()
}
export async function tabletJson(
method: 'POST' | 'PUT' | 'DELETE',
path: string,
body?: any,
params?: Record<string, string>,
): Promise<any> {
const url = new URL(`${baseUrl()}${path}`)
if (params) {
for (const [k, v] of Object.entries(params)) {
if (v !== undefined && v !== '') url.searchParams.set(k, v)
}
}
const r = await fetch(url, {
method,
headers: headers(),
body: body !== undefined ? JSON.stringify(body) : undefined,
})
if (!r.ok) throw new ToolHttpError(r.status, await r.text().catch(() => ''))
return r.json()
}