From 5098386fbe1db44ca5b09aad2ea87c3896a54448 Mon Sep 17 00:00:00 2001 From: Mikael Karon Date: Tue, 4 Nov 2025 02:06:16 +0100 Subject: [PATCH 1/3] fix: `toArgsAdapterInput` with non-array `result` and `path` Signed-off-by: Mikael Karon --- lib/query-builder.js | 9 +++------ test/query-builder.test.js | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 6 deletions(-) create mode 100644 test/query-builder.test.js diff --git a/lib/query-builder.js b/lib/query-builder.js index 52760cf..077318c 100644 --- a/lib/query-builder.js +++ b/lib/query-builder.js @@ -60,11 +60,7 @@ function addDeferredQueryField (query, fieldName, queryFieldNode) { function toArgsAdapterInput (result, path) { if (!result) { return [] } - if (!Array.isArray(result)) { - return [result] - } - - let r = result.filter(r => !!r) + let r = !Array.isArray(result) ? [result] : result.filter(r => !!r) if (!path) { return r.flat() @@ -357,5 +353,6 @@ module.exports = { queryParentResult, - buildQuery + buildQuery, + toArgsAdapterInput } diff --git a/test/query-builder.test.js b/test/query-builder.test.js new file mode 100644 index 0000000..8902166 --- /dev/null +++ b/test/query-builder.test.js @@ -0,0 +1,37 @@ +'use strict' + +const assert = require('node:assert') +const { test } = require('node:test') +const { toArgsAdapterInput } = require('../lib/query-builder') + +test('toArgsAdapterInput', async (t) => { + await t.test('returns empty array for falsy inputs', () => { + assert.deepStrictEqual(toArgsAdapterInput(null), []) + assert.deepStrictEqual(toArgsAdapterInput(undefined), []) + assert.deepStrictEqual(toArgsAdapterInput(0), []) + }) + + await t.test('converts non-array to array without path', () => { + assert.deepStrictEqual(toArgsAdapterInput({ id: 1 }), [{ id: 1 }]) + assert.deepStrictEqual(toArgsAdapterInput('test'), ['test']) + }) + + await t.test('filters falsy values and flattens arrays', () => { + assert.deepStrictEqual( + toArgsAdapterInput([{ id: 1 }, null, { id: 2 }]), + [{ id: 1 }, { id: 2 }] + ) + assert.deepStrictEqual( + toArgsAdapterInput([[{ id: 1 }], [{ id: 2 }]]), + [{ id: 1 }, { id: 2 }] + ) + }) + + await t.test('ensures consistent filtering for both arrays and non-arrays', () => { + // Non-arrays should go through the same filtering logic as arrays + const nonArrayResult = { id: 1, name: 'test' } + const output = toArgsAdapterInput(nonArrayResult) + + assert.deepStrictEqual(output, [{ id: 1, name: 'test' }]) + }) +}) From f9970e9aa420940ebe73a191610157d3ccf601d0 Mon Sep 17 00:00:00 2001 From: Mikael Karon Date: Tue, 4 Nov 2025 20:28:10 +0100 Subject: [PATCH 2/3] test: add better test with path Signed-off-by: Mikael Karon --- test/query-builder.test.js | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/test/query-builder.test.js b/test/query-builder.test.js index 8902166..3b1cf7b 100644 --- a/test/query-builder.test.js +++ b/test/query-builder.test.js @@ -27,11 +27,45 @@ test('toArgsAdapterInput', async (t) => { ) }) - await t.test('ensures consistent filtering for both arrays and non-arrays', () => { - // Non-arrays should go through the same filtering logic as arrays + await t.test('converts non-array objects to arrays for consistent processing', () => { const nonArrayResult = { id: 1, name: 'test' } const output = toArgsAdapterInput(nonArrayResult) assert.deepStrictEqual(output, [{ id: 1, name: 'test' }]) }) + + await t.test('processes non-array objects through path traversal like arrays', () => { + // Ensures non-array objects go through the same path logic as arrays + // instead of returning early and skipping path processing + + const arrayInput = [ + { + account: { + organizations: [{ id: 'ff82a360-5cf5-4a06-8dbf-1e55b02f9224' }] + } + } + ] + + const singleObjectInput = { + account: { + organizations: [{ id: 'ff82a360-5cf5-4a06-8dbf-1e55b02f9224' }] + } + } + + const path = ['account', 'organizations', 'id'] + + const output1 = toArgsAdapterInput(arrayInput, path) + const output2 = toArgsAdapterInput(singleObjectInput, path) + + // Both inputs should produce identical results after path traversal + assert.ok(Array.isArray(output1)) + assert.ok(Array.isArray(output2)) + assert.strictEqual(output1.length, 1) + assert.strictEqual(output2.length, 1) + + // Path traversal processes path.length - 1 elements, so ['account', 'organizations', 'id'] + // traverses to 'account' -> 'organizations', returning the organizations array + assert.strictEqual(output1[0].id, 'ff82a360-5cf5-4a06-8dbf-1e55b02f9224') + assert.strictEqual(output2[0].id, 'ff82a360-5cf5-4a06-8dbf-1e55b02f9224') + }) }) From 99e60df75460a024ad1bb44e7f5faec9bb8cae65 Mon Sep 17 00:00:00 2001 From: Mikael Karon Date: Wed, 5 Nov 2025 00:55:58 +0100 Subject: [PATCH 3/3] chore: simplify `toArgsAdapterInput` array conversion Signed-off-by: Mikael Karon --- lib/query-builder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/query-builder.js b/lib/query-builder.js index 077318c..8d694b7 100644 --- a/lib/query-builder.js +++ b/lib/query-builder.js @@ -60,7 +60,7 @@ function addDeferredQueryField (query, fieldName, queryFieldNode) { function toArgsAdapterInput (result, path) { if (!result) { return [] } - let r = !Array.isArray(result) ? [result] : result.filter(r => !!r) + let r = Array.isArray(result) ? result.filter(r => !!r) : [result] if (!path) { return r.flat()