graphql#GraphQLInputObjectType TypeScript Examples
The following examples show how to use
graphql#GraphQLInputObjectType.
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: inputObjectType.ts From genql with MIT License | 6 votes |
inputObjectType = (type: GraphQLInputObjectType, ctx: RenderContext) => {
let fields = type.getFields()
if (ctx.config?.sortProperties) {
fields = sortKeys(fields)
}
const fieldStrings = Object.keys(fields).map(fieldName => {
const field = fields[fieldName]
return `${argumentComment(field)}${field.name}${renderTyping(field.type, false, true)}`
})
ctx.addCodeBlock(`${typeComment(type)}export interface ${type.name} {${fieldStrings.join(',')}}`)
}
Example #2
Source File: printers.ts From tql with MIT License | 6 votes |
printInputType = (type: GraphQLInputType): string => {
const isList = listType(type);
const base = inputType(type);
return (
(() => {
if (base instanceof GraphQLScalarType) {
return toPrimitive(base);
} else if (base instanceof GraphQLEnumType) {
return base.name;
} else if (base instanceof GraphQLInputObjectType) {
return "I" + base.name;
} else {
throw new Error("Unable to render inputType.");
}
})() + (isList ? "[]" : "")
);
}
Example #3
Source File: withOperators.ts From payload with MIT License | 6 votes |
withOperators = (field: FieldAffectingData, type: GraphQLType, parentName: string, operators: string[]): GraphQLInputObjectType => {
const name = `${combineParentName(parentName, field.name)}_operator`;
const listOperators = ['in', 'not_in', 'all'];
if (!field.required) operators.push('exists');
return new GraphQLInputObjectType({
name,
fields: operators.reduce((fields, operator) => {
let gqlType: GraphQLType;
if (listOperators.indexOf(operator) > -1) {
gqlType = new GraphQLList(type);
} else if (operator === 'exists') {
gqlType = GraphQLBoolean;
} else {
gqlType = type;
}
return {
...fields,
[operator]: {
type: gqlType,
},
};
}, {}),
});
}
Example #4
Source File: schema-resolver.ts From graphql-mesh with MIT License | 6 votes |
private resolveInputType(soapType: SoapType): GraphQLInputType {
if (this.alreadyResolved.has(soapType)) {
return this.alreadyResolved.get(soapType);
}
if (typeof soapType === 'string') {
const customType: GraphQLInputType = this.options.customResolver.inputType(soapType);
if (customType) {
this.alreadyResolved.set(soapType, customType);
return customType;
}
} else if (soapType?.name && soapType?.fields?.length > 0) {
const objectType: GraphQLInputObjectType = this.createObjectType(soapType);
if (objectType) {
this.alreadyResolved.set(soapType, objectType);
return objectType;
}
}
this.logger.warn(`could not resolve input type '${soapType}'; using GraphQLString`);
this.alreadyResolved.set(soapType, GraphQLString);
return GraphQLString;
}
Example #5
Source File: Generator.ts From graphql-ts-client with MIT License | 6 votes |
private async generateInputTypes(inputTypes: GraphQLInputObjectType[]) {
const dir = join(this.config.targetDir, "inputs");
const promises = inputTypes.map(async type => {
const stream = createStreamAndLog(
join(dir, `${type.name}.ts`)
);
new InputWriter(type, stream, this.config).write();
await stream.end();
});
await Promise.all([
...promises,
this.writeSimpleIndex(dir, inputTypes)
]);
}
Example #6
Source File: Writer.ts From graphql-ts-client with MIT License | 6 votes |
protected importType(type: GraphQLType) {
if (this.imported) {
throw new Error("Writer's importing has been terminated");
}
if (type instanceof GraphQLNonNull) {
this.importType(type.ofType);
} else if (type instanceof GraphQLList) {
this.importType(type.ofType);
} else if (type instanceof GraphQLInputObjectType) {
this.importedTypes.add(type);
} else if (type instanceof GraphQLEnumType) {
this.importedTypes.add(type);
} else if (type instanceof GraphQLScalarType && this.config.scalarTypeMap !== undefined) {
const mappedType = this.config.scalarTypeMap[type.name];
if (typeof mappedType == 'object') {
const importSource = mappedType.importSource;
let set = this.importedScalarTypes.get(importSource);
if (set === undefined) {
set = new Set<string>();
this.importedScalarTypes.set(importSource, set);
}
set.add(mappedType.typeName);
};
}
}
Example #7
Source File: isRequired.test.ts From amplify-codegen with Apache License 2.0 | 6 votes |
describe('isRequired', () => {
const testObj = new GraphQLInputObjectType({
name: 'Address',
fields: {
street: { type: GraphQLString },
requiredInt: { type: new GraphQLNonNull(GraphQLInt) },
},
});
it('should return false for null types', () => {
expect(isRequired(testObj.getFields().street.type)).toEqual(false);
});
it('should return true for non null types', () => {
expect(isRequired(testObj.getFields().requiredInt.type)).toEqual(true);
});
});
Example #8
Source File: codeGeneration.ts From amplify-codegen with Apache License 2.0 | 6 votes |
function structDeclarationForInputObjectType(generator: CodeGenerator, type: GraphQLInputObjectType) {
const interfaceName = type.name;
interfaceDeclaration(
generator,
{
interfaceName,
},
() => {
const properties = propertiesFromFields(generator.context, Object.values(type.getFields()));
properties.forEach(property => propertyDeclaration(generator, { ...property }));
},
);
}
Example #9
Source File: codeGeneration.ts From amplify-codegen with Apache License 2.0 | 6 votes |
function printEnumsAndInputObjects(generator: FlowAPIGenerator, context: CompilerContext) {
generator.printer.enqueue(stripIndent`
//==============================================================
// START Enums and Input Objects
// All enums and input objects are included in every output file
// for now, but this will be changed soon.
// TODO: Link to issue to fix this.
//==============================================================
`);
context.typesUsed
.filter(type => type instanceof GraphQLEnumType)
.forEach(enumType => {
generator.typeAliasForEnumType(enumType as GraphQLEnumType);
});
context.typesUsed
.filter(type => type instanceof GraphQLInputObjectType)
.forEach(inputObjectType => {
generator.typeAliasForInputObjectType(inputObjectType as GraphQLInputObjectType);
});
generator.printer.enqueue(stripIndent`
//==============================================================
// END Enums and Input Objects
//==============================================================
`);
}
Example #10
Source File: language.ts From amplify-codegen with Apache License 2.0 | 6 votes |
public inputObjectDeclaration(inputObjectType: GraphQLInputObjectType) {
const { name, description } = inputObjectType;
const fieldMap = inputObjectType.getFields();
const fields: ObjectProperty[] = Object.keys(inputObjectType.getFields()).map((fieldName: string) => {
const field = fieldMap[fieldName];
return {
name: fieldName,
annotation: this.typeAnnotationFromGraphQLType(field.type),
};
});
const typeAlias = this.typeAliasObject(name, fields);
typeAlias.leadingComments = [
{
type: 'CommentLine',
value: ` ${description}`,
} as t.CommentLine,
];
return typeAlias;
}
Example #11
Source File: serializeToJSON.ts From amplify-codegen with Apache License 2.0 | 6 votes |
function serializeInputObjectType(type: GraphQLInputObjectType) {
const { name, description } = type;
const fields = Object.values(type.getFields());
return {
kind: 'InputObjectType',
name,
description,
fields: fields.map(field => ({
name: field.name,
type: String(field.type),
description: field.description,
defaultValue: field.defaultValue,
})),
};
}
Example #12
Source File: InputWriter.ts From graphql-ts-client with MIT License | 6 votes |
protected importingBehavior(type: GraphQLNamedType): ImportingBehavior {
if (type === this.inputType) {
return "SELF";
}
if (type instanceof GraphQLInputObjectType) {
return "SAME_DIR";
}
return "OTHER_DIR";
}
Example #13
Source File: Writer.ts From graphql-ts-client with MIT License | 5 votes |
write() {
this.prepareImportings();
this.imported = true;
for (const importStatement of this.importStatements) {
this.stream.write(importStatement);
this.stream.write("\n");
}
for (const importedType of this.importedTypes) {
const behavior = this.importingBehavior(importedType);
if (behavior === 'SELF') {
continue;
}
if (behavior === 'SAME_DIR') {
this.stream.write(`import type {${importedType.name}} from '.';\n`);
} else {
let subDir: string;
if (importedType instanceof GraphQLInputObjectType) {
subDir = "inputs";
} else if (importedType instanceof GraphQLEnumType) {
subDir = "enums";
} else {
subDir = "fetchers";
}
if (this.isUnderGlobalDir()) {
this.stream.write(`import type {${importedType.name}} from './${subDir}';\n`);
} else {
this.stream.write(`import type {${importedType.name}} from '../${subDir}';\n`);
}
}
}
if (this.importedScalarTypes.size !== 0) {
const sourcePrefix = this.isUnderGlobalDir() ? "../" : "../../";
for (const [importSource, typeNames] of this.importedScalarTypes) {
this.stream.write(`import type { ${Array.from(typeNames).join(", ")} } from '${sourcePrefix}${importSource}';\n`);
}
}
if (this.importStatements.size !== 0 || this.importedTypes.size !== 0 || this.importedScalarTypes.size !== 0) {
this.stream.write("\n");
}
this.writeCode();
}
Example #14
Source File: InputWriter.ts From graphql-ts-client with MIT License | 5 votes |
constructor(
private readonly inputType: GraphQLInputObjectType,
stream: WriteStream,
config: GeneratorConfig
) {
super(stream, config);
}
Example #15
Source File: codeGeneration.ts From amplify-codegen with Apache License 2.0 | 5 votes |
structDeclarationForInputObjectType(type: GraphQLInputObjectType) {
const { name: structName, description } = type;
const adoptedProtocols = ['GraphQLMapConvertible'];
const fields = Object.values(type.getFields());
let properties = fields.map(this.helpers.propertyFromInputField, this.helpers);
// File input should have localUri and mimeType which is used only in client
if (isS3Field(type)) {
properties = [
...properties,
...(properties.find(p => p.name === 'localUri')
? []
: [
{
propertyName: 'localUri',
name: 'localUri',
typeName: 'String',
isOptional: false,
description: '',
},
]),
...(properties.find(p => p.name === 'mimeType')
? []
: [
{
propertyName: 'mimeType',
name: 'mimeType',
typeName: 'String',
isOptional: false,
description: '',
},
]),
];
}
this.structDeclaration({ structName, description: description || undefined, adoptedProtocols }, () => {
this.printOnNewline(`public var graphQLMap: GraphQLMap`);
this.printNewlineIfNeeded();
this.printOnNewline(`public init`);
this.print('(');
this.print(
join(
properties.map(({ propertyName, typeName, isOptional }) =>
join([`${escapeIdentifierIfNeeded(propertyName)}: ${typeName}`, isOptional && ' = nil'])
),
', '
)
);
this.print(')');
this.withinBlock(() => {
this.printOnNewline(
wrap(
`graphQLMap = [`,
join(properties.map(({ name, propertyName }) => `"${name}": ${escapeIdentifierIfNeeded(propertyName)}`), ', ') || ':',
`]`
)
);
});
for (const { name, propertyName, typeName, description } of properties) {
this.printNewlineIfNeeded();
this.comment(description || undefined);
this.printOnNewline(`public var ${escapeIdentifierIfNeeded(propertyName)}: ${typeName}`);
this.withinBlock(() => {
this.printOnNewline('get');
this.withinBlock(() => {
this.printOnNewline(`return graphQLMap["${name}"] as! ${typeName}`);
});
this.printOnNewline('set');
this.withinBlock(() => {
this.printOnNewline(`graphQLMap.updateValue(newValue, forKey: "${name}")`);
});
});
}
});
}
Example #16
Source File: Writer.ts From graphql-ts-client with MIT License | 5 votes |
protected typeRef(
type: GraphQLType,
objectRender?: string | ((type: GraphQLObjectType | GraphQLInterfaceType, field: GraphQLField<any, any>) => boolean)
) {
if (type instanceof GraphQLScalarType) {
const mappedType =
(this.config.scalarTypeMap ?? EMPTY_MAP)[type.name]
?? SCALAR_MAP[type.name];
if (mappedType === undefined) {
throw new Error(`Unknown scalar type ${type.name}`);
}
if (typeof mappedType === 'string') {
this.text(mappedType);
} else {
this.text(mappedType.typeName);
}
} else if (type instanceof GraphQLObjectType ||
type instanceof GraphQLInterfaceType ||
type instanceof GraphQLUnionType
) {
if (typeof objectRender === "string") {
this.text(objectRender);
} else if (type instanceof GraphQLUnionType) {
this.enter("BLANK");
for (const itemType of type.getTypes()) {
this.separator(" | ");
this.text(itemType.name);
}
this.leave();
} else if (typeof objectRender === 'function') {
this.scope({type: "BLOCK", multiLines: true}, () => {
const fieldMap = type.getFields();
for (const fieldName in fieldMap) {
const field = fieldMap[fieldName];
if (objectRender(type, field)) {
this.separator(", ");
this.text("readonly ");
this.text(fieldName);
this.text(": ");
this.typeRef(field.type, objectRender);
}
}
});
} else {
this.text(type.name);
}
} else if (type instanceof GraphQLEnumType || type instanceof GraphQLInputObjectType) {
this.text(type.name);
} else if (type instanceof GraphQLNonNull) {
this.typeRef(type.ofType, objectRender);
} else if (type instanceof GraphQLList) {
if (type.ofType instanceof GraphQLNonNull) {
if (!this.config.arrayEditable) {
this.text("readonly ");
}
this.typeRef(type.ofType, objectRender);
this.text("[]");
} else {
if (!this.config.arrayEditable) {
this.text("Readonly");
}
this.text("Array<");
this.typeRef(type.ofType, objectRender);
this.text(" | undefined>");
}
}
}
Example #17
Source File: buildWhereInputType.ts From payload with MIT License | 5 votes |
buildWhereInputType = (name: string, fields: Field[], parentName: string): GraphQLInputObjectType => {
// This is the function that builds nested paths for all
// field types with nested paths.
const fieldTypes = fields.reduce((schema, field) => {
if (!fieldIsPresentationalOnly(field) && !field.hidden) {
const getFieldSchema = fieldToSchemaMap(parentName)[field.type];
if (getFieldSchema) {
const fieldSchema = getFieldSchema(field);
if (fieldHasSubFields(field)) {
return {
...schema,
...(fieldSchema.reduce((subFields, subField) => ({
...subFields,
[formatName(subField.key)]: subField.type,
}), {})),
};
}
return {
...schema,
[formatName(field.name)]: fieldSchema,
};
}
}
return schema;
}, {});
fieldTypes.id = {
type: withOperators(
{ name: 'id' } as FieldAffectingData,
GraphQLJSON,
parentName,
[...operators.equality, ...operators.contains],
),
};
const fieldName = formatName(name);
return new GraphQLInputObjectType({
name: `${fieldName}_where`,
fields: {
...fieldTypes,
OR: {
type: new GraphQLList(new GraphQLInputObjectType({
name: `${fieldName}_where_or`,
fields: fieldTypes,
})),
},
AND: {
type: new GraphQLList(new GraphQLInputObjectType({
name: `${fieldName}_where_and`,
fields: fieldTypes,
})),
},
},
});
}
Example #18
Source File: InputWriter.d.ts From graphql-ts-client with MIT License | 5 votes |
constructor(inputType: GraphQLInputObjectType, stream: WriteStream, config: GeneratorConfig);
Example #19
Source File: codeGeneration.ts From amplify-codegen with Apache License 2.0 | 5 votes |
typeDeclarationForGraphQLType(type: GraphQLType) {
if (type instanceof GraphQLEnumType) {
this.enumerationDeclaration(type);
} else if (type instanceof GraphQLInputObjectType) {
this.structDeclarationForInputObjectType(type);
}
}
Example #20
Source File: codeGeneration.ts From amplify-codegen with Apache License 2.0 | 5 votes |
public typeAliasForInputObjectType(inputObjectType: GraphQLInputObjectType) {
this.printer.enqueue(this.inputObjectDeclaration(inputObjectType));
}
Example #21
Source File: objectType.ts From genql with MIT License | 5 votes |
objectType = (
type: GraphQLObjectType | GraphQLInterfaceType | GraphQLInputObjectType,
ctx: RenderContext,
) => {
const typeObj: FieldMap<string> = Object.keys(type.getFields()).reduce<
FieldMap<string>
>((r, f) => {
const field = type.getFields()[f]
const namedType = getNamedType(field.type)
const fieldObj: Field<string> = { type: namedType.name }
r[f] = fieldObj
const args: GraphQLArgument[] =
(<GraphQLField<any, any>>field).args || []
if (args.length > 0) {
fieldObj.args = args.reduce<ArgMap<string>>((r, a) => {
const concreteType = a.type.toString()
const typename = getNamedType(a.type).name
r[a.name] = [typename]
if (typename !== concreteType) {
r[a.name]?.push(concreteType)
}
return r
}, {})
}
return r
}, {})
if (isInterfaceType(type) && ctx.schema) {
ctx.schema.getPossibleTypes(type).map((t) => {
if (!isEmpty(typeObj)) {
typeObj[`on_${t.name}`] = { type: t.name }
}
})
}
if (!isEmpty(typeObj)) {
typeObj.__typename = { type: 'String' }
}
// const scalar = Object.keys(type.getFields())
// .map(f => type.getFields()[f])
// .filter(f => isScalarType(getNamedType(f.type)) || isEnumType(getNamedType(f.type)))
// .map(f => f.name)
// if (scalar.length > 0) typeObj.scalar = scalar
return typeObj
}
Example #22
Source File: schema-resolver.ts From graphql-mesh with MIT License | 5 votes |
private createObjectType(soapType: SoapObjectType): GraphQLInputObjectType {
return new GraphQLInputObjectType(this.createObjectTypeConfig(soapType));
}
Example #23
Source File: example_api.test.ts From graphql-mesh with MIT License | 5 votes |
test('Required properties for input object types', () => {
const userInputType = createdSchema.getType('UserInput') as GraphQLInputObjectType;
// The exclamation mark shows that it is a required (non-nullable) property
expect(userInputType.toConfig().fields.address.type.toString()).toEqual('AddressInput!');
expect(userInputType.toConfig().fields.address2.type.toString()).toEqual('AddressInput');
});
Example #24
Source File: types.ts From tql with MIT License | 4 votes |
transform = (
ast: DocumentNode,
schema: GraphQLSchema
): ASTVisitor => {
// @note needed to serialize inline enum values correctly at runtime
const enumValues = new Set<string>();
return {
[Kind.DIRECTIVE_DEFINITION]: () => null,
[Kind.SCALAR_TYPE_DEFINITION]: () => null,
[Kind.ENUM_TYPE_DEFINITION]: (node) => {
const typename = node.name.value;
const values = node.values?.map((v) => v.name.value) ?? [];
const printMember = (member: string): string => {
return `${member} = "${member}"`;
};
return code`
export enum ${typename} {
${values.map(printMember).join(",\n")}
}
`;
},
[Kind.ENUM_VALUE_DEFINITION]: (node) => {
enumValues.add(node.name.value);
return null;
},
[Kind.INPUT_OBJECT_TYPE_DEFINITION]: (node) => {
const typename = node.name.value;
const type = schema.getType(typename);
invariant(
type instanceof GraphQLInputObjectType,
`Type "${typename}" was not instance of expected class GraphQLInputObjectType.`
);
const fields = Object.values(type.getFields());
const printField = (field: GraphQLInputField) => {
const isList = listType(field.type);
const isNonNull = isNonNullType(field.type);
const baseType = inputType(field.type);
let tsType: string;
if (baseType instanceof GraphQLScalarType) {
tsType = toPrimitive(baseType);
} else if (baseType instanceof GraphQLEnumType) {
tsType = baseType.name;
} else if (baseType instanceof GraphQLInputObjectType) {
tsType = "I" + baseType.name;
} else {
throw new Error("Unable to render inputField!");
}
return [
field.name,
isNonNull ? ":" : "?:",
" ",
tsType,
isList ? "[]" : "",
].join("");
};
return code`
export interface I${typename} {
${fields.map(printField).join("\n")}
}
`;
},
[Kind.OBJECT_TYPE_DEFINITION]: (node) => {
const typename = node.name.value;
const type = schema.getType(typename);
invariant(
type instanceof GraphQLObjectType,
`Type "${typename}" was not instance of expected class GraphQLObjectType.`
);
const fields = Object.values(type.getFields());
const interfaces = type.getInterfaces();
// @note TypeScript only requires new fields to be defined on interface extendors
const interfaceFields = interfaces.flatMap((i) =>
Object.values(i.getFields()).map((field) => field.name)
);
const uncommonFields = fields.filter(
(field) => !interfaceFields.includes(field.name)
);
// @todo extend any implemented interfaces
// @todo only render fields unique to this type
const extensions =
interfaces.length > 0
? `extends ${interfaces.map((i) => "I" + i.name).join(", ")}`
: "";
return code`
export interface I${typename} ${extensions} {
readonly __typename: ${`"${typename}"`}
${uncommonFields.map(printField).join("\n")}
}
`;
},
[Kind.INTERFACE_TYPE_DEFINITION]: (node) => {
const typename = node.name.value;
const type = schema.getType(typename);
invariant(
type instanceof GraphQLInterfaceType,
`Type "${typename}" was not instance of expected class GraphQLInterfaceType.`
);
// @note Get all implementors of this union
const implementations = schema
.getPossibleTypes(type)
.map((type) => type.name);
const fields = Object.values(type.getFields());
return code`
export interface I${typename} {
readonly __typename: ${implementations
.map((type) => `"${type}"`)
.join(" | ")}
${fields.map(printField).join("\n")}
}
`;
},
[Kind.UNION_TYPE_DEFINITION]: (node) => {
const typename = node.name.value;
const type = schema.getType(typename);
invariant(
type instanceof GraphQLUnionType,
`Type "${typename}" was not instance of expected class GraphQLUnionType.`
);
// @note Get all implementors of this union
const implementations = schema
.getPossibleTypes(type)
.map((type) => type.name);
return code`
export type ${"I" + type.name} = ${implementations
.map((type) => `I${type}`)
.join(" | ")}
`;
},
[Kind.SCHEMA_DEFINITION]: (_) => {
return null;
},
};
}
Example #25
Source File: fieldToWhereInputSchemaMap.ts From payload with MIT License | 4 votes |
fieldToSchemaMap: (parentName: string) => any = (parentName: string) => ({
number: (field: NumberField) => {
const type = GraphQLFloat;
return {
type: withOperators(
field,
type,
parentName,
[...operators.equality, ...operators.comparison],
),
};
},
text: (field: TextField) => {
const type = GraphQLString;
return {
type: withOperators(
field,
type,
parentName,
[...operators.equality, 'like', 'contains'],
),
};
},
email: (field: EmailField) => {
const type = EmailAddressResolver;
return {
type: withOperators(
field,
type,
parentName,
[...operators.equality, 'like', 'contains'],
),
};
},
textarea: (field: TextareaField) => {
const type = GraphQLString;
return {
type: withOperators(
field,
type,
parentName,
[...operators.equality, 'like', 'contains'],
),
};
},
richText: (field: RichTextField) => {
const type = GraphQLJSON;
return {
type: withOperators(
field,
type,
parentName,
[...operators.equality, 'like', 'contains'],
),
};
},
code: (field: CodeField) => {
const type = GraphQLString;
return {
type: withOperators(
field,
type,
parentName,
[...operators.equality, 'like', 'contains'],
),
};
},
radio: (field: RadioField) => ({
type: withOperators(
field,
new GraphQLEnumType({
name: `${combineParentName(parentName, field.name)}_Input`,
values: field.options.reduce((values, option) => {
if (optionIsObject(option)) {
return {
...values,
[formatName(option.value)]: {
value: option.value,
},
};
}
return {
...values,
[formatName(option)]: {
value: option,
},
};
}, {}),
}),
parentName,
[...operators.equality, 'like', 'contains'],
),
}),
date: (field: DateField) => {
const type = DateTimeResolver;
return {
type: withOperators(
field,
type,
parentName,
[...operators.equality, ...operators.comparison, 'like'],
),
};
},
point: (field: PointField) => {
const type = GraphQLList(GraphQLFloat);
return {
type: withOperators(
field,
type,
parentName,
[...operators.equality, ...operators.comparison, ...operators.geo],
),
};
},
relationship: (field: RelationshipField) => {
let type = withOperators(
field,
GraphQLString,
parentName,
[...operators.equality, ...operators.contains],
);
if (Array.isArray(field.relationTo)) {
type = new GraphQLInputObjectType({
name: `${combineParentName(parentName, field.name)}_Relation`,
fields: {
relationTo: {
type: new GraphQLEnumType({
name: `${combineParentName(parentName, field.name)}_Relation_RelationTo`,
values: field.relationTo.reduce((values, relation) => ({
...values,
[formatName(relation)]: {
value: relation,
},
}), {}),
}),
},
value: { type: GraphQLString },
},
});
}
return { type };
},
upload: (field: UploadField) => ({
type: withOperators(
field,
GraphQLString,
parentName,
[...operators.equality],
),
}),
checkbox: (field: CheckboxField) => ({
type: withOperators(
field,
GraphQLBoolean,
parentName,
[...operators.equality],
),
}),
select: (field: SelectField) => ({
type: withOperators(
field,
new GraphQLEnumType({
name: `${combineParentName(parentName, field.name)}_Input`,
values: field.options.reduce((values, option) => {
if (typeof option === 'object' && option.value) {
return {
...values,
[formatName(option.value)]: {
value: option.value,
},
};
}
if (typeof option === 'string') {
return {
...values,
[option]: {
value: option,
},
};
}
return values;
}, {}),
}),
parentName,
[...operators.equality, ...operators.contains],
),
}),
array: (field: ArrayField) => recursivelyBuildNestedPaths(parentName, field),
group: (field: GroupField) => recursivelyBuildNestedPaths(parentName, field),
row: (field: RowField) => field.fields.reduce((rowSchema, rowField) => {
const getFieldSchema = fieldToSchemaMap(parentName)[rowField.type];
if (getFieldSchema) {
const rowFieldSchema = getFieldSchema(rowField);
if (fieldHasSubFields(rowField)) {
return [
...rowSchema,
...rowFieldSchema,
];
}
if (fieldAffectsData(rowField)) {
return [
...rowSchema,
{
key: rowField.name,
type: rowFieldSchema,
},
];
}
}
return rowSchema;
}, []),
})
Example #26
Source File: generateSchema.ts From davinci with MIT License | 4 votes |
generateGQLSchema = ({
type,
parentType,
key,
schemas = {},
isInput = false,
operationType,
resolverMetadata,
partial,
transformMetadata = _.identity
}: IGenerateGQLSchemaArgs) => {
// grab meta infos
// maybe it's a decorated class, let's try to get the fields metadata
const parentFieldsMetadata: IFieldDecoratorMetadata[] = parentType?.prototype
? getFieldsMetadata(parentType.prototype.constructor, isInput, operationType, resolverMetadata)
: [];
const meta = _fp.find({ key }, parentFieldsMetadata) || ({} as IFieldDecoratorMetadata);
const metadata = transformMetadata(meta, { isInput, type, parentType, schemas });
const isRequired = !partial && metadata.opts?.required;
// it's a primitive type, simple case
if ([String, Number, Boolean, Date, Object].includes(type)) {
const gqlType = scalarDict[type.name.toLowerCase()];
const schema = isRequired ? new GraphQLNonNull(gqlType) : gqlType;
return { schema, schemas };
}
// it's an array => recursively call makeSchema on the first array element
if (Array.isArray(type)) {
const gqlSchema = generateGQLSchema({
type: type[0],
parentType,
schemas,
key,
isInput,
operationType,
resolverMetadata,
partial,
transformMetadata
});
const gqlType = new GraphQLList(gqlSchema.schema);
const schema = isRequired ? new GraphQLNonNull(gqlType) : gqlType;
return { schema, schemas: _.merge(schemas, gqlSchema.schemas) };
}
// it's a complex type => create nested types
if (typeof type === 'function' || typeof type === 'object') {
const suffix = isInput
? _.compact([partial && 'Partial', _.upperFirst(operationType || ''), 'Input']).join('')
: '';
const typeMetadata = Reflector.getMetadata('davinci:graphql:types', type) || {};
const name = `${typeMetadata.name || type.name || key}${suffix}`;
// existing type, let's return it
if (schemas[name]) {
return { schema: schemas[name], schemas };
}
if (type instanceof UnionType) {
const types = Array.isArray(type.types)
? type.types.map(
t =>
generateGQLSchema({
type: t,
parentType,
schemas,
key,
isInput,
operationType,
resolverMetadata,
partial,
transformMetadata
}).schema
)
: type.types;
const unionTypeConfig = {
..._.omit(metadata.opts, ['type']),
name,
types,
resolveType: type.resolveType
};
schemas[name] = isRequired
? new GraphQLNonNull(new GraphQLUnionType(unionTypeConfig))
: new GraphQLUnionType(unionTypeConfig);
} else {
const objTypeConfig: any = {
...metadata.opts,
name,
// eslint-disable-next-line no-use-before-define
fields: createObjectFields({
parentType: type,
schemas,
isInput,
operationType,
resolverMetadata,
partial,
transformMetadata
})
};
const ObjectType = isInput ? GraphQLInputObjectType : GraphQLObjectType;
schemas[name] = isRequired
? new GraphQLNonNull(new ObjectType(objTypeConfig))
: new ObjectType(objTypeConfig);
}
return { schema: schemas[name], schemas };
}
return null;
}
Example #27
Source File: buildMutationInputType.ts From payload with MIT License | 4 votes |
function buildMutationInputType(name: string, fields: Field[], parentName: string, forceNullable = false): GraphQLInputObjectType {
const fieldToSchemaMap = {
number: (field: NumberField) => {
const type = field.name === 'id' ? GraphQLInt : GraphQLFloat;
return { type: withNullableType(field, type, forceNullable) };
},
text: (field: TextField) => ({ type: withNullableType(field, GraphQLString, forceNullable) }),
email: (field: EmailField) => ({ type: withNullableType(field, GraphQLString, forceNullable) }),
textarea: (field: TextareaField) => ({ type: withNullableType(field, GraphQLString, forceNullable) }),
richText: (field: RichTextField) => ({ type: withNullableType(field, GraphQLJSON, forceNullable) }),
code: (field: CodeField) => ({ type: withNullableType(field, GraphQLString, forceNullable) }),
date: (field: DateField) => ({ type: withNullableType(field, GraphQLString, forceNullable) }),
upload: (field: UploadField) => ({ type: withNullableType(field, GraphQLString, forceNullable) }),
radio: (field: RadioField) => ({ type: withNullableType(field, GraphQLString, forceNullable) }),
point: (field: PointField) => ({ type: withNullableType(field, GraphQLList(GraphQLFloat), forceNullable) }),
checkbox: () => ({ type: GraphQLBoolean }),
select: (field: SelectField) => {
const formattedName = `${combineParentName(parentName, field.name)}_MutationInput`;
let type: GraphQLType = new GraphQLEnumType({
name: formattedName,
values: field.options.reduce((values, option) => {
if (typeof option === 'object' && option.value) {
return {
...values,
[formatName(option.value)]: {
value: option.value,
},
};
}
if (typeof option === 'string') {
return {
...values,
[option]: {
value: option,
},
};
}
return values;
}, {}),
});
type = field.hasMany ? new GraphQLList(type) : type;
type = withNullableType(field, type, forceNullable);
return { type };
},
relationship: (field: RelationshipField) => {
const { relationTo } = field;
type PayloadGraphQLRelationshipType = GraphQLScalarType | GraphQLList<GraphQLScalarType> | GraphQLInputObjectType;
let type: PayloadGraphQLRelationshipType;
if (Array.isArray(relationTo)) {
const fullName = `${combineParentName(parentName, field.label === false ? toWords(field.name, true) : field.label)}RelationshipInput`;
type = new GraphQLInputObjectType({
name: fullName,
fields: {
relationTo: {
type: new GraphQLEnumType({
name: `${fullName}RelationTo`,
values: relationTo.reduce((values, option) => ({
...values,
[formatName(option)]: {
value: option,
},
}), {}),
}),
},
value: { type: GraphQLJSON },
},
});
} else {
type = getCollectionIDType(payload.collections[relationTo].config);
}
return { type: field.hasMany ? new GraphQLList(type) : type };
},
array: (field: ArrayField) => {
const fullName = combineParentName(parentName, field.label === false ? toWords(field.name, true) : field.label);
let type: GraphQLType | GraphQLList<GraphQLType> = buildMutationInputType(fullName, field.fields, fullName);
type = new GraphQLList(withNullableType(field, type, forceNullable));
return { type };
},
group: (field: GroupField) => {
const requiresAtLeastOneField = field.fields.some((subField) => (!fieldIsPresentationalOnly(subField) && subField.required && !subField.localized));
const fullName = combineParentName(parentName, field.label === false ? toWords(field.name, true) : field.label);
let type: GraphQLType = buildMutationInputType(fullName, field.fields, fullName);
if (requiresAtLeastOneField) type = new GraphQLNonNull(type);
return { type };
},
blocks: () => ({ type: GraphQLJSON }),
row: (field: RowField) => field.fields.reduce((acc, rowField: RowField) => {
const getFieldSchema = fieldToSchemaMap[rowField.type];
if (getFieldSchema) {
const fieldSchema = getFieldSchema(rowField);
return [
...acc,
fieldSchema,
];
}
return acc;
}, []),
};
const fieldTypes = fields.reduce((schema, field: Field) => {
if (!fieldIsPresentationalOnly(field) && !field.hidden) {
const getFieldSchema: (field: Field) => { type: GraphQLType } = fieldToSchemaMap[field.type];
if (getFieldSchema) {
const fieldSchema = getFieldSchema(field);
if (fieldHasSubFields(field) && Array.isArray(fieldSchema)) {
return fieldSchema.reduce((acc, subField, i) => {
const currentSubField = field.fields[i];
if (fieldAffectsData(currentSubField)) {
return {
...acc,
[currentSubField.name]: subField,
};
}
return {
...acc,
...fieldSchema,
};
}, schema);
}
if (fieldAffectsData(field)) {
return {
...schema,
[field.name]: fieldSchema,
};
}
return {
...schema,
...fieldSchema,
};
}
}
return schema;
}, {});
const fieldName = formatName(name);
return new GraphQLInputObjectType({
name: `mutation${fieldName}Input`,
fields: {
...fieldTypes,
},
});
}
Example #28
Source File: schema.ts From Deep-Lynx with MIT License | 4 votes |
inputFieldsForTransformation(transformation: TypeTransformation): {[key: string]: any} {
const fields: {[key: string]: any} = {};
transformation.keys?.forEach((key) => {
if (!key.column_name || !key.value_type) return;
const propertyName = stringToValidPropertyName(key.column_name);
switch (key.value_type) {
// because we have no specification on our internal number type, we
// must set this as a float for now
case 'number': {
fields[propertyName] = {
type: new GraphQLInputObjectType({
name: stringToValidPropertyName(`z_${transformation.id}` + key.column_name),
fields: {
operator: {type: GraphQLString},
value: {type: new GraphQLList(GraphQLInt)},
},
}),
};
break;
}
case 'float': {
fields[propertyName] = {
type: new GraphQLInputObjectType({
name: stringToValidPropertyName(`z_${transformation.id}` + key.column_name),
fields: {
operator: {type: GraphQLString},
value: {type: new GraphQLList(GraphQLFloat)},
},
}),
};
break;
}
case 'boolean': {
fields[propertyName] = {
type: new GraphQLInputObjectType({
name: stringToValidPropertyName(`z_${transformation.id}` + key.column_name),
fields: {
operator: {type: GraphQLString},
value: {type: new GraphQLList(GraphQLBoolean)},
},
}),
};
break;
}
case 'string' || 'date' || 'file': {
fields[propertyName] = {
type: new GraphQLInputObjectType({
name: stringToValidPropertyName(`z_${transformation.id}` + key.column_name),
fields: {
operator: {type: GraphQLString},
value: {type: new GraphQLList(GraphQLString)},
},
}),
};
break;
}
case 'list': {
fields[propertyName] = {
type: new GraphQLInputObjectType({
name: stringToValidPropertyName(`z_${transformation.id}` + key.column_name),
fields: {
operator: {type: GraphQLString},
value: {type: new GraphQLList(GraphQLJSON)},
},
}),
};
break;
}
default: {
fields[propertyName] = {
type: new GraphQLInputObjectType({
name: stringToValidPropertyName(`z_${transformation.id}` + key.column_name),
fields: {
operator: {type: GraphQLString},
value: {type: new GraphQLList(GraphQLString)},
},
}),
};
}
}
});
return fields;
}
Example #29
Source File: schema.ts From Deep-Lynx with MIT License | 4 votes |
// 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,
}),
}),
),
);
}