Files
payloadcms/src/graphql/schema/fieldToWhereInputSchemaMap.ts
2022-07-13 14:45:10 -07:00

280 lines
6.7 KiB
TypeScript

import {
GraphQLBoolean,
GraphQLEnumType,
GraphQLFloat,
GraphQLInputObjectType,
GraphQLList,
GraphQLString,
} from 'graphql';
import { DateTimeResolver, EmailAddressResolver } from 'graphql-scalars';
import { GraphQLJSON } from 'graphql-type-json';
import {
ArrayField,
CheckboxField,
CodeField, CollapsibleField, DateField,
EmailField, fieldAffectsData, fieldHasSubFields, GroupField,
NumberField, optionIsObject, PointField,
RadioField, RelationshipField,
RichTextField, RowField, SelectField,
TextareaField,
TextField, UploadField,
} from '../../fields/config/types';
import withOperators from './withOperators';
import operators from './operators';
import combineParentName from '../utilities/combineParentName';
import formatName from '../utilities/formatName';
import recursivelyBuildNestedPaths from './recursivelyBuildNestedPaths';
const 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, subField) => {
const getFieldSchema = fieldToSchemaMap(parentName)[subField.type];
if (getFieldSchema) {
const rowFieldSchema = getFieldSchema(subField);
if (fieldHasSubFields(subField)) {
return [
...rowSchema,
...rowFieldSchema,
];
}
if (fieldAffectsData(subField)) {
return [
...rowSchema,
{
key: subField.name,
type: rowFieldSchema,
},
];
}
}
return rowSchema;
}, []),
collapsible: (field: CollapsibleField) => field.fields.reduce((rowSchema, subField) => {
const getFieldSchema = fieldToSchemaMap(parentName)[subField.type];
if (getFieldSchema) {
const rowFieldSchema = getFieldSchema(subField);
if (fieldHasSubFields(subField)) {
return [
...rowSchema,
...rowFieldSchema,
];
}
if (fieldAffectsData(subField)) {
return [
...rowSchema,
{
key: subField.name,
type: rowFieldSchema,
},
];
}
}
return rowSchema;
}, []),
});
export default fieldToSchemaMap;