From a959a26d60a4fae91e939382ed447b991577c49d Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Mon, 24 Feb 2025 16:15:59 +0000 Subject: [PATCH 1/4] Support filtering relationships by _id --- .../src/api/routes/tests/search.spec.ts | 22 +++++++++++++++++++ .../server/src/sdk/app/rows/queryUtils.ts | 7 +++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/packages/server/src/api/routes/tests/search.spec.ts b/packages/server/src/api/routes/tests/search.spec.ts index ee372914d7..ba2b3f0acf 100644 --- a/packages/server/src/api/routes/tests/search.spec.ts +++ b/packages/server/src/api/routes/tests/search.spec.ts @@ -3553,6 +3553,28 @@ if (descriptions.length) { limit: 1, }).toContainExactly([row]) }) + + it("can filter by the related _id", async () => { + await expectSearch({ + query: { + equal: { "rel._id": row.rel[0]._id }, + }, + }).toContainExactly([row]) + + await expectSearch({ + query: { + equal: { "rel._id": row.rel[1]._id }, + }, + }).toContainExactly([row]) + }) + + it("can filter by the related _id and find nothing", async () => { + await expectSearch({ + query: { + equal: { "rel._id": "rel_none" }, + }, + }).toFindNothing() + }) }) !isInternal && diff --git a/packages/server/src/sdk/app/rows/queryUtils.ts b/packages/server/src/sdk/app/rows/queryUtils.ts index ddd32870be..12e724b5d8 100644 --- a/packages/server/src/sdk/app/rows/queryUtils.ts +++ b/packages/server/src/sdk/app/rows/queryUtils.ts @@ -69,7 +69,8 @@ export const getQueryableFields = async ( fromTables: string[], opts?: { noRelationships?: boolean } ): Promise => { - const result = [] + // Querying by _id is always allowed, even if it's never part of the schema + const result = ["_id"] for (const field of Object.keys(table.schema).filter( f => allowedFields.includes(f) && table.schema[f].visible !== false )) { @@ -113,9 +114,7 @@ export const getQueryableFields = async ( return result } - const result = [ - "_id", // Querying by _id is always allowed, even if it's never part of the schema - ] + const result = [] if (fields == null) { fields = Object.keys(table.schema) From e6fc3dbff42922285b197f271845528f73684225 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Tue, 25 Feb 2025 09:19:25 +0000 Subject: [PATCH 2/4] Fix queryUtils tests. --- .../src/sdk/app/rows/tests/queryUtils.spec.ts | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/packages/server/src/sdk/app/rows/tests/queryUtils.spec.ts b/packages/server/src/sdk/app/rows/tests/queryUtils.spec.ts index f399801f1e..100581cb54 100644 --- a/packages/server/src/sdk/app/rows/tests/queryUtils.spec.ts +++ b/packages/server/src/sdk/app/rows/tests/queryUtils.spec.ts @@ -250,6 +250,8 @@ describe("query utils", () => { expect(result).toEqual([ "_id", "name", + "aux._id", + "auxTable._id", "aux.title", "auxTable.title", "aux.name", @@ -284,7 +286,14 @@ describe("query utils", () => { const result = await config.doInContext(config.appId, () => { return getQueryableFields(table) }) - expect(result).toEqual(["_id", "name", "aux.name", "auxTable.name"]) + expect(result).toEqual([ + "_id", + "name", + "aux._id", + "auxTable._id", + "aux.name", + "auxTable.name", + ]) }) it("excludes all relationship fields if hidden", async () => { @@ -387,10 +396,14 @@ describe("query utils", () => { "_id", "name", // aux1 primitive props + "aux1._id", + "aux1Table._id", "aux1.name", "aux1Table.name", // aux2 primitive props + "aux2._id", + "aux2Table._id", "aux2.title", "aux2Table.title", ]) @@ -405,14 +418,20 @@ describe("query utils", () => { "name", // aux2_1 primitive props + "aux2_1._id", + "aux2Table._id", "aux2_1.title", "aux2Table.title", // aux2_2 primitive props + "aux2_2._id", + "aux2Table._id", "aux2_2.title", "aux2Table.title", // table primitive props + "table._id", + "TestTable._id", "table.name", "TestTable.name", ]) @@ -427,14 +446,20 @@ describe("query utils", () => { "title", // aux1_1 primitive props + "aux1_1._id", + "aux1Table._id", "aux1_1.name", "aux1Table.name", // aux1_2 primitive props + "aux1_2._id", + "aux1Table._id", "aux1_2.name", "aux1Table.name", // table primitive props + "table._id", + "TestTable._id", "table.name", "TestTable.name", ]) @@ -481,6 +506,8 @@ describe("query utils", () => { "name", // deep 1 aux primitive props + "aux._id", + "auxTable._id", "aux.title", "auxTable.title", ]) @@ -495,6 +522,8 @@ describe("query utils", () => { "title", // deep 1 dependency primitive props + "table._id", + "TestTable._id", "table.name", "TestTable.name", ]) From 3c6e2ff2d784cd79fc42df2c9955ebdba1897e2c Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Tue, 25 Feb 2025 09:54:10 +0000 Subject: [PATCH 3/4] Fix search tests. --- .../src/api/routes/tests/search.spec.ts | 41 ++++++++++--------- .../server/src/sdk/app/rows/queryUtils.ts | 11 +++-- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/packages/server/src/api/routes/tests/search.spec.ts b/packages/server/src/api/routes/tests/search.spec.ts index ba2b3f0acf..76ce4a0243 100644 --- a/packages/server/src/api/routes/tests/search.spec.ts +++ b/packages/server/src/api/routes/tests/search.spec.ts @@ -3554,27 +3554,30 @@ if (descriptions.length) { }).toContainExactly([row]) }) - it("can filter by the related _id", async () => { - await expectSearch({ - query: { - equal: { "rel._id": row.rel[0]._id }, - }, - }).toContainExactly([row]) + isInternal && + describe("search by _id for relations", () => { + it("can filter by the related _id", async () => { + await expectSearch({ + query: { + equal: { "rel._id": row.rel[0]._id }, + }, + }).toContainExactly([row]) - await expectSearch({ - query: { - equal: { "rel._id": row.rel[1]._id }, - }, - }).toContainExactly([row]) - }) + await expectSearch({ + query: { + equal: { "rel._id": row.rel[1]._id }, + }, + }).toContainExactly([row]) + }) - it("can filter by the related _id and find nothing", async () => { - await expectSearch({ - query: { - equal: { "rel._id": "rel_none" }, - }, - }).toFindNothing() - }) + it("can filter by the related _id and find nothing", async () => { + await expectSearch({ + query: { + equal: { "rel._id": "rel_none" }, + }, + }).toFindNothing() + }) + }) }) !isInternal && diff --git a/packages/server/src/sdk/app/rows/queryUtils.ts b/packages/server/src/sdk/app/rows/queryUtils.ts index 12e724b5d8..629fb50545 100644 --- a/packages/server/src/sdk/app/rows/queryUtils.ts +++ b/packages/server/src/sdk/app/rows/queryUtils.ts @@ -7,6 +7,7 @@ import { } from "@budibase/types" import { cloneDeep } from "lodash/fp" import sdk from "../../../sdk" +import { isInternal } from "../tables/utils" export const removeInvalidFilters = ( filters: SearchFilters, @@ -69,8 +70,11 @@ export const getQueryableFields = async ( fromTables: string[], opts?: { noRelationships?: boolean } ): Promise => { - // Querying by _id is always allowed, even if it's never part of the schema - const result = ["_id"] + const result = [] + if (isInternal({ table })) { + result.push("_id") + } + for (const field of Object.keys(table.schema).filter( f => allowedFields.includes(f) && table.schema[f].visible !== false )) { @@ -114,7 +118,8 @@ export const getQueryableFields = async ( return result } - const result = [] + // Querying by _id is always allowed, even if it's never part of the schema + const result = ["_id"] if (fields == null) { fields = Object.keys(table.schema) From da8c5be6857c0190f3ec3c3cd99c51a994425ef0 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Tue, 25 Feb 2025 11:08:18 +0000 Subject: [PATCH 4/4] Fix queryUtils tests. --- packages/server/src/sdk/app/rows/queryUtils.ts | 2 +- packages/server/src/sdk/app/rows/tests/queryUtils.spec.ts | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/server/src/sdk/app/rows/queryUtils.ts b/packages/server/src/sdk/app/rows/queryUtils.ts index 629fb50545..8ab50ea1b7 100644 --- a/packages/server/src/sdk/app/rows/queryUtils.ts +++ b/packages/server/src/sdk/app/rows/queryUtils.ts @@ -126,5 +126,5 @@ export const getQueryableFields = async ( } result.push(...(await extractTableFields(table, fields, [table._id!]))) - return result + return Array.from(new Set(result)) } diff --git a/packages/server/src/sdk/app/rows/tests/queryUtils.spec.ts b/packages/server/src/sdk/app/rows/tests/queryUtils.spec.ts index 100581cb54..26a8431446 100644 --- a/packages/server/src/sdk/app/rows/tests/queryUtils.spec.ts +++ b/packages/server/src/sdk/app/rows/tests/queryUtils.spec.ts @@ -425,9 +425,7 @@ describe("query utils", () => { // aux2_2 primitive props "aux2_2._id", - "aux2Table._id", "aux2_2.title", - "aux2Table.title", // table primitive props "table._id", @@ -453,9 +451,7 @@ describe("query utils", () => { // aux1_2 primitive props "aux1_2._id", - "aux1Table._id", "aux1_2.name", - "aux1Table.name", // table primitive props "table._id",