Skip to content

Commit

Permalink
fix: allow mutation selection without passing a patch builder (#964)
Browse files Browse the repository at this point in the history
  • Loading branch information
nkgentile authored Jan 16, 2025
1 parent ddfd244 commit fd70208
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 1 deletion.
27 changes: 26 additions & 1 deletion src/data/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type {
IdentifiedSanityDocumentStub,
MultipleMutationResult,
Mutation,
MutationSelection,
PatchOperations,
SanityDocument,
SanityDocumentStub,
Expand Down Expand Up @@ -213,16 +214,29 @@ export class Transaction extends BaseTransaction {
* @param patchOps - Operations to perform, or a builder function
*/
patch(documentId: string, patchOps?: PatchBuilder | PatchOperations): this
/**
* Performs a patch on the given selection. Can either be a builder function or an object of patch operations.
*
* @param selection - An object with `query` and optional `params`, defining which document(s) to patch
* @param patchOps - Operations to perform, or a builder function
*/
patch(patch: MutationSelection, patchOps?: PatchBuilder | PatchOperations): this
/**
* Adds the given patch instance to the transaction.
* The operation is added to the current transaction, ready to be commited by `commit()`
*
* @param patch - Patch to execute
*/
patch(patch: Patch): this
patch(patchOrDocumentId: Patch | string, patchOps?: PatchBuilder | PatchOperations): this {
patch(
patchOrDocumentId: Patch | MutationSelection | string,
patchOps?: PatchBuilder | PatchOperations,
): this {
const isBuilder = typeof patchOps === 'function'
const isPatch = typeof patchOrDocumentId !== 'string' && patchOrDocumentId instanceof Patch
const isMutationSelection =
typeof patchOrDocumentId === 'object' &&
('query' in patchOrDocumentId || 'id' in patchOrDocumentId)

// transaction.patch(client.patch('documentId').inc({visits: 1}))
if (isPatch) {
Expand All @@ -239,6 +253,17 @@ export class Transaction extends BaseTransaction {
return this._add({patch: patch.serialize()})
}

/**
* transaction.patch(
* {query: "*[_type == 'person' && points >= $threshold]", params: { threshold: 100 }},
* {dec: { points: 100 }, inc: { bonuses: 1 }}
* )
*/
if (isMutationSelection) {
const patch = new Patch(patchOrDocumentId, patchOps || {}, this.#client)
return this._add({patch: patch.serialize()})
}

return this._add({patch: {id: patchOrDocumentId, ...patchOps}})
}
}
Expand Down
42 changes: 42 additions & 0 deletions test/client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2379,6 +2379,48 @@ describe('client', async () => {
])
})

test('patch can use a mutation selector', () => {
const transaction = getClient()
.transaction()
.patch(
{
query: '*[_id in $ids]',
params: {ids: ['abc123', 'foo.456']},
},
{inc: {count: 1}},
)

expect(transaction.serialize()).toEqual([
{
patch: {
query: '*[_id in $ids]',
params: {ids: ['abc123', 'foo.456']},
inc: {count: 1},
},
},
])

const transactionWithCallback = getClient()
.transaction()
.patch(
{
query: '*[_id in $ids]',
params: {ids: ['abc123', 'foo.456']},
},
(p) => p.inc({count: 1}),
)

expect(transactionWithCallback.serialize()).toEqual([
{
patch: {
query: '*[_id in $ids]',
params: {ids: ['abc123', 'foo.456']},
inc: {count: 1},
},
},
])
})

test.skipIf(isEdge)('executes transaction when commit() is called', async () => {
const mutations = [{create: {_type: 'foo', bar: true}}, {delete: {id: 'barfoo'}}]
nock(projectHost())
Expand Down

0 comments on commit fd70208

Please sign in to comment.