Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
getGqlTypes({ schemaName }) {
const schemaAccess = this.access[schemaName];
// https://github.com/opencrud/opencrud/blob/master/spec/2-relational/2-2-queries/2-2-3-filters.md#boolean-expressions
const types = [];
if (
schemaAccess.read ||
schemaAccess.create ||
schemaAccess.update ||
schemaAccess.delete ||
schemaAccess.auth
) {
types.push(
...flatten(this.fields.map(field => field.getGqlAuxTypes({ schemaName }))),
`
""" ${this.schemaDoc || 'A keystone list'} """
type ${this.gqlNames.outputTypeName} {
"""
This virtual field will be resolved in one of the following ways (in this order):
1. Execution of 'labelResolver' set on the ${this.key} List config, or
2. As an alias to the field set on 'labelField' in the ${this.key} List config, or
3. As an alias to a 'name' field on the ${this.key} List (if one exists), or
4. As an alias to the 'id' field on the ${this.key} List.
"""
_label_: String
${flatten(
this.fields
.filter(field => field.access[schemaName].read) // If it's globally set to false, makes sense to never show it
.map(field =>
field.schemaDoc
getGqlQueries({ schemaName }) {
const schemaAccess = this.access[schemaName];
// All the auxiliary queries the fields want to add
const queries = flatten(this.fields.map(field => field.getGqlAuxQueries()));
// If `read` is either `true`, or a function (we don't care what the result
// of the function is, that'll get executed at a later time)
if (schemaAccess.read) {
queries.push(
`
""" Search for all ${this.gqlNames.outputTypeName} items which match the where clause. """
${this.gqlNames.listQueryName}(
${this.getGraphqlFilterFragment().join('\n')}
): [${this.gqlNames.outputTypeName}]`,
`
""" Search for the ${this.gqlNames.outputTypeName} item with the matching ID. """
${this.gqlNames.itemQueryName}(
where: ${this.gqlNames.whereUniqueInputName}!
): ${this.gqlNames.outputTypeName}`,
getTypeDefs({ schemaName }) {
// Aux lists are only there for typing and internal operations, they should
// not have any GraphQL operations performed on them
const firstClassLists = this.listsArray.filter(list => !list.isAuxList);
const mutations = unique(
flatten([
...firstClassLists.map(list => list.getGqlMutations({ schemaName })),
this._extendedMutations
.filter(({ access }) => access[schemaName])
.map(({ schema }) => schema),
])
);
// Fields can be represented multiple times within and between lists.
// If a field defines a `getGqlAuxTypes()` method, it will be
// duplicated.
// graphql-tools will blow up (rightly so) on duplicated types.
// Deduping here avoids that problem.
return [
...unique(flatten(this.listsArray.map(list => list.getGqlTypes({ schemaName })))),
...unique(
this._extendedTypes.filter(({ access }) => access[schemaName]).map(({ type }) => type)
[`${uniqueField}_every`]: {
// We use `ifNull` here to handle the case unique to mongo where a
// record may be entirely missing a field (or have the value set to
// `null`)
$eq: [fieldSize, many ? { $size: { $ifNull: [`$${field}`, []] } } : 1],
},
[`${uniqueField}_none`]: { $eq: [fieldSize, 0] },
[`${uniqueField}_some`]: { $gt: [fieldSize, 0] },
},
},
];
});
return [
relationshipIdTerm && { $match: relationshipIdTerm },
...flatten(relationshipPipelines),
matchTerm && { $match: matchTerm },
{ $addFields: { id: '$_id' } },
excludeFields && excludeFields.length && { $project: defaultObj(excludeFields, 0) },
...postJoinPipeline,
].filter(i => i);
}
getGqlMutations({ schemaName }) {
const schemaAccess = this.access[schemaName];
const mutations = flatten(this.fields.map(field => field.getGqlAuxMutations()));
// NOTE: We only check for truthy as it could be `true`, or a function (the
// function is executed later in the resolver)
const createFields = this.getFieldsWithAccess({ schemaName, access: 'create' });
if (schemaAccess.create && createFields.length) {
mutations.push(`
""" Create a single ${this.gqlNames.outputTypeName} item. """
${this.gqlNames.createMutationName}(
data: ${this.gqlNames.createInputName}
): ${this.gqlNames.outputTypeName}
`);
mutations.push(`
""" Create multiple ${this.gqlNames.outputTypeName} items. """
${this.gqlNames.createManyMutationName}(
.map(field => field.gqlQueryInputFields({ schemaName }))
).join('\n')}
}`,
// TODO: Include other `unique` fields and allow filtering by them
`
input ${this.gqlNames.whereUniqueInputName} {
id: ID!
}`
);
}
const updateFields = this.getFieldsWithAccess({ schemaName, access: 'update' });
if (schemaAccess.update && updateFields.length) {
types.push(`
input ${this.gqlNames.updateInputName} {
${flatten(updateFields.map(field => field.gqlUpdateInputFields)).join('\n')}
}
`);
types.push(`
input ${this.gqlNames.updateManyInputName} {
id: ID!
data: ${this.gqlNames.updateInputName}
}
`);
}
const createFields = this.getFieldsWithAccess({ schemaName, access: 'create' });
if (schemaAccess.create && createFields.length) {
types.push(`
input ${this.gqlNames.createInputName} {
${flatten(createFields.map(field => field.gqlCreateInputFields)).join('\n')}
}
.map(list => ({
type: list.gqlNames.outputTypeName,
fields: flatten(
list
.getFieldsRelatedTo(key)
.filter(field => field.access[schemaName].read)
.map(field => Object.keys(field.gqlOutputFieldResolvers({ schemaName })))
),
}))
.filter(({ fields }) => fields.length),