UNPKG

polen

Version:

A framework for delightful GraphQL developer portals

95 lines (80 loc) 3.04 kB
import type { FormattedExecutionResult, GraphQLFormattedError } from 'graphql' // import { CONTENT_TYPE_GQL, CONTENT_TYPE_JSON } from '../../http.js' import { Rec } from '@wollybeard/kit' export interface RequestConfig { query: string variables?: Record<string, unknown> // Variables operationName?: string } export const parseExecutionResult = (result: unknown): FormattedExecutionResult => { if (typeof result !== `object` || result === null) { throw new Error(`Invalid execution result: result is not object`) } if (`errors` in result) { if ( !Array.isArray(result.errors) || result.errors.some( error => !(Rec.is(error) && `message` in error && typeof error[`message`] === `string`), ) ) { throw new Error(`Invalid execution result: errors is not array of formatted errors`) // prettier-ignore } result.errors.forEach(maybeError => { if (!isFormattedError(maybeError)) { throw new Error(`Invalid value in errors array.`) // prettier-ignore } }) } // todo add test coverage for case of null. @see https://github.com/graffle-js/graffle/issues/739 if (`data` in result) { if (!Rec.is(result.data) && result.data !== null) { throw new Error(`Invalid execution result: data is not plain object`) // prettier-ignore } } if (`extensions` in result) { if (!Rec.is(result.extensions)) { throw new Error(`Invalid execution result: extensions is not plain object`) // prettier-ignore } } return result } // /** // * @see https://graphql.github.io/graphql-over-http/draft/#sec-Media-Types // */ // export const CONTENT_TYPE_REC = CONTENT_TYPE_JSON // /** // * @see https://graphql.github.io/graphql-over-http/draft/#sec-Accept // * @see https://graphql.github.io/graphql-over-http/draft/#sec-Legacy-Watershed // */ // export const ACCEPT_REC = `${CONTENT_TYPE_GQL}; charset=utf-8, ${CONTENT_TYPE_JSON}; charset=utf-8` // export const postRequestHeadersRec = { // accept: ACCEPT_REC, // 'content-type': CONTENT_TYPE_REC, // } // export const getRequestHeadersRec = { // accept: ACCEPT_REC, // } export const getRequestEncodeSearchParameters = ( request: RequestConfig, ): Record<string, string> => { return { query: request.query, ...(request.variables ? { variables: JSON.stringify(request.variables) } : {}), ...(request.operationName ? { operationName: request.operationName } : {}), } } export type getRequestEncodeSearchParameters = typeof getRequestEncodeSearchParameters export const postRequestEncodeBody = (input: RequestConfig): BodyInit => { return JSON.stringify({ query: input.query, variables: input.variables, operationName: input.operationName, }) } export type postRequestEncodeBody = typeof postRequestEncodeBody // todo make this more robust export const isFormattedError = (error: unknown): error is GraphQLFormattedError => { return Rec.is(error) && `message` in error && typeof error[`message`] === `string` }