UNPKG

ra-data-graphql

Version:

A GraphQL data provider for react-admin

135 lines 6.34 kB
import merge from 'lodash/merge.js'; import get from 'lodash/get.js'; import pluralize from 'pluralize'; import { HttpError, GET_LIST, GET_ONE, GET_MANY, GET_MANY_REFERENCE, CREATE, UPDATE, DELETE, DELETE_MANY, UPDATE_MANY, } from 'ra-core'; import buildApolloClient from "./buildApolloClient.js"; import { QUERY_TYPES as INNER_QUERY_TYPES, MUTATION_TYPES as INNER_MUTATION_TYPES, ALL_TYPES as INNER_ALL_TYPES, } from "./constants.js"; import { introspectSchema, } from "./introspection.js"; export * from "./introspection.js"; export const QUERY_TYPES = INNER_QUERY_TYPES; export const MUTATION_TYPES = INNER_MUTATION_TYPES; export const ALL_TYPES = INNER_ALL_TYPES; /** * Map dataProvider method names to GraphQL queries and mutations * * @example for the Customer resource: * dataProvider.getList() // query allCustomers() { ... } * dataProvider.getOne() // query Customer($id: id) { ... } * dataProvider.getMany() // query allCustomers($filter: { ids: [ids] }) { ... } * dataProvider.getManyReference() // query allCustomers($filter: { [target]: [id] }) { ... } * dataProvider.create() // mutation createCustomer($firstName: firstName, $lastName: lastName, ...) { ... } * dataProvider.update() // mutation updateCustomer($id: id, firstName: firstName, $lastName: lastName, ...) { ... } * dataProvider.delete() // mutation deleteCustomer($id: id) { ... } * // note that updateMany and deleteMany aren't mapped in this adapter */ export const defaultOptions = { resolveIntrospection: introspectSchema, introspection: { operationNames: { [GET_LIST]: resource => `all${pluralize(resource.name)}`, [GET_ONE]: resource => `${resource.name}`, [GET_MANY]: resource => `all${pluralize(resource.name)}`, [GET_MANY_REFERENCE]: resource => `all${pluralize(resource.name)}`, [CREATE]: resource => `create${resource.name}`, [UPDATE]: resource => `update${resource.name}`, [DELETE]: resource => `delete${resource.name}`, }, exclude: undefined, include: undefined, }, }; const getOptions = (options, raFetchMethod, resource) => { if (typeof options === 'function') { return options(resource, raFetchMethod); } return options; }; const buildGraphQLProvider = (options) => { const { client: clientObject, clientOptions, introspection, resolveIntrospection, buildQuery: buildQueryFactory, override = {}, ...otherOptions } = merge({}, defaultOptions, options); if (Object.keys(override).length > 0 && process.env.NODE_ENV === 'production') { console.warn('The override option is deprecated. You should instead wrap the buildQuery function provided by the dataProvider you use.'); } const client = clientObject || buildApolloClient(clientOptions); let introspectionResults; let introspectionResultsPromise; const callApollo = async (raFetchMethod, resource, params) => { if (introspection) { if (!introspectionResultsPromise) { introspectionResultsPromise = resolveIntrospection(client, introspection); } introspectionResults = await introspectionResultsPromise; } const buildQuery = buildQueryFactory(introspectionResults); const overriddenBuildQuery = get(override, `${resource}.${raFetchMethod}`); const { parseResponse, ...query } = overriddenBuildQuery ? { ...buildQuery(raFetchMethod, resource, params), ...overriddenBuildQuery(params), } : buildQuery(raFetchMethod, resource, params); const operation = getQueryOperation(query.query); if (operation === 'query') { const apolloQuery = { ...query, fetchPolicy: 'network-only', ...getOptions(otherOptions.query, raFetchMethod, resource), }; apolloQuery.context = merge({ fetchOptions: { signal: params?.signal, }, }, apolloQuery.context); return (client // @ts-ignore .query(apolloQuery) .then(response => parseResponse(response)) .catch(handleError)); } const apolloQuery = { mutation: query.query, variables: query.variables, ...getOptions(otherOptions.mutation, raFetchMethod, resource), }; return (client // @ts-ignore .mutate(apolloQuery) .then(parseResponse) .catch(handleError)); }; const raDataProvider = { create: (resource, params) => callApollo(CREATE, resource, params), delete: (resource, params) => callApollo(DELETE, resource, params), deleteMany: (resource, params) => callApollo(DELETE_MANY, resource, params), getList: (resource, params) => callApollo(GET_LIST, resource, params), getMany: (resource, params) => callApollo(GET_MANY, resource, params), getManyReference: (resource, params) => callApollo(GET_MANY_REFERENCE, resource, params), getOne: (resource, params) => callApollo(GET_ONE, resource, params), update: (resource, params) => callApollo(UPDATE, resource, params), updateMany: (resource, params) => callApollo(UPDATE_MANY, resource, params), getIntrospection: () => { if (introspection) { if (!introspectionResultsPromise) { introspectionResultsPromise = resolveIntrospection(client, introspection); } return introspectionResultsPromise; } }, client, }; return raDataProvider; }; const handleError = (error) => { if (error?.networkError) { throw new HttpError(error?.networkError?.message, error?.networkError?.statusCode); } throw new HttpError(error.message, 200, error); }; const getQueryOperation = query => { if (query && query.definitions && query.definitions.length > 0) { return query.definitions[0].operation; } throw new Error('Unable to determine the query operation'); }; export default buildGraphQLProvider; //# sourceMappingURL=index.js.map