diff --git a/packages/server/src/sdk/app/rows/queryUtils.ts b/packages/server/src/sdk/app/rows/queryUtils.ts index 20e6af4d67..02e77a77b7 100644 --- a/packages/server/src/sdk/app/rows/queryUtils.ts +++ b/packages/server/src/sdk/app/rows/queryUtils.ts @@ -1,6 +1,12 @@ import { db } from "@budibase/backend-core" -import { isLogicalSearchOperator, SearchFilters } from "@budibase/types" +import { + FieldType, + isLogicalSearchOperator, + SearchFilters, + Table, +} from "@budibase/types" import { cloneDeep } from "lodash/fp" +import sdk from "../../../sdk" export const removeInvalidFilters = ( filters: SearchFilters, @@ -45,3 +51,48 @@ export const removeInvalidFilters = ( return result } + +export const getQueryableFields = async ( + fields: string[], + table: Table +): Promise => { + const handledTables = new Set([table._id!]) + const extractTableFields = async ( + table: Table, + allowedFields: string[] + ): Promise => { + const result = [] + for (const field of Object.keys(table.schema).filter(f => + allowedFields.includes(f) + )) { + const subSchema = table.schema[field] + if (subSchema.type === FieldType.LINK) { + if (handledTables.has(`${table._id}_${subSchema.tableId}`)) { + // avoid circular loops + continue + } + handledTables.add(`${table._id}_${subSchema.tableId}`) + const relatedTable = await sdk.tables.getTable(subSchema.tableId) + const relatedFields = await extractTableFields( + relatedTable, + Object.keys(relatedTable.schema) + ) + + result.push(...relatedFields.map(f => `${subSchema.name}.${f}`)) + // should be able to filter by relationship using table name + result.push(...relatedFields.map(f => `${relatedTable.name}.${f}`)) + } else { + result.push(field) + } + } + return result + } + + const result = [ + "_id", // Querying by _id is always allowed, even if it's never part of the schema + ] + + result.push(...(await extractTableFields(table, fields))) + + return result +} diff --git a/packages/server/src/sdk/app/rows/search.ts b/packages/server/src/sdk/app/rows/search.ts index 1bf25ff926..6a4286814d 100644 --- a/packages/server/src/sdk/app/rows/search.ts +++ b/packages/server/src/sdk/app/rows/search.ts @@ -1,11 +1,9 @@ import { EmptyFilterOption, - FieldType, Row, RowSearchParams, SearchResponse, SortOrder, - Table, } from "@budibase/types" import { isExternalTableID } from "../../../integrations/utils" import * as internal from "./search/internal" @@ -16,7 +14,7 @@ import sdk from "../../index" import { searchInputMapping } from "./search/utils" import { db as dbCore } from "@budibase/backend-core" import tracer from "dd-trace" -import { removeInvalidFilters } from "./queryUtils" +import { getQueryableFields, removeInvalidFilters } from "./queryUtils" export { isValidFilter } from "../../../integrations/utils" @@ -130,48 +128,3 @@ export async function fetchView( ): Promise { return pickApi(tableId).fetchView(viewName, params) } - -async function getQueryableFields( - fields: string[], - table: Table -): Promise { - const handledTables = new Set([table._id!]) - const extractTableFields = async ( - table: Table, - allowedFields: string[] - ): Promise => { - const result = [] - for (const field of Object.keys(table.schema).filter(f => - allowedFields.includes(f) - )) { - const subSchema = table.schema[field] - if (subSchema.type === FieldType.LINK) { - if (handledTables.has(`${table._id}_${subSchema.tableId}`)) { - // avoid circular loops - continue - } - handledTables.add(`${subSchema.tableId}_${table._id}`) - const relatedTable = await sdk.tables.getTable(subSchema.tableId) - const relatedFields = await extractTableFields( - relatedTable, - Object.keys(relatedTable.schema) - ) - - result.push(...relatedFields.map(f => `${subSchema.name}.${f}`)) - // should be able to filter by relationship using table name - result.push(...relatedFields.map(f => `${relatedTable.name}.${f}`)) - } else { - result.push(field) - } - } - return result - } - - const result = [ - "_id", // Querying by _id is always allowed, even if it's never part of the schema - ] - - result.push(...(await extractTableFields(table, fields))) - - return result -}