UNPKG

ra-data-graphql

Version:

A GraphQL data provider for react-admin

79 lines 2.88 kB
import { getIntrospectionQuery, } from 'graphql'; import { gql } from '@apollo/client'; import { ALL_TYPES } from "./constants.js"; /** * @param {ApolloClient} client The Apollo client * @param {Object} options The introspection options */ export const introspectSchema = async (client, options) => { const schema = options.schema ? options.schema : await fetchSchema(client); const queries = getQueriesFromSchema(schema); const types = getTypesFromSchema(schema); const resources = getResources(types, queries, options); return { types, queries, resources, schema, }; }; const fetchSchema = (client) => client .query({ fetchPolicy: 'network-only', query: gql ` ${getIntrospectionQuery()} `, }) .then(({ data: { __schema } }) => __schema); const getQueriesFromSchema = (schema) => schema.types.reduce((acc, type) => { if (type.name !== schema.queryType?.name && type.name !== schema.mutationType?.name && type.fields) { return acc; } return [...acc, ...(type.fields || [])]; }, []); const getTypesFromSchema = (schema) => schema.types.filter(type => type.name !== (schema.queryType && schema.queryType.name) && type.name !== (schema.mutationType && schema.mutationType.name)); const getResources = (types, queries, options) => { const filteredResources = types.filter(type => isResource(type, queries, options)); return filteredResources.map(type => buildResource(type, queries, options)); }; const isResource = (type, queries, options) => { if (isResourceIncluded(type, options)) return true; if (isResourceExcluded(type, options)) return false; const operations = Object.keys(options.operationNames).map(operation => options.operationNames[operation](type)); const hasAtLeastOneOperation = operations.some(operation => queries.find(({ name }) => name === operation)); return hasAtLeastOneOperation; }; export const isResourceIncluded = (type, { include } = {}) => { if (Array.isArray(include)) { return include.includes(type.name); } if (typeof include === 'function') { return include(type); } return false; }; export const isResourceExcluded = (type, { exclude } = {}) => { if (Array.isArray(exclude)) { return exclude.includes(type.name); } if (typeof exclude === 'function') { return exclude(type); } return false; }; const buildResource = (type, queries, options) => ALL_TYPES.reduce((acc, raFetchMethod) => { const query = queries.find(({ name }) => options.operationNames[raFetchMethod] && name === options.operationNames[raFetchMethod](type)); if (!query) return acc; return { ...acc, [raFetchMethod]: query, }; }, { type }); //# sourceMappingURL=introspection.js.map