From 460f0ba003abe92d7b4abf06d8c1957a44bd3c23 Mon Sep 17 00:00:00 2001 From: Azri Kahar <42867097+azrikahar@users.noreply.github.com> Date: Tue, 19 Apr 2022 22:19:49 +0800 Subject: [PATCH] Fix alias (#12826) * fix alias * minor clean up * fix graphql nested junction aliases --- api/src/database/run-ast.ts | 8 +++++--- api/src/services/graphql.ts | 21 ++++++++++++++++++++- api/src/utils/get-ast-from-query.ts | 19 +++++++++++++++---- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/api/src/database/run-ast.ts b/api/src/database/run-ast.ts index b8e0067361..8c37baba7e 100644 --- a/api/src/database/run-ast.ts +++ b/api/src/database/run-ast.ts @@ -168,7 +168,7 @@ async function parseCurrentLevel( if (!child.relation) continue; if (child.type === 'm2o') { - columnsToSelectInternal.push(child.fieldKey); + columnsToSelectInternal.push(child.relation.field); } if (child.type === 'a2o') { @@ -193,7 +193,9 @@ async function parseCurrentLevel( const fieldNodes = columnsToSelect.map( (column: string) => - children.find((childNode) => childNode.type === 'field' && childNode.fieldKey === column) ?? { + children.find( + (childNode) => childNode.type === 'field' && (childNode.fieldKey === column || childNode.name === column) + ) ?? { type: 'field', name: column, fieldKey: column, @@ -322,7 +324,7 @@ function mergeWithParentItems( const itemChild = nestedItems.find((nestedItem) => { return ( nestedItem[schema.collections[nestedNode.relation.related_collection!].primary] == - parentItem[nestedNode.fieldKey] + parentItem[nestedNode.relation.field] ); }); diff --git a/api/src/services/graphql.ts b/api/src/services/graphql.ts index ccacfc206e..5a3fb6078c 100644 --- a/api/src/services/graphql.ts +++ b/api/src/services/graphql.ts @@ -1414,6 +1414,7 @@ export class GraphQLService { selection = selection as FieldNode | InlineFragmentNode; let current: string; + let currentAlias: string | null = null; // Union type (Many-to-Any) if (selection.kind === 'InlineFragment') { @@ -1428,8 +1429,26 @@ export class GraphQLService { current = selection.name.value; + if (selection.alias) { + currentAlias = selection.alias.value; + } + if (parent) { current = `${parent}.${current}`; + + if (currentAlias) { + currentAlias = `${parent}.${currentAlias}`; + + // add nested aliases into deep query + if (selection.selectionSet) { + if (!query.deep) query.deep = {}; + set( + query.deep, + parent, + merge(get(query.deep, parent), { _alias: { [selection.alias!.value]: selection.name.value } }) + ); + } + } } } @@ -1446,7 +1465,7 @@ export class GraphQLService { children.push(`${subSelection.name!.value}(${rootField})`); } } else { - children = parseFields(selection.selectionSet.selections, current); + children = parseFields(selection.selectionSet.selections, currentAlias ?? current); } fields.push(...children); diff --git a/api/src/utils/get-ast-from-query.ts b/api/src/utils/get-ast-from-query.ts index d271958ef0..e39afd0fd5 100644 --- a/api/src/utils/get-ast-from-query.ts +++ b/api/src/utils/get-ast-from-query.ts @@ -3,7 +3,7 @@ */ import { Knex } from 'knex'; -import { cloneDeep, mapKeys, omitBy, uniq } from 'lodash'; +import { cloneDeep, mapKeys, omitBy, uniq, isEmpty } from 'lodash'; import { AST, FieldNode, NestedCollectionNode } from '../types'; import { Query, PermissionsAction, Accountability, SchemaOverview } from '@directus/shared/types'; import { getRelationType } from '../utils/get-relation-type'; @@ -114,10 +114,17 @@ export default async function getASTFromQuery( for (const fieldKey of fields) { let name = fieldKey; - const isAlias = (query.alias && name in query.alias) ?? false; + if (query.alias) { + // check for field alias (is is one of the key) + if (name in query.alias) { + name = query.alias[fieldKey]; + } - if (isAlias) { - name = query.alias![fieldKey]; + // check for junction alias (it is one of the value instead of the key) + if (Object.values(query.alias).includes(name)) { + const aliasKey = Object.keys(query.alias).find((key) => query.alias?.[key] === name); + if (aliasKey && fieldKey !== aliasKey) name = aliasKey; + } } const isRelational = @@ -223,6 +230,10 @@ export default async function getASTFromQuery( continue; } + // update query alias for children parseFields + const deepAlias = getDeepQuery(deep?.[fieldKey] || {})?.alias; + if (!isEmpty(deepAlias)) query.alias = deepAlias; + child = { type: relationType, name: relatedCollection,