From 819bfb5f2f2df93960314a03a453831421b1615b Mon Sep 17 00:00:00 2001 From: psteinroe Date: Tue, 12 Mar 2024 11:18:11 +0100 Subject: [PATCH] fix: apply potential dedupe alias on normalized query also on pk filter --- .changeset/calm-mirrors-study.md | 5 +++ .../__tests__/delete-fetcher.spec.ts | 35 +++++++++++++++++++ .../__tests__/update-fetcher.spec.ts | 30 ++++++++++++++++ packages/postgrest-core/src/delete-fetcher.ts | 12 ++++--- packages/postgrest-core/src/update-fetcher.ts | 10 ++++-- 5 files changed, 86 insertions(+), 6 deletions(-) create mode 100644 .changeset/calm-mirrors-study.md diff --git a/.changeset/calm-mirrors-study.md b/.changeset/calm-mirrors-study.md new file mode 100644 index 00000000..6796900d --- /dev/null +++ b/.changeset/calm-mirrors-study.md @@ -0,0 +1,5 @@ +--- +"@supabase-cache-helpers/postgrest-core": patch +--- + +fix: apply dedupe aliased to pk filters if there are any diff --git a/packages/postgrest-core/__tests__/delete-fetcher.spec.ts b/packages/postgrest-core/__tests__/delete-fetcher.spec.ts index 164e804f..58431084 100644 --- a/packages/postgrest-core/__tests__/delete-fetcher.spec.ts +++ b/packages/postgrest-core/__tests__/delete-fetcher.spec.ts @@ -3,6 +3,7 @@ import { createClient, SupabaseClient } from '@supabase/supabase-js'; import { Database } from './database.types'; import { buildDeleteFetcher } from '../src/delete-fetcher'; import './utils'; +import { PostgrestParser } from '../dist'; const TEST_PREFIX = 'postgrest-fetcher-delete-'; @@ -139,4 +140,38 @@ describe('delete', () => { expect(data).toEqual([]); }); + + it('should use alias if there is one on the pks', async () => { + const { data: contact } = await client + .from('contact') + .insert({ username: `${testRunPrefix}-test`, ticket_number: 1234 }) + .select('id') + .throwOnError() + .single(); + expect(contact?.id).toBeDefined(); + + const q = client + .from('contact') + .select('test:id,username') + .eq('test', contact!.id); + + const result = await buildDeleteFetcher(client.from('contact'), ['id'], { + query: 'ticket_number', + queriesForTable: () => [new PostgrestParser(q)], + })([ + { + id: contact?.id, + }, + ]); + expect(result).toEqual([ + { + normalizedData: { + id: contact?.id, + ticket_number: 1234, + username: `${testRunPrefix}-test`, + }, + userQueryData: { ticket_number: 1234 }, + }, + ]); + }); }); diff --git a/packages/postgrest-core/__tests__/update-fetcher.spec.ts b/packages/postgrest-core/__tests__/update-fetcher.spec.ts index d73e2ddf..f8043f8f 100644 --- a/packages/postgrest-core/__tests__/update-fetcher.spec.ts +++ b/packages/postgrest-core/__tests__/update-fetcher.spec.ts @@ -3,6 +3,7 @@ import { createClient, SupabaseClient } from '@supabase/supabase-js'; import { Database } from './database.types'; import './utils'; +import { PostgrestParser } from '../dist'; import { buildUpdateFetcher } from '../src/update-fetcher'; const TEST_PREFIX = 'postgrest-fetcher-update-'; @@ -79,4 +80,33 @@ describe('update', () => { }, }); }); + + it('should use alias if there is one on the pks', async () => { + const q = client + .from('contact') + .select('test:id,username') + .eq('test', contact!.id); + + const updatedContact = await buildUpdateFetcher( + client.from('contact'), + ['id'], + { queriesForTable: () => [new PostgrestParser(q)] }, + )({ + id: contact?.id, + username: `${testRunPrefix}-username-4`, + }); + expect(updatedContact).toEqual({ + normalizedData: { + id: expect.anything(), + username: `${testRunPrefix}-username-4`, + }, + }); + const { data } = await client + .from('contact') + .select('*') + .eq('id', contact?.id ?? '') + .throwOnError() + .maybeSingle(); + expect(data?.username).toEqual(`${testRunPrefix}-username-4`); + }); }); diff --git a/packages/postgrest-core/src/delete-fetcher.ts b/packages/postgrest-core/src/delete-fetcher.ts index 85efe85d..df2400ac 100644 --- a/packages/postgrest-core/src/delete-fetcher.ts +++ b/packages/postgrest-core/src/delete-fetcher.ts @@ -42,10 +42,15 @@ export const buildDeleteFetcher = ): Promise[] | null> => { let filterBuilder = qb.delete(opts); + const query = buildNormalizedQuery(opts); + + const pkAlias = (path: string): string => + query?.paths.find((p) => p.path === path)?.alias || path; + if (primaryKeys.length === 1) { - const primaryKey = primaryKeys[0]; + const primaryKey = primaryKeys[0] as string; filterBuilder.in( - primaryKey as string, + pkAlias(primaryKey), input.map((i) => { const v = i[primaryKey]; if (!v) { @@ -68,7 +73,7 @@ export const buildDeleteFetcher = `Missing value for primary key ${c as string}`, ); } - return `${c as string}.eq.${v}`; + return `${pkAlias(c as string)}.eq.${v}`; })})`, ) .join(','), @@ -84,7 +89,6 @@ export const buildDeleteFetcher = }, {} as R), ); - const query = buildNormalizedQuery(opts); if (query) { const { selectQuery, userQueryPaths, paths } = query; // make sure that primary keys are included in the select query diff --git a/packages/postgrest-core/src/update-fetcher.ts b/packages/postgrest-core/src/update-fetcher.ts index 9f3a8c4b..a9a32204 100644 --- a/packages/postgrest-core/src/update-fetcher.ts +++ b/packages/postgrest-core/src/update-fetcher.ts @@ -41,13 +41,19 @@ export const buildUpdateFetcher = input: Partial, ): Promise | null> => { let filterBuilder = qb.update(input as any, opts); // todo fix type; + + const query = buildNormalizedQuery(opts); + + const pkAlias = (path: string): string => + query?.paths.find((p) => p.path === path)?.alias || path; + for (const key of primaryKeys) { const value = input[key]; if (!value) throw new Error(`Missing value for primary key ${String(key)}`); - filterBuilder = filterBuilder.eq(key as string, value); + filterBuilder = filterBuilder.eq(pkAlias(key as string), value); } - const query = buildNormalizedQuery(opts); + if (query) { const { selectQuery, userQueryPaths, paths } = query; const { data } = await filterBuilder