Skip to content

Commit

Permalink
Merge pull request #495 from elyobo/lo/do-not-set-primary-keys-in-update
Browse files Browse the repository at this point in the history
Strip primary keys from the update payload
  • Loading branch information
psteinroe authored Aug 28, 2024
2 parents 146d436 + 4d2d1e7 commit 5bacd08
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 12 deletions.
7 changes: 7 additions & 0 deletions .changeset/tricky-pans-draw.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@supabase-cache-helpers/postgrest-core": minor
"@supabase-cache-helpers/postgrest-react-query": minor
"@supabase-cache-helpers/postgrest-swr": minor
---

Strip primary keys from the update payload
21 changes: 17 additions & 4 deletions packages/postgrest-core/src/update-fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ export type UpdateFetcherOptions<
S extends GenericSchema,
T extends GenericTable,
Re = T extends { Relationships: infer R } ? R : unknown,
> = Parameters<PostgrestQueryBuilder<S, T, Re>['update']>[1];
> = Parameters<PostgrestQueryBuilder<S, T, Re>['update']>[1] & {
stripPrimaryKeys?: boolean;
};

export const buildUpdateFetcher =
<
Expand All @@ -35,13 +37,24 @@ export const buildUpdateFetcher =
>(
qb: PostgrestQueryBuilder<S, T, Re>,
primaryKeys: (keyof T['Row'])[],
opts: BuildNormalizedQueryOps<Q> & UpdateFetcherOptions<S, T>,
{
stripPrimaryKeys = true,
...opts
}: BuildNormalizedQueryOps<Q> & UpdateFetcherOptions<S, T>,
): UpdateFetcher<T, R> =>
async (
input: Partial<T['Row']>,
): Promise<MutationFetcherResponse<R> | null> => {
let filterBuilder = qb.update(input as any, opts); // todo fix type;

const payload = stripPrimaryKeys
? primaryKeys.reduce<typeof input>(
(acc, key) => {
delete acc[key];
return acc;
},
{ ...input },
)
: input;
let filterBuilder = qb.update(payload as any, opts); // todo fix type;
for (const key of primaryKeys) {
const value = input[key];
if (!value)
Expand Down
51 changes: 43 additions & 8 deletions packages/postgrest-core/tests/update-fetcher.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type SupabaseClient, createClient } from '@supabase/supabase-js';
import { beforeAll, describe, expect, it } from 'vitest';
import { beforeAll, describe, expect, it, vi } from 'vitest';

import type { Database } from './database.types';
import './utils';
Expand Down Expand Up @@ -41,20 +41,55 @@ describe('update', () => {
});

it('should update entity by primary keys', async () => {
const updatedContact = await buildUpdateFetcher(
client.from('contact'),
['id'],
{ queriesForTable: () => [] },
)({
const qb = client.from('contact');
const updateSpy = vi.spyOn(qb, 'update');
const username = `${testRunPrefix}-username-2`;
const updatedContact = await buildUpdateFetcher(qb, ['id'], {
stripPrimaryKeys: false,
queriesForTable: () => [],
})({
id: contact?.id,
username,
});
expect(updatedContact).toEqual({
normalizedData: {
id: expect.anything(),
username,
},
});
expect(updateSpy).toHaveBeenCalledWith(
{
id: expect.anything(),
username,
},
expect.anything(),
);
const { data } = await client
.from('contact')
.select('*')
.eq('id', contact?.id ?? '')
.throwOnError()
.maybeSingle();
expect(data?.username).toEqual(`${testRunPrefix}-username-2`);
});

it('should update entity by primary keys excluding primary keys in payload', async () => {
const qb = client.from('contact');
const updateSpy = vi.spyOn(qb, 'update');
const username = `${testRunPrefix}-username-2`;
const updatedContact = await buildUpdateFetcher(qb, ['id'], {
queriesForTable: () => [],
})({
id: contact?.id,
username: `${testRunPrefix}-username-2`,
username,
});
expect(updatedContact).toEqual({
normalizedData: {
id: expect.anything(),
username: `${testRunPrefix}-username-2`,
username,
},
});
expect(updateSpy).toHaveBeenCalledWith({ username }, expect.anything());
const { data } = await client
.from('contact')
.select('*')
Expand Down

0 comments on commit 5bacd08

Please sign in to comment.