60 lines
1.4 KiB
TypeScript
60 lines
1.4 KiB
TypeScript
export const getApiBase = () => process.env.NEXT_PUBLIC_API_BASE ?? '/api'
|
|
|
|
export const getToken = () => {
|
|
if (typeof window === 'undefined') return null
|
|
return window.localStorage.getItem('magent_token')
|
|
}
|
|
|
|
export const setToken = (token: string) => {
|
|
if (typeof window === 'undefined') return
|
|
window.localStorage.setItem('magent_token', token)
|
|
}
|
|
|
|
export const clearToken = () => {
|
|
if (typeof window === 'undefined') return
|
|
window.localStorage.removeItem('magent_token')
|
|
}
|
|
|
|
export const authFetch = (input: RequestInfo | URL, init?: RequestInit) => {
|
|
const token = getToken()
|
|
const headers = new Headers(init?.headers || {})
|
|
if (token) {
|
|
headers.set('Authorization', `Bearer ${token}`)
|
|
}
|
|
return fetch(input, { ...init, headers })
|
|
}
|
|
|
|
export class UnauthorizedError extends Error {
|
|
constructor() {
|
|
super('Unauthorized')
|
|
this.name = 'UnauthorizedError'
|
|
}
|
|
}
|
|
|
|
export class ForbiddenError extends Error {
|
|
constructor() {
|
|
super('Forbidden')
|
|
this.name = 'ForbiddenError'
|
|
}
|
|
}
|
|
|
|
export const authFetchOrThrow = async (input: RequestInfo | URL, init?: RequestInit) => {
|
|
const response = await authFetch(input, init)
|
|
if (response.status === 401) {
|
|
clearToken()
|
|
throw new UnauthorizedError()
|
|
}
|
|
if (response.status === 403) {
|
|
throw new ForbiddenError()
|
|
}
|
|
return response
|
|
}
|
|
|
|
export const readResponseText = async (response: Response) => {
|
|
try {
|
|
return (await response.text()).trim()
|
|
} catch {
|
|
return ''
|
|
}
|
|
}
|