Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@graphql-tools/schema

Package Overview
Dependencies
Maintainers
3
Versions
1127
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@graphql-tools/schema - npm Package Compare versions

Comparing version 5.0.1-alpha-b4a3ab5.0 to 5.0.1-alpha-b5658b2.0

2

addCatchUndefinedToSchema.d.ts
import { GraphQLSchema } from 'graphql';
export declare function addCatchUndefinedToSchema(schema: GraphQLSchema): void;
export declare function addCatchUndefinedToSchema(schema: GraphQLSchema): GraphQLSchema;
import { GraphQLSchema } from 'graphql';
import { ILogger } from './types';
export declare function addErrorLoggingToSchema(schema: GraphQLSchema, logger?: ILogger): void;
export declare function addErrorLoggingToSchema(schema: GraphQLSchema, logger?: ILogger): GraphQLSchema;
import { GraphQLSchema, GraphQLFieldResolver } from 'graphql';
export declare function addSchemaLevelResolver(schema: GraphQLSchema, fn: GraphQLFieldResolver<any, any>): void;
export declare function addSchemaLevelResolver(schema: GraphQLSchema, fn: GraphQLFieldResolver<any, any>): GraphQLSchema;
import { GraphQLSchema } from 'graphql';
import { IDirectiveResolvers } from '@graphql-tools/utils';
export declare function attachDirectiveResolvers(schema: GraphQLSchema, directiveResolvers: IDirectiveResolvers): void;
export declare function attachDirectiveResolvers(schema: GraphQLSchema, directiveResolvers: IDirectiveResolvers): GraphQLSchema;
import { GraphQLSchema } from 'graphql';
import { IResolvers } from '@graphql-tools/utils';
export declare function extendResolversFromInterfaces(schema: GraphQLSchema, resolvers: IResolvers): {};
export declare function extendResolversFromInterfaces(schema: GraphQLSchema, resolvers: IResolvers): IResolvers;

@@ -12,20 +12,21 @@ 'use strict';

