graphql#GraphQLNamedType TypeScript Examples

The following examples show how to use graphql#GraphQLNamedType. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.ts    From tql with MIT License 7 votes vote down vote up
printType = (type: GraphQLNamedType) => {
  if (type instanceof GraphQLScalarType) {
    return `${type.name}: ${toPrimitive(type)}`;
  } else if (type instanceof GraphQLEnumType) {
    return `${type.name}: ${type.name}`;
  } else {
    return `${type.name}: I${type.name}`;
  }
}
Example #2
Source File: schema.ts    From squid with GNU General Public License v3.0 6 votes vote down vote up
function handleFulltextDirective(model: Model, object: GraphQLNamedType, f: GraphQLField<any, any>): void {
    f.astNode?.directives?.forEach(d => {
        if (d.name.value != 'fulltext') return
        if (!isEntityType(object) || !isStringField(f)) {
            throw new Error(`@fulltext directive can be only applied to String entity fields, but was applied to ${object.name}.${f.name}`)
        }
        let queryArgument = d.arguments?.find(arg => arg.name.value == 'query')
        assert(queryArgument != null)
        assert(queryArgument.value.kind == 'StringValue')
        let queryName = queryArgument.value.value
        let query = model[queryName]
        if (query == null) {
            query = model[queryName] = {
                kind: 'fts',
                sources: []
            }
        }
        assert(query.kind == 'fts')
        let src = query.sources.find(s => s.entity == object.name)
        if (src == null) {
            query.sources.push({
                entity: object.name,
                fields: [f.name]
            })
        } else {
            src.fields.push(f.name)
        }
    })
}
Example #3
Source File: visitor.ts    From proto2graphql with MIT License 6 votes vote down vote up
function visitNested(
  objects: protobuf.ReflectionObject[],
  context: Context
): GraphQLNamedType[] {
  return objects
    .map(object => {
      if (object instanceof protobuf.Type) {
        return visitMessage(object, context);
      }
      if (object instanceof protobuf.Enum) {
        return visitEnum(object, context);
      }
      if (object instanceof protobuf.Namespace) {
        return visitNested(object.nestedArray, context);
      }
    })
    .flat()
    .filter(Boolean);
}
Example #4
Source File: utils.ts    From graphql-eslint with MIT License 6 votes vote down vote up
export function getBaseType(type: GraphQLOutputType): GraphQLNamedType {
  if (isNonNullType(type) || isListType(type)) {
    return getBaseType(type.ofType);
  }
  return type;
}
Example #5
Source File: InputWriter.ts    From graphql-ts-client with MIT License 6 votes vote down vote up
protected importingBehavior(type: GraphQLNamedType): ImportingBehavior {
        if (type === this.inputType) {
            return "SELF";
        }
        if (type instanceof GraphQLInputObjectType) {
            return "SAME_DIR";
        }
        return "OTHER_DIR";
    }
Example #6
Source File: Generator.ts    From graphql-ts-client with MIT License 6 votes vote down vote up
private async writeSimpleIndex(dir: string, types: GraphQLNamedType[]) {
        const stream = createStreamAndLog(join(dir, "index.ts"));
        for (const type of types) {
            stream.write(
                `export type {${type.name}} from './${type.name}';\n`
            );
        }
        await stream.end();
    }
Example #7
Source File: FetcherWriter.ts    From graphql-ts-client with MIT License 6 votes vote down vote up
protected importingBehavior(type: GraphQLNamedType): ImportingBehavior {
        if (type === this.modelType) {
            return "SELF";
        }
        if (type instanceof GraphQLObjectType || type instanceof GraphQLInterfaceType) {
            return "SAME_DIR";
        }
        return "OTHER_DIR";
    }
Example #8
Source File: schema.ts    From squid with GNU General Public License v3.0 6 votes vote down vote up
function checkFieldIndex(type: GraphQLNamedType, f: GraphQLField<any, any>): Index | undefined {
    let unique = false
    let index = false

    f.astNode?.directives?.forEach(d => {
        if (d.name.value == 'unique') {
            assertCanBeIndexed(type, f)
            index = true
            unique = true
        } else if (d.name.value == 'index') {
            assertCanBeIndexed(type, f)
            let fieldsArg = d.arguments?.find(arg => arg.name.value == 'fields')
            if (fieldsArg) throw new SchemaError(
                `@index(fields: ...) where applied to ${type.name}.${f.name}, but fields argument is not allowed when @index is applied to a field`
            )
            let uniqueArg = d.arguments?.find(arg => arg.name.value == 'unique')
            if (uniqueArg) {
                assert(uniqueArg.value.kind == 'BooleanValue')
                unique = uniqueArg.value.value
            }
            index = true
        }
    })

    if (!index) return undefined

    return {
        fields: [{name: f.name}],
        unique
    }
}
Example #9
Source File: resolve-additional-resolvers.ts    From graphql-mesh with MIT License 6 votes vote down vote up
function getTypeByPath(type: GraphQLType, path: string[]): GraphQLNamedType {
  if ('ofType' in type) {
    return getTypeByPath(getNamedType(type), path);
  }
  if (path.length === 0) {
    return getNamedType(type);
  }
  if (!('getFields' in type)) {
    throw new Error(`${type} cannot have a path ${path.join('.')}`);
  }
  const fieldMap = type.getFields();
  const currentFieldName = path[0];
  // Might be an index of an array
  if (!Number.isNaN(parseInt(currentFieldName))) {
    return getTypeByPath(type, path.slice(1));
  }
  const field = fieldMap[currentFieldName];
  if (!field?.type) {
    throw new Error(`${type}.${currentFieldName} is not a valid field.`);
  }
  return getTypeByPath(field.type, path.slice(1));
}
Example #10
Source File: barePrefix.ts    From graphql-mesh with MIT License 6 votes vote down vote up
transformSchema(schema: GraphQLSchema) {
    return mapSchema(schema, {
      [MapperKind.TYPE]: (type: GraphQLNamedType) => {
        if (this.includeTypes && !isSpecifiedScalarType(type)) {
          const currentName = type.name;
          if (!this.ignoreList.includes(currentName)) {
            return renameType(type, this.prefix + currentName);
          }
        }
        return undefined;
      },
      [MapperKind.ROOT_OBJECT]() {
        return undefined;
      },
      ...(this.includeRootOperations && {
        [MapperKind.COMPOSITE_FIELD]: (
          fieldConfig: GraphQLFieldConfig<any, any>,
          fieldName: string,
          typeName: string
        ) => {
          return !rootOperations.has(typeName) || // check we're in a root Type
            this.ignoreList.includes(typeName) || // check if type is to be ignored
            this.ignoreList.includes(`${typeName}.${fieldName}`) // check if field in type is to be ignored
            ? undefined // do not perform any change
            : [`${this.prefix}${fieldName}`, fieldConfig]; // apply prefix
        },
      }),
    });
  }
Example #11
Source File: provide-variables.ts    From graphql-query-generator with MIT License 6 votes vote down vote up
export function getProviderValue(
  varName: string,
  config: Configuration,
  providedValues: Variables,
  argType?: GraphQLNamedType
): {
  providerFound: boolean
  value: any
} {
  const { providerFound, provider } = getProvider(varName, config.providerMap)

  return {
    providerFound,
    value:
      typeof provider === 'function'
        ? (provider as ProviderFunction)(providedValues, argType)
        : provider
  }
}
Example #12
Source File: provide-variables.ts    From graphql-query-generator with MIT License 6 votes vote down vote up
export function isEnumType(type: GraphQLNamedType): boolean {
  const typeDef = type.astNode
  if (
    typeof typeDef !== 'undefined' &&
    typeDef.kind === Kind.ENUM_TYPE_DEFINITION
  ) {
    return true
  }
  return false
}
Example #13
Source File: provide-variables.ts    From graphql-query-generator with MIT License 6 votes vote down vote up
export function getRandomEnum(type: GraphQLNamedType) {
  const typeDef = type.astNode
  if (
    typeof typeDef !== 'undefined' &&
    typeDef.kind === Kind.ENUM_TYPE_DEFINITION
  ) {
    let value =
      typeDef.values[Math.floor(Math.random() * typeDef.values.length)]
    return value.name.value
  }
}
Example #14
Source File: schema.ts    From squid with GNU General Public License v3.0 6 votes vote down vote up
function checkDerivedFrom(type: GraphQLNamedType, f: GraphQLField<any, any>): {field: string} | undefined {
    let directives = f.astNode?.directives?.filter(d => d.name.value == 'derivedFrom') || []
    if (directives.length == 0) return undefined
    if (!isEntityType(type)) throw new SchemaError(
        `@derivedFrom where applied to ${type.name}.${f.name}, but only entities can have lookup fields`
    )
    if (directives.length > 1) throw new SchemaError(
        `Multiple @derivedFrom where applied to ${type.name}.${f.name}`
    )
    let d = directives[0]
    let fieldArg = assertNotNull(d.arguments?.find(arg => arg.name.value == 'field'))
    assert(fieldArg.value.kind == 'StringValue')
    return {field: fieldArg.value.value}
}
Example #15
Source File: Writer.ts    From graphql-ts-client with MIT License 5 votes vote down vote up
protected importingBehavior(type: GraphQLNamedType): ImportingBehavior {
        return "OTHER_DIR";
    }
Example #16
Source File: typeMappedAlias.ts    From genql with MIT License 5 votes vote down vote up
getTypeMappedAlias = (
    type: GraphQLNamedType,
    ctx: RenderContext,
) => {
    const map = { ...knownTypes, ...(ctx?.config?.scalarTypes || {}) }
    return map?.[type.name] || 'any'
}
Example #17
Source File: schema.ts    From squid with GNU General Public License v3.0 5 votes vote down vote up
function assertCanBeIndexed(type: GraphQLNamedType, f: GraphQLField<any, any>): void {
    if (!isEntityType(type)) throw new SchemaError(
        `${type.name}.${f.name} can't be indexed, because ${type.name} is not an entity`
    )
    if (!canBeIndexed(f)) throw new SchemaError(
        `${type.name}.${f.name} can't be indexed, it is not a scalar, enum or foreign key`
    )
}
Example #18
Source File: requestTypeName.ts    From genql with MIT License 5 votes vote down vote up
requestTypeName = (type: GraphQLNamedType) => `${type.name}Request`
Example #19
Source File: comment.ts    From genql with MIT License 5 votes vote down vote up
typeComment = (type: GraphQLNamedType) =>
  comment({
    text: type.description,
  })
Example #20
Source File: objectType.ts    From genql with MIT License 5 votes vote down vote up
chainTypeName = (
    type: GraphQLNamedType,
    wrapper: 'Promise' | 'Observable',
) => {
    return `${type.name}${wrapper}Chain`
}
Example #21
Source File: context.ts    From proto2graphql with MIT License 5 votes vote down vote up
export function setType(type: GraphQLNamedType, context: Context) {
  context.types[type.name] = type as GraphQLOutputType;
}
Example #22
Source File: Writer.ts    From graphql-ts-client with MIT License 5 votes vote down vote up
private importedTypes = new Set<GraphQLNamedType>();
Example #23
Source File: Writer.d.ts    From graphql-ts-client with MIT License 5 votes vote down vote up
protected importingBehavior(type: GraphQLNamedType): ImportingBehavior;
Example #24
Source File: InputWriter.d.ts    From graphql-ts-client with MIT License 5 votes vote down vote up
protected importingBehavior(type: GraphQLNamedType): ImportingBehavior;
Example #25
Source File: FetcherWriter.d.ts    From graphql-ts-client with MIT License 5 votes vote down vote up
protected importingBehavior(type: GraphQLNamedType): ImportingBehavior;
Example #26
Source File: provide-variables.d.ts    From graphql-query-generator with MIT License 5 votes vote down vote up
export declare function getProviderValue(varName: string, config: Configuration, providedValues: Variables, argType?: GraphQLNamedType): {
    providerFound: boolean;
    value: any;
};
Example #27
Source File: provide-variables.d.ts    From graphql-query-generator with MIT License 5 votes vote down vote up
export declare function isEnumType(type: GraphQLNamedType): boolean;
Example #28
Source File: provide-variables.d.ts    From graphql-query-generator with MIT License 5 votes vote down vote up
export declare function getRandomEnum(type: GraphQLNamedType): string;
Example #29
Source File: schema.ts    From Deep-Lynx with MIT License 4 votes vote down vote up
// generate requires a containerID because the schema it generates is based on a user's ontology and ontologies are
    // separated by containers
    async ForContainer(containerID: string, options: ResolverOptions): Promise<Result<GraphQLSchema>> {
        // fetch the currently published ontology if the versionID wasn't provided
        if (!options.ontologyVersionID) {
            const ontResults = await this.#ontologyRepo
                .where()
                .containerID('eq', containerID)
                .and()
                .status('eq', 'published')
                .list({sortBy: 'id', sortDesc: true});
            if (ontResults.isError || ontResults.value.length === 0) {
                Logger.error('unable to fetch current ontology, or no currently published ontology');
            } else {
                options.ontologyVersionID = ontResults.value[0].id;
            }
        }

        // fetch all metatypes for the container, with their keys - the single most expensive call of this function
        const metatypeResults = await this.#metatypeRepo
            .where()
            .containerID('eq', containerID)
            .and()
            .ontologyVersion('eq', options.ontologyVersionID)
            .list(true);
        if (metatypeResults.isError) {
            return Promise.resolve(Result.Pass(metatypeResults));
        }

        // fetch all metatype relationship pairs - used for _relationship queries.
        const metatypePairResults = await this.#metatypePairRepo
            .where()
            .containerID('eq', containerID)
            .and()
            .ontologyVersion('eq', options.ontologyVersionID)
            .list();
        if (metatypePairResults.isError) {
            return Promise.resolve(Result.Pass(metatypePairResults));
        }

        // fetch all relationship types. Used for relationship wrapper queries.
        const relationshipResults = await this.#relationshipRepo
            .where()
            .containerID('eq', containerID)
            .and()
            .ontologyVersion('eq', options.ontologyVersionID)
            .list(true);
        if (relationshipResults.isError) {
            return Promise.resolve(Result.Pass(relationshipResults));
        }

        // used for querying edges based on node (see input._relationship resolver)
        const metatypePairObjects: {[key: string]: any} = {};
        metatypePairResults.value.forEach((pair) => {
            const origin = stringToValidPropertyName(pair.origin_metatype_name!);
            const rel = stringToValidPropertyName(pair.relationship_name!);
            const dest = stringToValidPropertyName(pair.destination_metatype_name!);
            // populate list for forward searching
            if (!(origin in metatypePairObjects)) {
                metatypePairObjects[origin] = {};
            }
            if (!(rel in metatypePairObjects[origin])) {
                metatypePairObjects[origin][rel] = {};
            }
            if (!(dest in metatypePairObjects[origin][rel])) {
                metatypePairObjects[origin][rel][dest] = {type: GraphQLString};
            }
        });

        const metatypeGraphQLObjects: {[key: string]: any} = {};

        // we must declare the metadata input object beforehand so we can include it in the final schema entry for each
        // metatype
        const recordInputType = new GraphQLInputObjectType({
            name: 'record_input',
            fields: {
                id: {type: GraphQLString},
                data_source_id: {type: GraphQLString},
                original_id: {type: GraphQLJSON}, // since the original ID might be a number, treat it as valid JSON
                import_id: {type: GraphQLString},
                limit: {type: GraphQLInt, defaultValue: 10000},
                page: {type: GraphQLInt, defaultValue: 1},
            },
        });

        const recordInfo = new GraphQLObjectType({
            name: 'recordInfo',
            fields: {
                id: {type: GraphQLString},
                data_source_id: {type: GraphQLString},
                original_id: {type: GraphQLJSON}, // since the original ID might be a number, treat it as valid JSON
                import_id: {type: GraphQLString},
                metatype_id: {type: GraphQLString},
                metatype_name: {type: GraphQLString},
                created_at: {type: GraphQLString},
                created_by: {type: GraphQLString},
                modified_at: {type: GraphQLString},
                modified_by: {type: GraphQLString},
                metadata: {type: GraphQLJSON},
                count: {type: GraphQLInt},
                page: {type: GraphQLInt},
            },
        });

        // needed when a user decides they want the results as a file vs. a raw return
        const fileInfo = new GraphQLObjectType({
            name: 'fileInfo',
            fields: {
                id: {type: GraphQLString},
                file_name: {type: GraphQLString},
                file_size: {type: GraphQLFloat},
                md5hash: {type: GraphQLString},
                metadata: {type: GraphQLJSON},
                url: {type: GraphQLString},
            },
        });

        metatypeResults.value.forEach((metatype) => {
            if (!metatype.keys || metatype.keys.length === 0) return;

            // the following 4 input/object types are used for querying or introspection on _relationship
            const destinationInputType = new GraphQLInputObjectType({
                name: `${stringToValidPropertyName(metatype.name)}_destination_input`,
                // needed because the return type accepts an object, but throws a fit about it
                // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                // @ts-ignore
                fields: () => {
                    const fields: {[key: string]: {[key: string]: any}} = {};
                    if (metatypePairObjects[stringToValidPropertyName(metatype.name)]) {
                        Object.keys(metatypePairObjects[stringToValidPropertyName(metatype.name)]).forEach((pair) => {
                            Object.keys(metatypePairObjects[stringToValidPropertyName(metatype.name)][pair]).forEach((dest) => {
                                fields[dest] = {type: GraphQLBoolean};
                            });
                        });
                    }
                    return fields;
                },
            });

            const relationshipInputType = new GraphQLInputObjectType({
                name: `${stringToValidPropertyName(metatype.name)}_relationship_input`,
                // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                // @ts-ignore
                fields: () => {
                    const fields: {[key: string]: {[key: string]: GraphQLNamedType | GraphQLList<any>}} = {};
                    if (metatypePairObjects[metatype.name]) {
                        Object.keys(metatypePairObjects[metatype.name]).forEach((rel) => {
                            fields[rel] = {type: new GraphQLList(destinationInputType)};
                        });
                    } else {
                        // if no relationships exists, set relationship to _none: true
                        fields._none = {type: GraphQLBoolean};
                    }
                    return fields;
                },
            });

            const destinationInfo = new GraphQLObjectType({
                name: `${stringToValidPropertyName(metatype.name)}_destinationInfo`,
                // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                // @ts-ignore
                fields: () => {
                    const fields: {[key: string]: any} = {};
                    if (metatypePairObjects[metatype.name]) {
                        Object.keys(metatypePairObjects[metatype.name]).forEach((pair) => {
                            Object.keys(metatypePairObjects[metatype.name][pair]).forEach((dest) => {
                                fields[dest] = {type: GraphQLString};
                            });
                        });
                    }
                    return fields;
                },
            });

            const relationshipInfo = new GraphQLObjectType({
                name: `${stringToValidPropertyName(metatype.name)}_relationshipInfo`,
                // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                // @ts-ignore
                fields: () => {
                    const fields: {[key: string]: any} = {};
                    if (metatypePairObjects[metatype.name]) {
                        Object.keys(metatypePairObjects[metatype.name]).forEach((pair) => {
                            fields[pair] = {type: destinationInfo};
                        });
                    } else {
                        // if no relationships exists, set relationship to _none: true
                        fields._none = {type: GraphQLBoolean};
                    }
                    return fields;
                },
            });

            metatypeGraphQLObjects[stringToValidPropertyName(metatype.name)] = {
                args: {
                    ...this.inputFieldsForMetatype(metatype),
                    _record: {type: recordInputType},
                    _relationship: {type: relationshipInputType},
                },
                description: metatype.description,
                type: options.returnFile
                    ? fileInfo
                    : new GraphQLList(
                        new GraphQLObjectType({
                            name: stringToValidPropertyName(metatype.name),
                            // needed because the return type accepts an object, but throws a fit about it
                            // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                            // @ts-ignore
                            fields: () => {
                                const output: {[key: string]: {[key: string]: GraphQLNamedType | GraphQLList<any>}} = {};
                                output._record = {type: recordInfo};
                                output._relationship = {type: relationshipInfo};
                                output._file = {type: fileInfo};

                                metatype.keys?.forEach((metatypeKey) => {
                                    // keys must match the regex format of /^[_a-zA-Z][_a-zA-Z0-9]*$/ in order to be considered
                                    // valid graphql property names. While we force the user to meet these requirements at key
                                    // creation, we can't guarantee that legacy data will conform to these standards
                                    const propertyName = stringToValidPropertyName(metatypeKey.property_name);

                                    switch (metatypeKey.data_type) {
                                        // because we have no specification on our internal number type, we
                                        // must set this as a float for now
                                        case 'number': {
                                            output[propertyName] = {
                                                type: GraphQLFloat,
                                            };
                                            break;
                                        }

                                        case 'boolean': {
                                            output[propertyName] = {
                                                type: GraphQLBoolean,
                                            };
                                            break;
                                        }

                                        case 'string' || 'date' || 'file': {
                                            output[propertyName] = {
                                                type: GraphQLString,
                                            };
                                            break;
                                        }

                                        case 'list': {
                                            output[propertyName] = {
                                                type: new GraphQLList(GraphQLJSON),
                                            };
                                            break;
                                        }

                                        case 'enumeration': {
                                            const enumMap: {[key: string]: GraphQLEnumValueConfig} = {};

                                            if (metatypeKey.options) {
                                                metatypeKey.options.forEach((option) => {
                                                    enumMap[option] = {
                                                        value: option,
                                                    };
                                                });
                                            }

                                            output[propertyName] = {
                                                type: new GraphQLEnumType({
                                                    name: stringToValidPropertyName(`${metatype.name}_${metatypeKey.name}_Enum_TypeA`),
                                                    values: enumMap,
                                                }),
                                            };
                                            break;
                                        }

                                        default: {
                                            output[propertyName] = {
                                                type: GraphQLString,
                                            };
                                        }
                                    }
                                });

                                return output;
                            },
                        }),
                    ),
                resolve: this.resolverForMetatype(containerID, metatype, options),
            };
        });

        const relationshipGraphQLObjects: {[key: string]: any} = {};

        // metadata objects for edges (metatype relationships)
        const edgeRecordInputType = new GraphQLInputObjectType({
            name: 'edge_record_input',
            fields: {
                id: {type: GraphQLString},
                pair_id: {type: GraphQLString},
                data_source_id: {type: GraphQLString},
                import_id: {type: GraphQLString},
                origin_id: {type: GraphQLString},
                destination_id: {type: GraphQLString},
                limit: {type: GraphQLInt, defaultValue: 10000},
                page: {type: GraphQLInt, defaultValue: 1},
            },
        });

        const edgeRecordInfo = new GraphQLObjectType({
            name: 'edge_recordInfo',
            fields: {
                id: {type: GraphQLString},
                pair_id: {type: GraphQLString},
                data_source_id: {type: GraphQLString},
                import_id: {type: GraphQLString},
                origin_id: {type: GraphQLString},
                origin_metatype_id: {type: GraphQLString},
                destination_id: {type: GraphQLString},
                destination_metatype_id: {type: GraphQLString},
                relationship_name: {type: GraphQLString},
                created_at: {type: GraphQLString},
                created_by: {type: GraphQLString},
                modified_at: {type: GraphQLString},
                modified_by: {type: GraphQLString},
                metadata: {type: GraphQLJSON},
                count: {type: GraphQLInt},
                page: {type: GraphQLInt},
            },
        });

        relationshipResults.value.forEach((relationship) => {
            relationshipGraphQLObjects[stringToValidPropertyName(relationship.name)] = {
                args: {
                    ...this.inputFieldsForRelationship(relationship),
                    _record: {type: edgeRecordInputType},
                },
                description: relationship.description,
                type: (options.returnFile) ? fileInfo : new GraphQLList(
                    new GraphQLObjectType({
                        name: stringToValidPropertyName(relationship.name),
                        // needed because the return type accepts an object, but throws a fit about it
                        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
                        // @ts-ignore
                        fields: () => {
                            const output: {[key: string]: {[key: string]: GraphQLNamedType | GraphQLList<any>}} = {};
                            output._record = {type: edgeRecordInfo};

                            relationship.keys?.forEach((relationshipKey) => {
                                const propertyName = stringToValidPropertyName(relationshipKey.property_name);

                                switch (relationshipKey.data_type) {
                                    // because we have no specification on our internal number type, we
                                    // must set this as a float for now
                                    case 'number': {
                                        output[propertyName] = {
                                            type: GraphQLFloat,
                                        };
                                        break;
                                    }

                                    case 'boolean': {
                                        output[propertyName] = {
                                            type: GraphQLBoolean,
                                        };
                                        break;
                                    }

                                    case 'string' || 'date' || 'file': {
                                        output[propertyName] = {
                                            type: GraphQLString,
                                        };
                                        break;
                                    }

                                    case 'list': {
                                        output[propertyName] = {
                                            type: new GraphQLList(GraphQLJSON),
                                        };
                                        break;
                                    }

                                    case 'enumeration': {
                                        const enumMap: {[key: string]: GraphQLEnumValueConfig} = {};

                                        if (relationshipKey.options) {
                                            relationshipKey.options.forEach((option) => {
                                                enumMap[option] = {
                                                    value: option,
                                                };
                                            });
                                        }

                                        output[propertyName] = {
                                            type: new GraphQLEnumType({
                                                name: stringToValidPropertyName(`${relationship.name}_${relationshipKey.name}_Enum_TypeA`),
                                                values: enumMap,
                                            }),
                                        };
                                        break;
                                    }

                                    default: {
                                        output[propertyName] = {
                                            type: GraphQLString,
                                        };
                                    }
                                }
                            });
                            return output;
                        },
                    }),
                ),
                resolve: this.resolverForRelationships(containerID, relationship, options),
            };
        });

        const metatypeObjects = new GraphQLObjectType({
            name: 'metatypes',
            fields: metatypeGraphQLObjects,
        });

        const relationshipObjects = new GraphQLObjectType({
            name: 'relationships',
            fields: relationshipGraphQLObjects,
        });

        // nodeType and edgeType for flexibility in filtering graph return
        const nodeInputType = new GraphQLInputObjectType({
            name: 'node_input',
            fields: {
                name: {type: GraphQLString},
                id: {type: GraphQLString},
                origin_name: {type: GraphQLString},
                origin_id: {type: GraphQLString},
                destination_name: {type: GraphQLString},
                destination_id: {type: GraphQLString},
            },
        });

        const edgeInputType = new GraphQLInputObjectType({
            name: 'edge_input',
            fields: {
                name: {type: GraphQLString},
                id: {type: GraphQLString},
            },
        });

        // the fields on which a user can filter the graph return
        const graphInput: {[key: string]: any} = {
            root_node: {type: new GraphQLNonNull(GraphQLString)}, // root node must be specified
            node_type: {type: nodeInputType},
            edge_type: {type: edgeInputType},
            depth: {type: new GraphQLNonNull(GraphQLString)}, // depth must be specified
        };

        const graphType = new GraphQLList(
            new GraphQLObjectType({
                name: 'graph_type',
                fields: {
                    // For more advanced querying these may become an Object type of their own
                    // to retrieve only specific properties from origin, edge and destination.
                    // For now json will do.
                    origin_properties: {type: GraphQLJSON},
                    edge_properties: {type: GraphQLJSON},
                    destination_properties: {type: GraphQLJSON},
                    // origin data
                    origin_id: {type: GraphQLString},
                    origin_metatype_name: {type: GraphQLString},
                    origin_metatype_id: {type: GraphQLString},
                    origin_data_source: {type: GraphQLString},
                    origin_metadata: {type: GraphQLJSON},
                    origin_created_by: {type: GraphQLString},
                    origin_created_at: {type: GraphQLString},
                    origin_modified_by: {type: GraphQLString},
                    origin_modified_at: {type: GraphQLString},
                    // edge data
                    edge_id: {type: GraphQLString},
                    relationship_name: {type: GraphQLString},
                    relationship_pair_id: {type: GraphQLString},
                    relationship_id: {type: GraphQLString},
                    edge_data_source: {type: GraphQLString},
                    edge_metadata: {type: GraphQLJSON},
                    edge_created_by: {type: GraphQLString},
                    edge_created_at: {type: GraphQLString},
                    edge_modified_by: {type: GraphQLString},
                    edge_modified_at: {type: GraphQLString},
                    // destination data
                    destination_id: {type: GraphQLString},
                    destination_metatype_name: {type: GraphQLString},
                    destination_metatype_id: {type: GraphQLString},
                    destination_data_source: {type: GraphQLString},
                    destination_metadata: {type: GraphQLJSON},
                    destination_created_by: {type: GraphQLString},
                    destination_created_at: {type: GraphQLString},
                    destination_modified_by: {type: GraphQLString},
                    destination_modified_at: {type: GraphQLString},
                    // graph metadata
                    depth: {type: GraphQLInt},
                    path: {type: GraphQLList(GraphQLString)},
                },
            }),
        );

        const fields: {[key: string]: any} = {};

        if (Object.keys(metatypeGraphQLObjects).length > 0) {
            fields.metatypes = {
                type: metatypeObjects,
                resolve: () => {
                    return metatypeGraphQLObjects;
                },
            };
        }

        if (Object.keys(relationshipGraphQLObjects).length > 0) {
            fields.relationships = {
                type: relationshipObjects,
                resolve: () => {
                    return relationshipGraphQLObjects;
                },
            };
        }

        fields.graph = {
            args: {...graphInput},
            type: (options.returnFile) ? fileInfo : graphType,
            resolve: this.resolverForGraph(containerID, options) as any,
        };

        return Promise.resolve(
            Result.Success(
                new GraphQLSchema({
                    query: new GraphQLObjectType({
                        name: 'Query',
                        fields,
                    }),
                }),
            ),
        );
    }