@graphql-tools/load
Version:
A set of utils for faster development of GraphQL tools
106 lines (105 loc) • 3.58 kB
JavaScript
import { GraphQLSchema, Source as GraphQLSource, lexicographicSortSchema, print, } from 'graphql';
import { extractExtensionsFromSchema, mergeSchemas, } from '@graphql-tools/schema';
import { getResolversFromSchema, } from '@graphql-tools/utils';
import { OPERATION_KINDS } from './documents.js';
import { loadTypedefs, loadTypedefsSync, } from './load-typedefs.js';
/**
* Asynchronously loads a schema from the provided pointers.
* @param schemaPointers Pointers to the sources to load the schema from
* @param options Additional options
*/
export async function loadSchema(schemaPointers, options) {
const sources = await loadTypedefs(schemaPointers, {
...options,
filterKinds: OPERATION_KINDS,
});
return getSchemaFromSources(sources, options);
}
/**
* Synchronously loads a schema from the provided pointers.
* @param schemaPointers Pointers to the sources to load the schema from
* @param options Additional options
*/
export function loadSchemaSync(schemaPointers, options) {
const sources = loadTypedefsSync(schemaPointers, {
filterKinds: OPERATION_KINDS,
...options,
});
return getSchemaFromSources(sources, options);
}
function includeSources(schema, sources) {
const finalSources = [];
for (const source of sources) {
if (source.rawSDL) {
finalSources.push(new GraphQLSource(source.rawSDL, source.location));
}
else if (source.document) {
finalSources.push(new GraphQLSource(print(source.document), source.location));
}
}
schema.extensions = {
...schema.extensions,
sources: finalSources,
extendedSources: sources,
};
}
function getSchemaFromSources(sources, options) {
if (sources.length === 1 &&
sources[0].schema != null &&
options.typeDefs == null &&
options.resolvers == null) {
return applySchemaSort(sources[0].schema, options);
}
const { typeDefs, resolvers, schemaExtensions } = collectSchemaParts(sources);
const schema = mergeSchemas({
...options,
typeDefs,
resolvers,
schemaExtensions,
// mergeTypeDefs also honors `sort` and would reorder fields and enum values.
...(options.sortMode === 'typesOnly' ? { sort: false } : {}),
});
if (options?.includeSources) {
includeSources(schema, sources);
}
return applySchemaSort(schema, options);
}
function applySchemaSort(schema, options) {
if (!options.sort) {
return schema;
}
if (options.sortMode === 'typesOnly') {
return sortSchemaTypesOnly(schema);
}
return lexicographicSortSchema(schema);
}
function sortSchemaTypesOnly(schema) {
const schemaConfig = schema.toConfig();
return new GraphQLSchema({
...schemaConfig,
types: [...schemaConfig.types].sort((typeA, typeB) => typeA.name.localeCompare(typeB.name)),
});
}
function collectSchemaParts(sources) {
const typeDefs = [];
const resolvers = [];
const schemaExtensions = [];
for (const source of sources) {
if (source.schema) {
typeDefs.push(source.schema);
resolvers.push(getResolversFromSchema(source.schema));
schemaExtensions.push(extractExtensionsFromSchema(source.schema));
}
else {
const typeDef = source.document || source.rawSDL;
if (typeDef) {
typeDefs.push(typeDef);
}
}
}
return {
typeDefs,
resolvers,
schemaExtensions,
};
}