// TODO test that schema is a schema, fn is a function
const rootTypes = [schema.getQueryType(), schema.getMutationType(), schema.getSubscriptionType()].filter(x => Boolean(x));
rootTypes.forEach(type => {
if (type != null) {
const fnToRunOnlyOnce = runAtMostOncePerRequest(fn);
return utils.mapSchema(schema, {
[utils.MapperKind.ROOT_FIELD]: (fieldConfig, _fieldName, typeName, schema) => {
// XXX this should run at most once per request to simulate a true root resolver
// for graphql-js this is an approximation that works with queries but not mutations
const rootResolveFn = runAtMostOncePerRequest(fn);
const fields = type.getFields();
Object.keys(fields).forEach(fieldName => {
// XXX if the type is a subscription, a same query AST will be ran multiple times so we
// deactivate here the runOnce if it's a subscription. This may not be optimal though...
if (type === schema.getSubscriptionType()) {
fields[fieldName].resolve = wrapResolver(fields[fieldName].resolve, fn);
}
else {
fields[fieldName].resolve = wrapResolver(fields[fieldName].resolve, rootResolveFn);
}
});
}
// XXX if the type is a subscription, a same query AST will be ran multiple times so we
// deactivate here the runOnce if it's a subscription. This may not be optimal though...
const subscription = schema.getSubscriptionType();
if (subscription != null && subscription.name === typeName) {
return {
...fieldConfig,
resolve: wrapResolver(fieldConfig.resolve, fn),
};
}
return {
...fieldConfig,
resolve: wrapResolver(fieldConfig.resolve, fnToRunOnlyOnce),
};
},
});

@@ -121,23 +122,25 @@ }

}
const schemaDirectives = Object.create(null);
Object.keys(directiveResolvers).forEach(directiveName => {
schemaDirectives[directiveName] = class extends utils.SchemaDirectiveVisitor {
visitFieldDefinition(field) {
const resolver = directiveResolvers[directiveName];
const originalResolver = field.resolve != null ? field.resolve : graphql.defaultFieldResolver;
const directiveArgs = this.args;
field.resolve = (...args) => {
const [source /* original args */, , context, info] = args;
return resolver(() => new Promise((resolve, reject) => {
const result = originalResolver.apply(field, args);
if (result instanceof Error) {
reject(result);
}
resolve(result);
}), source, directiveArgs, context, info);
};
}
};
return utils.mapSchema(schema, {
[utils.MapperKind.OBJECT_FIELD]: fieldConfig => {
const newFieldConfig = { ...fieldConfig };
const directives = utils.getDirectives(schema, fieldConfig);
Object.keys(directives).forEach(directiveName => {
if (directiveResolvers[directiveName]) {
const resolver = directiveResolvers[directiveName];
const originalResolver = newFieldConfig.resolve != null ? newFieldConfig.resolve : graphql.defaultFieldResolver;
const directiveArgs = directives[directiveName];
newFieldConfig.resolve = (source, originalArgs, context, info) => {
return resolver(() => new Promise((resolve, reject) => {
const result = originalResolver(source, originalArgs, context, info);
if (result instanceof Error) {
reject(result);
}
resolve(result);
}), source, directiveArgs, context, info);
};
}
});
return newFieldConfig;
},
});
utils.SchemaDirectiveVisitor.visitSchemaDirectives(schema, schemaDirectives);
}

@@ -343,3 +346,3 @@

: schemaOrOptions;
const { schema, resolvers: inputResolvers, defaultFieldResolver, resolverValidationOptions = {}, inheritResolversFromInterfaces = false, } = options;
let { schema, resolvers: inputResolvers, defaultFieldResolver, resolverValidationOptions = {}, inheritResolversFromInterfaces = false, } = options;
const { allowResolversNotInSchema = false, requireResolversForResolveType } = resolverValidationOptions;

@@ -349,3 +352,2 @@ const resolvers = inheritResolversFromInterfaces

: inputResolvers;
const typeMap = schema.getTypeMap();
Object.keys(resolvers).forEach(typeName => {

@@ -363,104 +365,149 @@ const resolverValue = resolvers[typeName];

}
const type = schema.getType(typeName);
if (type == null) {
if (allowResolversNotInSchema) {
return;
}
throw new Error(`"${typeName}" defined in resolvers, but not in schema`);
}
else if (graphql.isSpecifiedScalarType(type)) {
// allow -- without recommending -- overriding of specified scalar types
const resolverValue = resolvers[typeName];
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
type[fieldName.substring(2)] = resolverValue[fieldName];
}
else {
type[fieldName] = resolverValue[fieldName];
}
});
}
}
const type = schema.getType(typeName);
if (!type && typeName !== '__schema') {
if (allowResolversNotInSchema) {
return;
});
schema = utils.mapSchema(schema, {
[utils.MapperKind.SCALAR_TYPE]: type => {
const config = type.toConfig();
const resolverValue = resolvers[type.name];
if (!graphql.isSpecifiedScalarType(type) && resolverValue != null) {
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
config[fieldName.substring(2)] = resolverValue[fieldName];
}
else {
config[fieldName] = resolverValue[fieldName];
}
});
return new graphql.GraphQLScalarType(config);
}
throw new Error(`"${typeName}" defined in resolvers, but not in schema`);
}
if (graphql.isScalarType(type)) {
// Support -- without recommending -- overriding default scalar types
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
type[fieldName.substring(2)] = resolverValue[fieldName];
}
else {
type[fieldName] = resolverValue[fieldName];
}
});
}
else if (graphql.isEnumType(type)) {
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
type[fieldName.substring(2)] = resolverValue[fieldName];
}
else if (!type.getValue(fieldName)) {
if (allowResolversNotInSchema) {
},
[utils.MapperKind.ENUM_TYPE]: type => {
const resolverValue = resolvers[type.name];
const config = type.toConfig();
const enumValueConfigMap = config.values;
if (resolverValue != null) {
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
config[fieldName.substring(2)] = resolverValue[fieldName];
}
else if (!enumValueConfigMap[fieldName]) {
if (allowResolversNotInSchema) {
return;
}
throw new Error(`${type.name}.${fieldName} was defined in resolvers, but not present within ${type.name}`);
}
else {
enumValueConfigMap[fieldName].value = resolverValue[fieldName];
}
});
return new graphql.GraphQLEnumType(config);
}
},
[utils.MapperKind.UNION_TYPE]: type => {
const resolverValue = resolvers[type.name];
if (resolverValue != null) {
const config = type.toConfig();
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
// this is for isTypeOf and resolveType and all the other stuff.
config[fieldName.substring(2)] = resolverValue[fieldName];
return;
}
throw new Error(`${typeName}.${fieldName} was defined in resolvers, but not present within ${typeName}`);
}
});
const config = type.toConfig();
const values = type.getValues();
const newValues = values.reduce((prev, value) => ({
...prev,
[value.name]: {
value: Object.keys(resolverValue).includes(value.name) ? resolverValue[value.name] : value.name,
deprecationReason: value.deprecationReason,
description: value.description,
astNode: value.astNode,
},
}), {});
// healSchema called later to update all fields to new type
typeMap[typeName] = new graphql.GraphQLEnumType({
...config,
values: newValues,
});
}
else if (graphql.isUnionType(type)) {
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
// this is for isTypeOf and resolveType and all the other stuff.
type[fieldName.substring(2)] = resolverValue[fieldName];
return;
}
if (allowResolversNotInSchema) {
return;
}
throw new Error(`${typeName}.${fieldName} was defined in resolvers, but ${typeName} is not an object or interface type`);
});
}
else if (graphql.isObjectType(type) || graphql.isInterfaceType(type)) {
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
// this is for isTypeOf and resolveType and all the other stuff.
type[fieldName.substring(2)] = resolverValue[fieldName];
return;
}
const fields = type.getFields();
const field = fields[fieldName];
if (field == null) {
if (allowResolversNotInSchema) {
return;
}
throw new Error(`${typeName}.${fieldName} defined in resolvers, but not in schema`);
}
throw new Error(`${type.name}.${fieldName} was defined in resolvers, but ${type.name} is not an object or interface type`);
});
return new graphql.GraphQLUnionType(config);
}
},
[utils.MapperKind.OBJECT_TYPE]: type => {
const resolverValue = resolvers[type.name];
if (resolverValue != null) {
const config = type.toConfig();
const fields = config.fields;
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
config[fieldName.substring(2)] = resolverValue[fieldName];
return;
}
const field = fields[fieldName];
if (field == null) {
if (allowResolversNotInSchema) {
return;
}
throw new Error(`${type.name}.${fieldName} defined in resolvers, but not in schema`);
}
});
return new graphql.GraphQLObjectType(config);
}
},
[utils.MapperKind.INTERFACE_TYPE]: type => {
const resolverValue = resolvers[type.name];
if (resolverValue != null) {
const config = type.toConfig();
const fields = config.fields;
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
config[fieldName.substring(2)] = resolverValue[fieldName];
return;
}
const field = fields[fieldName];
if (field == null) {
if (allowResolversNotInSchema) {
return;
}
throw new Error(`${type.name}.${fieldName} defined in resolvers, but not in schema`);
}
});
return new graphql.GraphQLInterfaceType(config);
}
},
[utils.MapperKind.COMPOSITE_FIELD]: (fieldConfig, fieldName, typeName) => {
const resolverValue = resolvers[typeName];
if (resolverValue != null) {
const fieldResolve = resolverValue[fieldName];
if (typeof fieldResolve === 'function') {
// for convenience. Allows shorter syntax in resolver definition file
field.resolve = fieldResolve;
}
else {
if (typeof fieldResolve !== 'object') {
throw new Error(`Resolver ${typeName}.${fieldName} must be object or function`);
if (fieldResolve != null) {
const newFieldConfig = { ...fieldConfig };
if (typeof fieldResolve === 'function') {
// for convenience. Allows shorter syntax in resolver definition file
newFieldConfig.resolve = fieldResolve;
}
setFieldProperties(field, fieldResolve);
else {
if (typeof fieldResolve !== 'object') {
throw new Error(`Resolver ${typeName}.${fieldName} must be object or function`);
}
setFieldProperties(newFieldConfig, fieldResolve);
}
return newFieldConfig;
}
});
}
}
},
});
checkForResolveTypeResolver(schema, requireResolversForResolveType);
// serialize all default values prior to healing fields with new scalar/enum types.
utils.forEachDefaultValue(schema, utils.serializeInputValue);
// schema may have new scalar/enum types that require healing
utils.healSchema(schema);
// reparse all default values with new parsing functions.
utils.forEachDefaultValue(schema, utils.parseInputValue);
if (defaultFieldResolver != null) {
utils.forEachField(schema, field => {
if (!field.resolve) {
field.resolve = defaultFieldResolver;
}
schema = utils.mapSchema(schema, {
[utils.MapperKind.OBJECT_FIELD]: fieldConfig => ({
...fieldConfig,
resolve: fieldConfig.resolve != null ? fieldConfig.resolve : defaultFieldResolver,
}),
});

@@ -483,5 +530,7 @@ }

}
utils.forEachField(schema, (field, typeName, fieldName) => {
const errorHint = `${typeName}.${fieldName}`;
field.resolve = decorateWithLogger(field.resolve, logger, errorHint);
return utils.mapSchema(schema, {
[utils.MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName, typeName) => ({
...fieldConfig,
resolve: decorateWithLogger(fieldConfig.resolve, logger, `${typeName}.${fieldName}`),
}),
});

@@ -501,9 +550,11 @@ }

function addCatchUndefinedToSchema(schema) {
utils.forEachField(schema, (field, typeName, fieldName) => {
const errorHint = `${typeName}.${fieldName}`;
field.resolve = decorateToCatchUndefined(field.resolve, errorHint);
return utils.mapSchema(schema, {
[utils.MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName, typeName) => ({
...fieldConfig,
resolve: decorateToCatchUndefined(fieldConfig.resolve, `${typeName}.${fieldName}`),
}),
});
}
function makeExecutableSchema({ typeDefs, resolvers = {}, logger, allowUndefinedInResolve = true, resolverValidationOptions = {}, directiveResolvers, schemaDirectives, parseOptions = {}, inheritResolversFromInterfaces = false, }) {
function makeExecutableSchema({ typeDefs, resolvers = {}, logger, allowUndefinedInResolve = true, resolverValidationOptions = {}, directiveResolvers, schemaDirectives, schemaTransforms = [], parseOptions = {}, inheritResolversFromInterfaces = false, }) {
// Validate and clean up arguments

@@ -519,4 +570,4 @@ if (typeof resolverValidationOptions !== 'object') {

// Arguments are now validated and cleaned up
const schema = buildSchemaFromTypeDefinitions(typeDefs, parseOptions);
addResolversToSchema({
let schema = buildSchemaFromTypeDefinitions(typeDefs, parseOptions);
schema = addResolversToSchema({
schema,

@@ -529,6 +580,6 @@ resolvers: resolverMap,

if (!allowUndefinedInResolve) {
addCatchUndefinedToSchema(schema);
schema = addCatchUndefinedToSchema(schema);
}
if (logger != null) {
addErrorLoggingToSchema(schema, logger);
schema = addErrorLoggingToSchema(schema, logger);
}

@@ -538,6 +589,11 @@ if (typeof resolvers['__schema'] === 'function') {

// not doing that now, because I'd have to rewrite a lot of tests.
addSchemaLevelResolver(schema, resolvers['__schema']);
schema = addSchemaLevelResolver(schema, resolvers['__schema']);
}
schemaTransforms.forEach(schemaTransform => {
schema = schemaTransform(schema);
});
// directive resolvers are implemented using SchemaDirectiveVisitor.visitSchemaDirectives
// schema visiting modifies the schema in place
if (directiveResolvers != null) {
attachDirectiveResolvers(schema, directiveResolvers);
schema = attachDirectiveResolvers(schema, directiveResolvers);
}

@@ -544,0 +600,0 @@ if (schemaDirectives != null) {

@@ -1,3 +0,3 @@

import { defaultFieldResolver, isScalarType, getNamedType, Kind, print, buildASTSchema, extendSchema, parse, isAbstractType, isSchema, isEnumType, GraphQLEnumType, isUnionType, isObjectType, isInterfaceType } from 'graphql';
import { forEachField, SchemaDirectiveVisitor, forEachDefaultValue, serializeInputValue, healSchema, parseInputValue, mergeDeep } from '@graphql-tools/utils';
import { defaultFieldResolver, isScalarType, getNamedType, Kind, print, buildASTSchema, extendSchema, parse, isAbstractType, isSchema, isSpecifiedScalarType, GraphQLScalarType, GraphQLEnumType, GraphQLUnionType, GraphQLObjectType, GraphQLInterfaceType } from 'graphql';
import { mapSchema, MapperKind, forEachField, getDirectives, mergeDeep, SchemaDirectiveVisitor } from '@graphql-tools/utils';

@@ -8,20 +8,21 @@ // wraps all resolvers of query, mutation or subscription fields

// TODO test that schema is a schema, fn is a function
const rootTypes = [schema.getQueryType(), schema.getMutationType(), schema.getSubscriptionType()].filter(x => Boolean(x));
rootTypes.forEach(type => {
if (type != null) {
const fnToRunOnlyOnce = runAtMostOncePerRequest(fn);
return mapSchema(schema, {
[MapperKind.ROOT_FIELD]: (fieldConfig, _fieldName, typeName, schema) => {
// XXX this should run at most once per request to simulate a true root resolver
// for graphql-js this is an approximation that works with queries but not mutations
const rootResolveFn = runAtMostOncePerRequest(fn);
const fields = type.getFields();
Object.keys(fields).forEach(fieldName => {
// XXX if the type is a subscription, a same query AST will be ran multiple times so we
// deactivate here the runOnce if it's a subscription. This may not be optimal though...
if (type === schema.getSubscriptionType()) {
fields[fieldName].resolve = wrapResolver(fields[fieldName].resolve, fn);
}
else {
fields[fieldName].resolve = wrapResolver(fields[fieldName].resolve, rootResolveFn);
}
});
}
// XXX if the type is a subscription, a same query AST will be ran multiple times so we
// deactivate here the runOnce if it's a subscription. This may not be optimal though...
const subscription = schema.getSubscriptionType();
if (subscription != null && subscription.name === typeName) {
return {
...fieldConfig,
resolve: wrapResolver(fieldConfig.resolve, fn),
};
}
return {
...fieldConfig,
resolve: wrapResolver(fieldConfig.resolve, fnToRunOnlyOnce),
};
},
});

@@ -117,23 +118,25 @@ }

}
const schemaDirectives = Object.create(null);
Object.keys(directiveResolvers).forEach(directiveName => {
schemaDirectives[directiveName] = class extends SchemaDirectiveVisitor {
visitFieldDefinition(field) {
const resolver = directiveResolvers[directiveName];
const originalResolver = field.resolve != null ? field.resolve : defaultFieldResolver;
const directiveArgs = this.args;
field.resolve = (...args) => {
const [source /* original args */, , context, info] = args;
return resolver(() => new Promise((resolve, reject) => {
const result = originalResolver.apply(field, args);
if (result instanceof Error) {
reject(result);
}
resolve(result);
}), source, directiveArgs, context, info);
};
}
};
return mapSchema(schema, {
[MapperKind.OBJECT_FIELD]: fieldConfig => {
const newFieldConfig = { ...fieldConfig };
const directives = getDirectives(schema, fieldConfig);
Object.keys(directives).forEach(directiveName => {
if (directiveResolvers[directiveName]) {
const resolver = directiveResolvers[directiveName];
const originalResolver = newFieldConfig.resolve != null ? newFieldConfig.resolve : defaultFieldResolver;
const directiveArgs = directives[directiveName];
newFieldConfig.resolve = (source, originalArgs, context, info) => {
return resolver(() => new Promise((resolve, reject) => {
const result = originalResolver(source, originalArgs, context, info);
if (result instanceof Error) {
reject(result);
}
resolve(result);
}), source, directiveArgs, context, info);
};
}
});
return newFieldConfig;
},
});
SchemaDirectiveVisitor.visitSchemaDirectives(schema, schemaDirectives);
}

@@ -339,3 +342,3 @@

: schemaOrOptions;
const { schema, resolvers: inputResolvers, defaultFieldResolver, resolverValidationOptions = {}, inheritResolversFromInterfaces = false, } = options;
let { schema, resolvers: inputResolvers, defaultFieldResolver, resolverValidationOptions = {}, inheritResolversFromInterfaces = false, } = options;
const { allowResolversNotInSchema = false, requireResolversForResolveType } = resolverValidationOptions;

@@ -345,3 +348,2 @@ const resolvers = inheritResolversFromInterfaces

: inputResolvers;
const typeMap = schema.getTypeMap();
Object.keys(resolvers).forEach(typeName => {

@@ -359,104 +361,149 @@ const resolverValue = resolvers[typeName];

}
const type = schema.getType(typeName);
if (type == null) {
if (allowResolversNotInSchema) {
return;
}
throw new Error(`"${typeName}" defined in resolvers, but not in schema`);
}
else if (isSpecifiedScalarType(type)) {
// allow -- without recommending -- overriding of specified scalar types
const resolverValue = resolvers[typeName];
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
type[fieldName.substring(2)] = resolverValue[fieldName];
}
else {
type[fieldName] = resolverValue[fieldName];
}
});
}
}
const type = schema.getType(typeName);
if (!type && typeName !== '__schema') {
if (allowResolversNotInSchema) {
return;
});
schema = mapSchema(schema, {
[MapperKind.SCALAR_TYPE]: type => {
const config = type.toConfig();
const resolverValue = resolvers[type.name];
if (!isSpecifiedScalarType(type) && resolverValue != null) {
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
config[fieldName.substring(2)] = resolverValue[fieldName];
}
else {
config[fieldName] = resolverValue[fieldName];
}
});
return new GraphQLScalarType(config);
}
throw new Error(`"${typeName}" defined in resolvers, but not in schema`);
}
if (isScalarType(type)) {
// Support -- without recommending -- overriding default scalar types
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
type[fieldName.substring(2)] = resolverValue[fieldName];
}
else {
type[fieldName] = resolverValue[fieldName];
}
});
}
else if (isEnumType(type)) {
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
type[fieldName.substring(2)] = resolverValue[fieldName];
}
else if (!type.getValue(fieldName)) {
if (allowResolversNotInSchema) {
},
[MapperKind.ENUM_TYPE]: type => {
const resolverValue = resolvers[type.name];
const config = type.toConfig();
const enumValueConfigMap = config.values;
if (resolverValue != null) {
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
config[fieldName.substring(2)] = resolverValue[fieldName];
}
else if (!enumValueConfigMap[fieldName]) {
if (allowResolversNotInSchema) {
return;
}
throw new Error(`${type.name}.${fieldName} was defined in resolvers, but not present within ${type.name}`);
}
else {
enumValueConfigMap[fieldName].value = resolverValue[fieldName];
}
});
return new GraphQLEnumType(config);
}
},
[MapperKind.UNION_TYPE]: type => {
const resolverValue = resolvers[type.name];
if (resolverValue != null) {
const config = type.toConfig();
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
// this is for isTypeOf and resolveType and all the other stuff.
config[fieldName.substring(2)] = resolverValue[fieldName];
return;
}
throw new Error(`${typeName}.${fieldName} was defined in resolvers, but not present within ${typeName}`);
}
});
const config = type.toConfig();
const values = type.getValues();
const newValues = values.reduce((prev, value) => ({
...prev,
[value.name]: {
value: Object.keys(resolverValue).includes(value.name) ? resolverValue[value.name] : value.name,
deprecationReason: value.deprecationReason,
description: value.description,
astNode: value.astNode,
},
}), {});
// healSchema called later to update all fields to new type
typeMap[typeName] = new GraphQLEnumType({
...config,
values: newValues,
});
}
else if (isUnionType(type)) {
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
// this is for isTypeOf and resolveType and all the other stuff.
type[fieldName.substring(2)] = resolverValue[fieldName];
return;
}
if (allowResolversNotInSchema) {
return;
}
throw new Error(`${typeName}.${fieldName} was defined in resolvers, but ${typeName} is not an object or interface type`);
});
}
else if (isObjectType(type) || isInterfaceType(type)) {
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
// this is for isTypeOf and resolveType and all the other stuff.
type[fieldName.substring(2)] = resolverValue[fieldName];
return;
}
const fields = type.getFields();
const field = fields[fieldName];
if (field == null) {
if (allowResolversNotInSchema) {
return;
}
throw new Error(`${typeName}.${fieldName} defined in resolvers, but not in schema`);
}
throw new Error(`${type.name}.${fieldName} was defined in resolvers, but ${type.name} is not an object or interface type`);
});
return new GraphQLUnionType(config);
}
},
[MapperKind.OBJECT_TYPE]: type => {
const resolverValue = resolvers[type.name];
if (resolverValue != null) {
const config = type.toConfig();
const fields = config.fields;
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
config[fieldName.substring(2)] = resolverValue[fieldName];
return;
}
const field = fields[fieldName];
if (field == null) {
if (allowResolversNotInSchema) {
return;
}
throw new Error(`${type.name}.${fieldName} defined in resolvers, but not in schema`);
}
});
return new GraphQLObjectType(config);
}
},
[MapperKind.INTERFACE_TYPE]: type => {
const resolverValue = resolvers[type.name];
if (resolverValue != null) {
const config = type.toConfig();
const fields = config.fields;
Object.keys(resolverValue).forEach(fieldName => {
if (fieldName.startsWith('__')) {
config[fieldName.substring(2)] = resolverValue[fieldName];
return;
}
const field = fields[fieldName];
if (field == null) {
if (allowResolversNotInSchema) {
return;
}
throw new Error(`${type.name}.${fieldName} defined in resolvers, but not in schema`);
}
});
return new GraphQLInterfaceType(config);
}
},
[MapperKind.COMPOSITE_FIELD]: (fieldConfig, fieldName, typeName) => {
const resolverValue = resolvers[typeName];
if (resolverValue != null) {
const fieldResolve = resolverValue[fieldName];
if (typeof fieldResolve === 'function') {
// for convenience. Allows shorter syntax in resolver definition file
field.resolve = fieldResolve;
}
else {
if (typeof fieldResolve !== 'object') {
throw new Error(`Resolver ${typeName}.${fieldName} must be object or function`);
if (fieldResolve != null) {
const newFieldConfig = { ...fieldConfig };
if (typeof fieldResolve === 'function') {
// for convenience. Allows shorter syntax in resolver definition file
newFieldConfig.resolve = fieldResolve;
}
setFieldProperties(field, fieldResolve);
else {
if (typeof fieldResolve !== 'object') {
throw new Error(`Resolver ${typeName}.${fieldName} must be object or function`);
}
setFieldProperties(newFieldConfig, fieldResolve);
}
return newFieldConfig;
}
});
}
}
},
});
checkForResolveTypeResolver(schema, requireResolversForResolveType);
// serialize all default values prior to healing fields with new scalar/enum types.
forEachDefaultValue(schema, serializeInputValue);
// schema may have new scalar/enum types that require healing
healSchema(schema);
// reparse all default values with new parsing functions.
forEachDefaultValue(schema, parseInputValue);
if (defaultFieldResolver != null) {
forEachField(schema, field => {
if (!field.resolve) {
field.resolve = defaultFieldResolver;
}
schema = mapSchema(schema, {
[MapperKind.OBJECT_FIELD]: fieldConfig => ({
...fieldConfig,
resolve: fieldConfig.resolve != null ? fieldConfig.resolve : defaultFieldResolver,
}),
});

@@ -479,5 +526,7 @@ }

}
forEachField(schema, (field, typeName, fieldName) => {
const errorHint = `${typeName}.${fieldName}`;
field.resolve = decorateWithLogger(field.resolve, logger, errorHint);
return mapSchema(schema, {
[MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName, typeName) => ({
...fieldConfig,
resolve: decorateWithLogger(fieldConfig.resolve, logger, `${typeName}.${fieldName}`),
}),
});

@@ -497,9 +546,11 @@ }

function addCatchUndefinedToSchema(schema) {
forEachField(schema, (field, typeName, fieldName) => {
const errorHint = `${typeName}.${fieldName}`;
field.resolve = decorateToCatchUndefined(field.resolve, errorHint);
return mapSchema(schema, {
[MapperKind.OBJECT_FIELD]: (fieldConfig, fieldName, typeName) => ({
...fieldConfig,
resolve: decorateToCatchUndefined(fieldConfig.resolve, `${typeName}.${fieldName}`),
}),
});
}
function makeExecutableSchema({ typeDefs, resolvers = {}, logger, allowUndefinedInResolve = true, resolverValidationOptions = {}, directiveResolvers, schemaDirectives, parseOptions = {}, inheritResolversFromInterfaces = false, }) {
function makeExecutableSchema({ typeDefs, resolvers = {}, logger, allowUndefinedInResolve = true, resolverValidationOptions = {}, directiveResolvers, schemaDirectives, schemaTransforms = [], parseOptions = {}, inheritResolversFromInterfaces = false, }) {
// Validate and clean up arguments

@@ -515,4 +566,4 @@ if (typeof resolverValidationOptions !== 'object') {

// Arguments are now validated and cleaned up
const schema = buildSchemaFromTypeDefinitions(typeDefs, parseOptions);
addResolversToSchema({
let schema = buildSchemaFromTypeDefinitions(typeDefs, parseOptions);
schema = addResolversToSchema({
schema,

@@ -525,6 +576,6 @@ resolvers: resolverMap,

if (!allowUndefinedInResolve) {
addCatchUndefinedToSchema(schema);
schema = addCatchUndefinedToSchema(schema);
}
if (logger != null) {
addErrorLoggingToSchema(schema, logger);
schema = addErrorLoggingToSchema(schema, logger);
}

@@ -534,6 +585,11 @@ if (typeof resolvers['__schema'] === 'function') {

// not doing that now, because I'd have to rewrite a lot of tests.
addSchemaLevelResolver(schema, resolvers['__schema']);
schema = addSchemaLevelResolver(schema, resolvers['__schema']);
}
schemaTransforms.forEach(schemaTransform => {
schema = schemaTransform(schema);
});
// directive resolvers are implemented using SchemaDirectiveVisitor.visitSchemaDirectives
// schema visiting modifies the schema in place
if (directiveResolvers != null) {
attachDirectiveResolvers(schema, directiveResolvers);
schema = attachDirectiveResolvers(schema, directiveResolvers);
}

@@ -540,0 +596,0 @@ if (schemaDirectives != null) {

import { IExecutableSchemaDefinition } from './types';
export declare function makeExecutableSchema<TContext = any>({ typeDefs, resolvers, logger, allowUndefinedInResolve, resolverValidationOptions, directiveResolvers, schemaDirectives, parseOptions, inheritResolversFromInterfaces, }: IExecutableSchemaDefinition<TContext>): import("graphql").GraphQLSchema;
export declare function makeExecutableSchema<TContext = any>({ typeDefs, resolvers, logger, allowUndefinedInResolve, resolverValidationOptions, directiveResolvers, schemaDirectives, schemaTransforms, parseOptions, inheritResolversFromInterfaces, }: IExecutableSchemaDefinition<TContext>): import("graphql").GraphQLSchema;
{
"name": "@graphql-tools/schema",
"version": "5.0.1-alpha-b4a3ab5.0",
"version": "5.0.1-alpha-b5658b2.0",
"description": "A set of utils for faster development of GraphQL tools",

@@ -9,3 +9,3 @@ "peerDependencies": {

"dependencies": {
"@graphql-tools/utils": "5.0.1-alpha-b4a3ab5.0",
"@graphql-tools/utils": "5.0.1-alpha-b5658b2.0",
"tslib": "1.11.1"

@@ -12,0 +12,0 @@ },

@@ -1,2 +0,2 @@

import { ITypeDefinitions, IResolvers, IResolverValidationOptions, IDirectiveResolvers, SchemaDirectiveVisitorClass, GraphQLParseOptions } from 'packages/utils/src';
import { ITypeDefinitions, IResolvers, IResolverValidationOptions, IDirectiveResolvers, SchemaDirectiveVisitorClass, GraphQLParseOptions, SchemaTransform } from 'packages/utils/src';
export interface ILogger {

@@ -13,4 +13,5 @@ log: (error: Error) => void;

schemaDirectives?: Record<string, SchemaDirectiveVisitorClass>;
schemaTransforms?: Array<SchemaTransform>;
parseOptions?: GraphQLParseOptions;
inheritResolversFromInterfaces?: boolean;
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc