Handle args on nested GQL query selections for plural queries

This commit is contained in:
Prathamesh Musale 2024-08-02 13:00:17 +05:30
parent 6557504b27
commit 1e057bec47

View File

@ -280,15 +280,10 @@ export class GraphDatabase {
// Filter out __typename field in GQL for loading relations. // Filter out __typename field in GQL for loading relations.
childSelections = childSelections.filter(selection => !(selection.kind === 'Field' && selection.name.value === '__typename')); childSelections = childSelections.filter(selection => !(selection.kind === 'Field' && selection.name.value === '__typename'));
// Parse arguments on a plural selection field // Parse selection's arguments
let relationWhere: Where = {}; let { where: relationWhere, queryOptions: relationQueryOptions } = this._getSelectionFieldArguments(selection, queryInfo);
let relationQueryOptions: QueryOptions = {};
if (isDerived || isArray) {
({ where: relationWhere, queryOptions: relationQueryOptions } = this._getSelectionFieldArguments(selection, queryInfo));
}
if (isDerived) { if (isDerived) {
// TODO: Merge with relationWhere
const where: Where = { const where: Where = {
[foreignKey]: [{ [foreignKey]: [{
value: entityData.id, value: entityData.id,
@ -320,7 +315,6 @@ export class GraphDatabase {
} }
if (isArray) { if (isArray) {
// TODO: Merge with relationWhere
const where: Where = { const where: Where = {
id: [{ id: [{
value: entityData[field], value: entityData[field],
@ -810,6 +804,7 @@ export class GraphDatabase {
queryInfo: GraphQLResolveInfo queryInfo: GraphQLResolveInfo
): Promise<void> { ): Promise<void> {
assert(selection.kind === 'Field'); assert(selection.kind === 'Field');
const field = selection.name.value; const field = selection.name.value;
const { entity: relationEntity, isArray, isDerived, field: foreignKey } = relations[field]; const { entity: relationEntity, isArray, isDerived, field: foreignKey } = relations[field];
let childSelections = selection.selectionSet?.selections || []; let childSelections = selection.selectionSet?.selections || [];
@ -817,6 +812,9 @@ export class GraphDatabase {
// Filter out __typename field in GQL for loading relations. // Filter out __typename field in GQL for loading relations.
childSelections = childSelections.filter(selection => !(selection.kind === 'Field' && selection.name.value === '__typename')); childSelections = childSelections.filter(selection => !(selection.kind === 'Field' && selection.name.value === '__typename'));
// Parse selection's arguments
let { where: relationWhere, queryOptions: relationQueryOptions } = this._getSelectionFieldArguments(selection, queryInfo);
if (isDerived) { if (isDerived) {
const where: Where = { const where: Where = {
[foreignKey]: [{ [foreignKey]: [{
@ -825,14 +823,20 @@ export class GraphDatabase {
operator: 'in' operator: 'in'
}] }]
}; };
relationWhere = _.mergeWith(relationWhere, where, (objValue: any, srcValue: any) => {
if (Array.isArray(objValue)) {
// Overwrite the array in the target object with the source array
return srcValue;
}
});
const relatedEntities = await this.getEntities( const relatedEntities = await this.getEntities(
queryRunner, queryRunner,
relationEntity, relationEntity,
relationsMap, relationsMap,
block, block,
where, relationWhere,
{}, relationQueryOptions,
childSelections, childSelections,
queryInfo queryInfo
); );
@ -877,14 +881,20 @@ export class GraphDatabase {
operator: 'in' operator: 'in'
}] }]
}; };
relationWhere = _.mergeWith(relationWhere, where, (objValue: any, srcValue: any) => {
if (Array.isArray(objValue)) {
// Overwrite the array in the target object with the source array
return srcValue;
}
});
const relatedEntities = await this.getEntities( const relatedEntities = await this.getEntities(
queryRunner, queryRunner,
relationEntity, relationEntity,
relationsMap, relationsMap,
block, block,
where, relationWhere,
{}, relationQueryOptions,
childSelections, childSelections,
queryInfo queryInfo
); );
@ -929,14 +939,20 @@ export class GraphDatabase {
operator: 'in' operator: 'in'
}] }]
}; };
relationWhere = _.mergeWith(relationWhere, where, (objValue: any, srcValue: any) => {
if (Array.isArray(objValue)) {
// Overwrite the array in the target object with the source array
return srcValue;
}
});
const relatedEntities = await this.getEntities( const relatedEntities = await this.getEntities(
queryRunner, queryRunner,
relationEntity, relationEntity,
relationsMap, relationsMap,
block, block,
where, relationWhere,
{}, relationQueryOptions,
childSelections, childSelections,
queryInfo queryInfo
); );
@ -1445,32 +1461,34 @@ export class GraphDatabase {
const queryOptions: QueryOptions = {}; const queryOptions: QueryOptions = {};
fieldNode.arguments?.forEach((arg: ArgumentNode) => { fieldNode.arguments?.forEach((arg: ArgumentNode) => {
let argValue: any;
switch (arg.name.value) { switch (arg.name.value) {
case 'where': case 'where':
where = this.buildFilter(this._buildWhereFromArgumentNode(arg, queryInfo)); where = this.buildFilter(this._buildWhereFromArgumentNode(arg, queryInfo));
break; break;
case 'first': case 'first': {
argValue = (arg.value.kind === 'Variable') ? queryInfo.variableValues[arg.value.name.value] : (arg.value as IntValueNode).value; const argValue = (arg.value.kind === 'Variable') ? queryInfo.variableValues[arg.value.name.value] : (arg.value as IntValueNode).value;
queryOptions.limit = Number(argValue); queryOptions.limit = Number(argValue);
break; break;
}
case 'skip': case 'skip': {
argValue = (arg.value.kind === 'Variable') ? queryInfo.variableValues[arg.value.name.value] : (arg.value as IntValueNode).value; const argValue = (arg.value.kind === 'Variable') ? queryInfo.variableValues[arg.value.name.value] : (arg.value as IntValueNode).value;
queryOptions.skip = Number(argValue); queryOptions.skip = Number(argValue);
break; break;
}
case 'orderBy': case 'orderBy': {
argValue = (arg.value.kind === 'Variable') ? queryInfo.variableValues[arg.value.name.value] : (arg.value as EnumValueNode).value; const argValue = (arg.value.kind === 'Variable') ? queryInfo.variableValues[arg.value.name.value] : (arg.value as EnumValueNode).value;
queryOptions.orderBy = String(argValue); queryOptions.orderBy = String(argValue);
break; break;
}
case 'orderDirection': case 'orderDirection': {
argValue = (arg.value.kind === 'Variable') ? queryInfo.variableValues[arg.value.name.value] : (arg.value as EnumValueNode).value; const argValue = (arg.value.kind === 'Variable') ? queryInfo.variableValues[arg.value.name.value] : (arg.value as EnumValueNode).value;
queryOptions.orderDirection = argValue as OrderDirection; queryOptions.orderDirection = argValue as OrderDirection;
break; break;
}
default: default:
throw new Error('Unrecognized query argument'); throw new Error('Unrecognized query argument');