ecf52d961a
nwClient inclui o header x-nw-clinica (id do SCOREODONTO_ACTIVE_WORKSPACE) e o proxy REST o encaminha ao motor — assim as ações manuais escopam a ponte de agenda para a clínica do workspace ativo (por-requisição). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
54 lines
2.1 KiB
TypeScript
54 lines
2.1 KiB
TypeScript
// Cliente base do satélite NewWhats → /api/nw/v1/* (proxy do backend → motor
|
|
// /api/ext/v1/*). Auth: Bearer do scoreodonto (localStorage SCOREODONTO_AUTH_TOKEN).
|
|
// Retorna JSON já parseado; em erro, lança Error com `.response = { status, data }`
|
|
// (mesmo shape do axios, que o código portado do motor espera).
|
|
const API: string = (import.meta as any).env?.VITE_API_URL || '/api';
|
|
const TOKEN_KEY = 'SCOREODONTO_AUTH_TOKEN';
|
|
|
|
export function nwToken(): string | null {
|
|
try { return localStorage.getItem(TOKEN_KEY); } catch { return null; }
|
|
}
|
|
|
|
// Clínica do workspace ativo — escopo por-requisição (modelo de canal).
|
|
function activeClinicaId(): string | null {
|
|
try { return JSON.parse(localStorage.getItem('SCOREODONTO_ACTIVE_WORKSPACE') || '{}')?.id || null; } catch { return null; }
|
|
}
|
|
|
|
function authHeaders(extra?: Record<string, string>): Record<string, string> {
|
|
const t = nwToken();
|
|
const c = activeClinicaId();
|
|
return {
|
|
...(t ? { Authorization: `Bearer ${t}` } : {}),
|
|
...(c ? { 'x-nw-clinica': c } : {}),
|
|
...(extra || {}),
|
|
};
|
|
}
|
|
|
|
async function req(method: string, path: string, body?: any): Promise<any> {
|
|
const isForm = typeof FormData !== 'undefined' && body instanceof FormData;
|
|
const res = await fetch(`${API}/nw/v1${path}`, {
|
|
method,
|
|
headers: authHeaders(isForm ? undefined : (body != null ? { 'Content-Type': 'application/json' } : undefined)),
|
|
body: body == null ? undefined : (isForm ? body : JSON.stringify(body)),
|
|
});
|
|
const text = await res.text();
|
|
let data: any = null;
|
|
try { data = text ? JSON.parse(text) : null; } catch { data = text; }
|
|
if (!res.ok) {
|
|
const err: any = new Error((data && data.error) || `${res.status}`);
|
|
err.response = { status: res.status, data };
|
|
throw err;
|
|
}
|
|
return data;
|
|
}
|
|
|
|
export const nw = {
|
|
get: (p: string) => req('GET', p),
|
|
post: (p: string, body?: any) => req('POST', p, body),
|
|
put: (p: string, body?: any) => req('PUT', p, body),
|
|
patch: (p: string, body?: any) => req('PATCH', p, body),
|
|
delete: (p: string) => req('DELETE', p),
|
|
// URL base ('/api' relativo ou absoluta) — usada pelo socketService p/ o WS.
|
|
base: () => API,
|
|
};
|