diff --git a/.changeset/soft-moons-worry.md b/.changeset/soft-moons-worry.md new file mode 100644 index 00000000..cff69337 --- /dev/null +++ b/.changeset/soft-moons-worry.md @@ -0,0 +1,5 @@ +--- +"@supabase-cache-helpers/postgrest-core": patch +--- + +fix: transform empty jsonb array cols properly diff --git a/packages/postgrest-core/src/fetch/build-mutation-fetcher-response.ts b/packages/postgrest-core/src/fetch/build-mutation-fetcher-response.ts index 412c29f6..d6ad851d 100644 --- a/packages/postgrest-core/src/fetch/build-mutation-fetcher-response.ts +++ b/packages/postgrest-core/src/fetch/build-mutation-fetcher-response.ts @@ -2,6 +2,7 @@ import { flatten } from 'flat'; import { get } from '../lib/get'; import { type NestedPath, isNestedPath } from '../lib/group-paths-recursive'; +import { isPlainObject } from '../lib/is-plain-object'; import type { Path } from '../lib/query-types'; import type { BuildNormalizedQueryReturn } from './build-normalized-query'; @@ -83,7 +84,7 @@ export const normalizeResponse = ( ...flatten({ [curr.path]: value !== null && - (typeof value === 'object' || Array.isArray(value)) + (isPlainObject(value) || (Array.isArray(value) && value.length > 0)) ? flatten(value) : value, }), @@ -102,8 +103,11 @@ export const normalizeResponse = ( ...flatten({ // add hint to path if it has dedupe alias // can happen if the same relation is queried multiple times via different fkeys - [`${curr.path}${curr.alias?.startsWith('d_') && curr.declaration.split('!').length > 1 ? `!${curr.declaration.split('!')[1]}` : ''}`]: - normalizeResponse(curr.paths, value as Record), + [`${curr.path}${ + curr.alias?.startsWith('d_') && curr.declaration.split('!').length > 1 + ? `!${curr.declaration.split('!')[1]}` + : '' + }`]: normalizeResponse(curr.paths, value as Record), }), }; }, {} as R); diff --git a/packages/postgrest-core/src/lib/is-plain-object.ts b/packages/postgrest-core/src/lib/is-plain-object.ts new file mode 100644 index 00000000..07a87b3f --- /dev/null +++ b/packages/postgrest-core/src/lib/is-plain-object.ts @@ -0,0 +1,5 @@ +export function isPlainObject( + value: unknown, +): value is Record { + return Object.prototype.toString.call(value) === '[object Object]'; +} diff --git a/packages/postgrest-core/tests/fetch/build-mutation-fetcher-response.spec.ts b/packages/postgrest-core/tests/fetch/build-mutation-fetcher-response.spec.ts index d5c413ea..0c92f238 100644 --- a/packages/postgrest-core/tests/fetch/build-mutation-fetcher-response.spec.ts +++ b/packages/postgrest-core/tests/fetch/build-mutation-fetcher-response.spec.ts @@ -11,11 +11,14 @@ describe('buildMutationFetcherResponse', () => { it('should work with json columns', () => { const q = c .from('campaign') - .select('jsoncol,jsonarraycol,jsonarrayobjcol') + .select( + 'jsoncol,jsonarraycol,jsonarrayobjcol,jsonarraycolempty,jsonobjcolempty', + ) .eq('id', 'some-id'); const query = buildNormalizedQuery({ - query: 'jsoncol,jsonarraycol,jsonarrayobjcol', + query: + 'jsoncol,jsonarraycolempty,jsonobjcolempty,jsonarraycol,jsonarrayobjcol', queriesForTable: () => [new PostgrestParser(q)], }); @@ -29,6 +32,8 @@ describe('buildMutationFetcherResponse', () => { test: '123', }, jsonarraycol: ['123'], + jsonarraycolempty: [], + jsonobjcolempty: {}, jsonarrayobjcol: [{ some: 'value' }, { some: 'other' }], }, { @@ -41,6 +46,8 @@ describe('buildMutationFetcherResponse', () => { id: 'some-id', 'jsoncol.test': '123', 'jsonarraycol.0': '123', + jsonarraycolempty: [], + jsonobjcolempty: {}, 'jsonarrayobjcol.0.some': 'value', 'jsonarrayobjcol.1.some': 'other', }, @@ -50,6 +57,8 @@ describe('buildMutationFetcherResponse', () => { }, jsonarraycol: ['123'], jsonarrayobjcol: [{ some: 'value' }, { some: 'other' }], + jsonarraycolempty: [], + jsonobjcolempty: {}, }, }); });