From a5620b8b37b39fae09e241c9f73143b3feb9fbb0 Mon Sep 17 00:00:00 2001 From: rijkvanzanten Date: Tue, 14 Jul 2020 18:48:21 -0400 Subject: [PATCH] It works, pfew --- src/database/run-ast.ts | 12 ++++++++---- src/utils/get-ast-from-query.ts | 34 +++++++++++++++++++++++++++------ 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/database/run-ast.ts b/src/database/run-ast.ts index 957e78e6f0..b43ee7a1c0 100644 --- a/src/database/run-ast.ts +++ b/src/database/run-ast.ts @@ -1,5 +1,5 @@ import { AST, NestedCollectionAST } from '../types/ast'; -import { uniq, pick } from 'lodash'; +import { clone, uniq, pick } from 'lodash'; import database, { schemaInspector } from './index'; import { Filter, Query } from '../types'; import { QueryBuilder } from 'knex'; @@ -138,9 +138,13 @@ export default async function runAST(ast: AST, query = ast.query) { results = results.map((record) => { if (m2o) { const nestedResult = - nestedResults.find((nestedRecord) => { - return nestedRecord[batch.relation.primary_one] === record[batch.fieldKey]; - }) || null; + clone( + nestedResults.find((nestedRecord) => { + return ( + nestedRecord[batch.relation.primary_one] === record[batch.fieldKey] + ); + }) + ) || null; if (tempField && nestedResult) { delete nestedResult[tempField]; diff --git a/src/utils/get-ast-from-query.ts b/src/utils/get-ast-from-query.ts index 8ed61a4604..eec6fcb6b1 100644 --- a/src/utils/get-ast-from-query.ts +++ b/src/utils/get-ast-from-query.ts @@ -28,12 +28,12 @@ export default async function getASTFromQuery( children: [], }; - const fields = convertWildcards(collection, query.fields || ['*']); + const fields = query.fields || ['*']; // Prevent fields from showing up in the query object delete query.fields; - ast.children = parseFields(collection, fields); + ast.children = parseFields(collection, fields).filter(filterEmptyChildCollections); return ast; @@ -42,6 +42,8 @@ export default async function getASTFromQuery( .find((permission) => parentCollection === permission.collection) ?.fields?.split(','); + if (!allowedFields || allowedFields.length === 0) return []; + for (let index = 0; index < fields.length; index++) { const fieldKey = fields[index]; @@ -55,9 +57,20 @@ export default async function getASTFromQuery( // Swap *.* case for *,.*,.* if (fieldKey.includes('.') && fieldKey.split('.')[0] === '*') { const parts = fieldKey.split('.'); - const relationalFields = allowedFields.filter( - (fieldKey) => !!getRelation(parentCollection, fieldKey) - ); + + const relationalFields = allowedFields.includes('*') + ? relations + .filter( + (relation) => + relation.collection_many === parentCollection || + relation.collection_one === parentCollection + ) + .map((relation) => { + const isM2O = relation.collection_many === parentCollection; + return isM2O ? relation.field_many : relation.field_one; + }) + : allowedFields.filter((fieldKey) => !!getRelation(parentCollection, fieldKey)); + const nonRelationalFields = allowedFields.filter( (fieldKey) => relationalFields.includes(fieldKey) === false ); @@ -81,6 +94,8 @@ export default async function getASTFromQuery( function parseFields(parentCollection: string, fields: string[]) { fields = convertWildcards(parentCollection, fields); + if (!fields) return null; + const children: (NestedCollectionAST | FieldAST)[] = []; const relationalStructure: Record = {}; @@ -110,7 +125,9 @@ export default async function getASTFromQuery( parentKey: 'id' /** @todo this needs to come from somewhere real */, relation: getRelation(parentCollection, relationalField), query: {} /** @todo inject nested query here */, - children: parseFields(relatedCollection, nestedFields), + children: parseFields(relatedCollection, nestedFields).filter( + filterEmptyChildCollections + ), }; children.push(child); @@ -143,4 +160,9 @@ export default async function getASTFromQuery( return relation.collection_many; } } + + function filterEmptyChildCollections(childAST: NestedCollectionAST) { + if (childAST.type === 'collection' && childAST.children.length === 0) return false; + return true; + } }