Files
Investidor-V2/resources/js/lib/profile-json.ts
T

75 lines
2.5 KiB
TypeScript

export class ProfileValidationError extends Error {
constructor(
message: string,
public readonly fields: Record<string, string>,
public readonly reauthenticate = false,
public readonly status: number | null = null,
) {
super(message);
}
}
export async function profileJson(
url: string,
data: object = {},
method: 'GET' | 'POST' = 'POST',
) {
let token = '';
if (method !== 'GET') {
const cookie =
typeof document === 'undefined'
? undefined
: document.cookie
.split(';')
.map((value) => value.trim())
.find((value) => value.startsWith('XSRF-TOKEN='));
try {
token = cookie ? decodeURIComponent(cookie.slice(11)) : '';
} catch {
throw new ProfileValidationError(
'A sessão não pôde ser validada. Actualize a página e tente novamente.',
{},
);
}
}
const response = await fetch(url, {
method,
credentials: 'same-origin',
headers: {
Accept: 'application/json',
...(typeof FormData !== 'undefined' && data instanceof FormData
? {}
: { 'Content-Type': 'application/json' }),
...(method === 'GET' ? {} : { 'X-XSRF-TOKEN': token }),
},
...(method === 'GET'
? {}
: {
body:
typeof FormData !== 'undefined' &&
data instanceof FormData
? data
: JSON.stringify(data),
}),
});
const result = await response.json().catch(() => null);
const reauthenticate =
response.headers.get('X-Portal-Reauthentication') === 'required';
if (!response.ok || (result === null && response.status !== 204))
throw new ProfileValidationError(
typeof result?.message === 'string'
? result.message
: response.status === 419
? 'A sessão expirou. Actualize a página e tente novamente.'
: 'A ação não foi concluída. Tente novamente.',
Object.fromEntries(
Object.entries(result?.errors ?? {}).map(([key, value]) => [
key,
Array.isArray(value) ? value.join(' ') : String(value),
]),
),
reauthenticate,
response.status,
);
return result;
}