@directus/api
Version:
Directus is a real-time API and App dashboard for managing SQL database content
53 lines (52 loc) • 2.41 kB
JavaScript
import { parseFilterFunctionPath } from '@directus/utils';
import { omit } from 'lodash-es';
import { parseArgs } from '../schema/parse-args.js';
import { getQuery } from '../schema/parse-query.js';
import { getAggregateQuery } from '../utils/aggregate-query.js';
import { replaceFragmentsInSelections } from '../utils/replace-fragments.js';
/**
* Generic resolver that's used for every "regular" items/system query. Converts the incoming GraphQL AST / fragments into
* Directus' query structure which is then executed by the services.
*/
export async function resolveQuery(gql, info) {
let collection = info.fieldName;
if (gql.scope === 'system')
collection = `directus_${collection}`;
const selections = replaceFragmentsInSelections(info.fieldNodes[0]?.selectionSet?.selections, info.fragments);
if (!selections)
return null;
const args = parseArgs(info.fieldNodes[0].arguments || [], info.variableValues);
let query;
const isAggregate = collection.endsWith('_aggregated') && collection in gql.schema.collections === false;
if (isAggregate) {
collection = collection.slice(0, -11);
query = await getAggregateQuery(args, selections, gql.schema, gql.accountability, collection);
}
else {
if (collection.endsWith('_by_id') && collection in gql.schema.collections === false) {
collection = collection.slice(0, -6);
}
query = await getQuery(args, gql.schema, selections, info.variableValues, gql.accountability, collection);
if (collection.endsWith('_by_version') && collection in gql.schema.collections === false) {
collection = collection.slice(0, -11);
query.versionRaw = true;
}
}
// Transform count(a.b.c) into a.b.count(c)
if (query.fields?.length) {
for (let fieldIndex = 0; fieldIndex < query.fields.length; fieldIndex++) {
query.fields[fieldIndex] = parseFilterFunctionPath(query.fields[fieldIndex]);
}
}
const result = await gql.read(collection, query, args['id']);
if (args['id'])
return result;
if (query.group) {
// for every entry in result add a group field based on query.group;
const aggregateKeys = Object.keys(query.aggregate ?? {});
result['map']((field) => {
field['group'] = omit(field, aggregateKeys);
});
}
return result;
}