Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
297 lines
9.8 KiB
Plaintext
297 lines
9.8 KiB
Plaintext
import { GraphQLBoolean, GraphQLEnumType, GraphQLFloat, GraphQLInputObjectType, GraphQLInt, GraphQLList, GraphQLString } from 'graphql';
|
|
import { DateTimeResolver, EmailAddressResolver } from 'graphql-scalars';
|
|
import { optionIsObject } from 'payload/shared';
|
|
import { GraphQLJSON } from '../packages/graphql-type-json/index.js';
|
|
import { combineParentName } from '../utilities/combineParentName.js';
|
|
import { formatName } from '../utilities/formatName.js';
|
|
import { operators } from './operators.js';
|
|
const GeoJSONObject = new GraphQLInputObjectType({
|
|
name: 'GeoJSONObject',
|
|
fields: {
|
|
type: {
|
|
type: GraphQLString
|
|
},
|
|
coordinates: {
|
|
type: GraphQLJSON
|
|
}
|
|
}
|
|
});
|
|
const defaults = {
|
|
checkbox: {
|
|
operators: [
|
|
...operators.equality.map((operator)=>({
|
|
name: operator,
|
|
type: GraphQLBoolean
|
|
}))
|
|
]
|
|
},
|
|
code: {
|
|
operators: [
|
|
...[
|
|
...operators.equality,
|
|
...operators.partial
|
|
].map((operator)=>({
|
|
name: operator,
|
|
type: GraphQLString
|
|
}))
|
|
]
|
|
},
|
|
date: {
|
|
operators: [
|
|
...[
|
|
...operators.equality,
|
|
...operators.comparison,
|
|
'like'
|
|
].map((operator)=>({
|
|
name: operator,
|
|
type: DateTimeResolver
|
|
}))
|
|
]
|
|
},
|
|
email: {
|
|
operators: [
|
|
...[
|
|
...operators.equality,
|
|
...operators.partial,
|
|
...operators.contains
|
|
].map((operator)=>({
|
|
name: operator,
|
|
type: EmailAddressResolver
|
|
}))
|
|
]
|
|
},
|
|
json: {
|
|
operators: [
|
|
...[
|
|
...operators.equality,
|
|
...operators.partial,
|
|
...operators.geojson
|
|
].map((operator)=>({
|
|
name: operator,
|
|
type: GraphQLJSON
|
|
}))
|
|
]
|
|
},
|
|
number: {
|
|
operators: [
|
|
...[
|
|
...operators.equality,
|
|
...operators.comparison
|
|
].map((operator)=>({
|
|
name: operator,
|
|
type: (field)=>{
|
|
return field?.name === 'id' ? GraphQLInt : GraphQLFloat;
|
|
}
|
|
}))
|
|
]
|
|
},
|
|
point: {
|
|
operators: [
|
|
...[
|
|
...operators.equality,
|
|
...operators.comparison,
|
|
...operators.geo
|
|
].map((operator)=>({
|
|
name: operator,
|
|
type: new GraphQLList(GraphQLFloat)
|
|
})),
|
|
...operators.geojson.map((operator)=>({
|
|
name: operator,
|
|
/**
|
|
* @example:
|
|
* within: {
|
|
* type: "Polygon",
|
|
* coordinates: [[
|
|
* [0.0, 0.0],
|
|
* [1.0, 1.0],
|
|
* [1.0, 0.0],
|
|
* [0.0, 0.0],
|
|
* ]],
|
|
* }
|
|
* @example
|
|
* intersects: {
|
|
* type: "Point",
|
|
* coordinates: [ 0.5, 0.5 ]
|
|
* }
|
|
*/ type: GeoJSONObject
|
|
}))
|
|
]
|
|
},
|
|
radio: {
|
|
operators: [
|
|
...[
|
|
...operators.equality,
|
|
...operators.partial
|
|
].map((operator)=>({
|
|
name: operator,
|
|
type: (field, parentName)=>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
|
|
}
|
|
};
|
|
}, {})
|
|
})
|
|
}))
|
|
]
|
|
},
|
|
relationship: {
|
|
operators: [
|
|
...[
|
|
...operators.equality,
|
|
...operators.contains
|
|
].map((operator)=>({
|
|
name: operator,
|
|
type: GraphQLJSON
|
|
}))
|
|
]
|
|
},
|
|
richText: {
|
|
operators: [
|
|
...[
|
|
...operators.equality,
|
|
...operators.partial
|
|
].map((operator)=>({
|
|
name: operator,
|
|
type: GraphQLJSON
|
|
}))
|
|
]
|
|
},
|
|
select: {
|
|
operators: [
|
|
...[
|
|
...operators.equality,
|
|
...operators.contains
|
|
].map((operator)=>({
|
|
name: operator,
|
|
type: (field, parentName)=>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
|
|
}
|
|
};
|
|
}, {})
|
|
})
|
|
}))
|
|
]
|
|
},
|
|
text: {
|
|
operators: [
|
|
...[
|
|
...operators.equality,
|
|
...operators.partial,
|
|
...operators.contains
|
|
].map((operator)=>({
|
|
name: operator,
|
|
type: GraphQLString
|
|
}))
|
|
]
|
|
},
|
|
textarea: {
|
|
operators: [
|
|
...[
|
|
...operators.equality,
|
|
...operators.partial
|
|
].map((operator)=>({
|
|
name: operator,
|
|
type: GraphQLString
|
|
}))
|
|
]
|
|
},
|
|
upload: {
|
|
operators: [
|
|
...[
|
|
...operators.equality,
|
|
...operators.contains
|
|
].map((operator)=>({
|
|
name: operator,
|
|
type: GraphQLJSON
|
|
}))
|
|
]
|
|
}
|
|
};
|
|
const listOperators = [
|
|
'in',
|
|
'not_in',
|
|
'all'
|
|
];
|
|
const gqlTypeCache = {};
|
|
/**
|
|
* In GraphQL, you can use "where" as an argument to filter a collection. Example:
|
|
* { Posts(where: { title: { equals: "Hello" } }) { text } }
|
|
* This function defines the operators for a field's condition in the "where" argument of the collection (it thus gets called for every field).
|
|
* For example, in the example above, it would control that
|
|
* - "equals" is a valid operator for the "title" field
|
|
* - the accepted type of the "equals" argument has to be a string.
|
|
*
|
|
* @param field the field for which their valid operators inside a "where" argument is being defined
|
|
* @param parentName the name of the parent field (if any)
|
|
* @returns all the operators (including their types) which can be used as a condition for a given field inside a where
|
|
*/ export const withOperators = (field, parentName)=>{
|
|
if (!defaults?.[field.type]) {
|
|
throw new Error(`Error: ${field.type} has no defaults configured.`);
|
|
}
|
|
const name = `${combineParentName(parentName, field.name)}_operator`;
|
|
// Get the default operators for the field type which are hard-coded above
|
|
const fieldOperators = [
|
|
...defaults[field.type].operators
|
|
];
|
|
if (!('required' in field) || !field.required) {
|
|
fieldOperators.push({
|
|
name: 'exists',
|
|
type: fieldOperators[0].type
|
|
});
|
|
}
|
|
return new GraphQLInputObjectType({
|
|
name,
|
|
fields: fieldOperators.reduce((objectTypeFields, operator)=>{
|
|
// Get the type of the operator. It can be either static, or dynamic (=> a function)
|
|
let gqlType = typeof operator.type === 'function' ? operator.type(field, parentName) : operator.type;
|
|
// GraphQL does not allow types with duplicate names, so we use this cache to avoid that.
|
|
// Without this, select and radio fields would have the same name, and GraphQL would throw an error
|
|
// This usually only happens if a custom type is returned from the operator.type function
|
|
if (typeof operator.type === 'function' && 'name' in gqlType) {
|
|
if (gqlTypeCache[gqlType.name]) {
|
|
gqlType = gqlTypeCache[gqlType.name];
|
|
} else {
|
|
gqlTypeCache[gqlType.name] = gqlType;
|
|
}
|
|
}
|
|
if (listOperators.includes(operator.name)) {
|
|
gqlType = new GraphQLList(gqlType);
|
|
} else if (operator.name === 'exists') {
|
|
gqlType = GraphQLBoolean;
|
|
}
|
|
return {
|
|
...objectTypeFields,
|
|
[operator.name]: {
|
|
type: gqlType
|
|
}
|
|
};
|
|
}, {})
|
|
});
|
|
};
|
|
|
|
//# sourceMappingURL=withOperators.js.map |