/**
* Copyright (c) 2017-present, Graphene.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import { GraphQLInterfaceType, GraphQLObjectType } from "graphql";
import {
getGraphQLType,
UnmountedFieldMap,
getFields,
assertFields,
setGraphQLType,
getDescription,
mountFields
} from "./../reflection";
// The provided configuration type when creating an ObjectType.
export type ObjectTypeConfig = {
name?: string;
description?: string;
interfaces?: any[];
};
export const ObjectType = (opts: ObjectTypeConfig = {}) => <
T extends { new (...args: any[]): any }
>(
target: T
): T => {
// save a reference to the original constructor
const interfaces: GraphQLInterfaceType[] = (opts.interfaces || []).map(
iface => {
const ifaceType = getGraphQLType(iface);
if (!(ifaceType instanceof GraphQLInterfaceType)) {
throw new Error(`Provided interface ${ifaceType} is not valid`);
}
return ifaceType;
}
);
let allInterfaceFields: UnmountedFieldMap = {};
(opts.interfaces || []).forEach((_, index) => {
const iface = (opts.interfaces || [])[index];
const ifaceFields: UnmountedFieldMap = getFields(iface);
allInterfaceFields = {
...allInterfaceFields,
...ifaceFields
};
});
const fields: UnmountedFieldMap = {
// First we introduce the fields from the interfaces that we inherit
...allInterfaceFields,
// Then we retrieve the fields for the current type
...getFields(target)
};
assertFields(target, fields);
setGraphQLType(
target,
new GraphQLObjectType({
name: opts.name || target.name,
description: opts.description || getDescription(target),
interfaces: interfaces,
fields: mountFields(fields)
})
);
return target;
};
|