@elastic-suite/gally-admin-shared
Version:
Shared package for gally admin BO
63 lines (58 loc) • 1.53 kB
text/typescript
import {
authErrorCodes,
authHeader,
contentTypeHeader,
gqlUrl,
languageHeader,
tokenStorageKey,
} from '../constants'
import { IGraphql, IGraphqlError } from '../types'
import { fetchJson } from './fetch'
import { AuthError } from './network'
import { storageGet, storageRemove } from './storage'
export class GraphqlError extends Error {
errors: IGraphqlError[]
constructor(errors: IGraphqlError[]) {
super(errors[0].message)
this.errors = errors
}
}
export function isGraphqlError<T extends object>(
json: T | IGraphqlError[]
): json is IGraphqlError[] {
return 'errors' in json
}
export function fetchGraphql<T>(
language: string,
query: string,
variables?: Record<string, unknown>,
options: RequestInit = {},
secure = true
): Promise<T> {
const headers: Record<string, string> = {
[languageHeader]: language,
[contentTypeHeader]: 'application/json',
...(options.headers as Record<string, string>),
}
const token = storageGet(tokenStorageKey)
if (secure && token) {
headers[authHeader] = `Bearer ${token}`
}
return fetchJson<IGraphql<T>>(gqlUrl, {
body: JSON.stringify({
query,
variables,
}),
method: 'POST',
...options,
headers,
}).then(({ json, response }) => {
if (isGraphqlError(json)) {
throw new GraphqlError(json.errors)
} else if (authErrorCodes.includes(response.status)) {
storageRemove(tokenStorageKey)
throw new AuthError('Unauthorized/Forbidden')
}
return json.data
})
}