From d93390dea78c17fd2eb54694b2f0c803a330d2b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Thu, 5 Dec 2024 22:06:28 +0100 Subject: [PATCH] simplify the generated filters when parsing a query MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/small-boxes-enjoy.md | 5 +++++ .../src/service/createRouter.test.ts | 14 ++++---------- .../request/parseEntityFilterParams.test.ts | 10 ++++------ .../src/service/request/parseEntityFilterParams.ts | 9 +++++++-- 4 files changed, 20 insertions(+), 18 deletions(-) create mode 100644 .changeset/small-boxes-enjoy.md diff --git a/.changeset/small-boxes-enjoy.md b/.changeset/small-boxes-enjoy.md new file mode 100644 index 0000000000..819e247d49 --- /dev/null +++ b/.changeset/small-boxes-enjoy.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-catalog-backend': patch +--- + +When parsing filters, do not make redundant `anyOf` and `allOf` nodes when there's only a single entry within them diff --git a/plugins/catalog-backend/src/service/createRouter.test.ts b/plugins/catalog-backend/src/service/createRouter.test.ts index 6654187526..7cba2edea9 100644 --- a/plugins/catalog-backend/src/service/createRouter.test.ts +++ b/plugins/catalog-backend/src/service/createRouter.test.ts @@ -166,7 +166,7 @@ describe('createRouter readonly disabled', () => { { key: 'b', values: ['3'] }, ], }, - { allOf: [{ key: 'c', values: ['4'] }] }, + { key: 'c', values: ['4'] }, ], }, credentials: mockCredentials.user(), @@ -218,7 +218,7 @@ describe('createRouter readonly disabled', () => { { key: 'b', values: ['3'] }, ], }, - { allOf: [{ key: 'c', values: ['4'] }] }, + { key: 'c', values: ['4'] }, ], }, orderFields: [ @@ -258,7 +258,7 @@ describe('createRouter readonly disabled', () => { { key: 'b', values: ['3'] }, ], }, - { allOf: [{ key: 'c', values: ['4'] }] }, + { key: 'c', values: ['4'] }, ], }, orderFields: [ @@ -554,13 +554,7 @@ describe('createRouter readonly disabled', () => { entityRefs: [entityRef], fields: expect.any(Function), credentials: mockCredentials.user(), - filter: { - anyOf: [ - { - allOf: [{ key: 'kind', values: ['Component'] }], - }, - ], - }, + filter: { key: 'kind', values: ['Component'] }, }); expect(response.status).toEqual(200); expect(response.body).toEqual({ items: [entity] }); diff --git a/plugins/catalog-backend/src/service/request/parseEntityFilterParams.test.ts b/plugins/catalog-backend/src/service/request/parseEntityFilterParams.test.ts index f9fc596cb9..85e0d9caa1 100644 --- a/plugins/catalog-backend/src/service/request/parseEntityFilterParams.test.ts +++ b/plugins/catalog-backend/src/service/request/parseEntityFilterParams.test.ts @@ -27,9 +27,7 @@ describe('parseEntityFilterParams', () => { it('supports single-string format', () => { const result = parseEntityFilterParams({ filter: 'a=1' })!; - expect(result).toEqual({ - anyOf: [{ allOf: [{ key: 'a', values: ['1'] }] }], - }); + expect(result).toEqual({ key: 'a', values: ['1'] }); }); it('supports array-of-strings format', () => { @@ -38,8 +36,8 @@ describe('parseEntityFilterParams', () => { }); expect(result).toEqual({ anyOf: [ - { allOf: [{ key: 'a', values: ['1'] }] }, - { allOf: [{ key: 'b', values: ['2'] }] }, + { key: 'a', values: ['1'] }, + { key: 'b', values: ['2'] }, ], }); }); @@ -50,7 +48,7 @@ describe('parseEntityFilterParams', () => { }); expect(result).toEqual({ anyOf: [ - { allOf: [{ key: 'a', values: ['1'] }] }, + { key: 'a', values: ['1'] }, { allOf: [ { key: 'b', values: ['2', '3'] }, diff --git a/plugins/catalog-backend/src/service/request/parseEntityFilterParams.ts b/plugins/catalog-backend/src/service/request/parseEntityFilterParams.ts index 8666712f80..aabb24ff3f 100644 --- a/plugins/catalog-backend/src/service/request/parseEntityFilterParams.ts +++ b/plugins/catalog-backend/src/service/request/parseEntityFilterParams.ts @@ -36,12 +36,17 @@ export function parseEntityFilterParams( // Outer array: "any of the inner ones" // Inner arrays: "all of these must match" - const filters = filterStrings.map(parseEntityFilterString).filter(Boolean); + const filters = filterStrings + .map(parseEntityFilterString) + .filter((r): r is EntitiesSearchFilter[] => Boolean(r)); if (!filters.length) { return undefined; } - return { anyOf: filters.map(f => ({ allOf: f! })) }; + const outer = filters.map(inner => + inner.length === 1 ? inner[0] : { allOf: inner }, + ); + return outer.length === 1 ? outer[0] : { anyOf: outer }; } /**