Skip to content

Commit

Permalink
fix: 🐛 retransform data query on updateMany query
Browse files Browse the repository at this point in the history
  • Loading branch information
dennemark committed Sep 20, 2024
1 parent 53a8c85 commit a327b0e
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 0 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,9 @@ Here are some performance metrics for the above query for the small test sqlite
#### Nested fields and wildcards are not supported / tested
`can('read', 'User', ['nested.field', 'field.*'])` probably won't work.
#### Combined relation fields are not supported
`entry Relation @relation(fields: [entryIdA, entryIdB], references: [refA, refB])` does not work.
`entry Relation @relation(fields: [entryId], references: [ref])` does work.
Since internally a relation like `entryId: someId` might be replaced by `entry: { connect: { ref: someId, ...caslConditions } }`
4 changes: 4 additions & 0 deletions src/applyCaslToQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { applyIncludeSelectQuery } from "./applyIncludeSelectQuery"
import { applyRuleRelationsQuery } from './applyRuleRelationsQuery'
import { applyWhereQuery } from "./applyWhereQuery"
import { caslOperationDict, PrismaCaslOperation } from "./helpers"
import { transformDataToWhereQuery } from "./transformDataToWhereQuery"

/**
* Applies CASL authorization logic to prisma query
Expand All @@ -26,6 +27,9 @@ export function applyCaslToQuery(operation: PrismaCaslOperation, args: any, abil
const { args: dataArgs, creationTree: dataCreationTree } = applyDataQuery(abilities, args.data, operationAbility.action, model)
creationTree = dataCreationTree
args.data = dataArgs
if (operation === 'updateMany') {
args = transformDataToWhereQuery(args, model)
}
}


Expand Down
33 changes: 33 additions & 0 deletions src/transformDataToWhereQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { relationFieldsByModel } from "./helpers"

export function transformDataToWhereQuery(args: any, model: string) {

;['connect', 'disconnect'].forEach((action) => {
Object.entries(args.data).forEach(([relation, obj]: [string, any]) => {
if (typeof obj === 'object' && !Array.isArray(obj) && obj[action]) {
// combine args.data.relation[action].AND and args.where.AND
const ANDArgs = { AND: [...(obj[action].AND ?? []), ...(args.where[relation]?.AND ?? [])] }
const relationTo = relationFieldsByModel[model][relation].relationToFields?.[0]
const relationFrom = relationFieldsByModel[model][relation].relationFromFields?.[0]
if (!relationTo || !relationFrom) {
throw new Error('Cannot find correct relations to transform updateMany to casl query.')
}
args.where = {
...(args.where ?? {}),
[relation]: {
...(args.where[relation] ?? {}),
...obj[action],
...(ANDArgs.AND.length > 0 ? ANDArgs : {})
}
}
args.data = {
...args.data,
[relationFrom]: obj[action][relationTo]
}
delete args.data[relation]
delete args.where[relation][relationTo]
}
})
})
return args
}
21 changes: 21 additions & 0 deletions test/transformDataToWhereQuery.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { transformDataToWhereQuery } from '../src/transformDataToWhereQuery'

describe('transform data to where query', () => {

it('converts data relations with connect to where query and transforms to relationField data entries', () => {

const result = transformDataToWhereQuery({ data: { id: 1, thread: { connect: { id: 0, text: 'a' } } }, where: { id: 0 } },
'Post'
)
expect(result.data).toEqual({ id: 1, threadId: 0 })
expect(result.where).toEqual({ id: 0, thread: { text: 'a' } })
})

it('converts data relations with disconnect to where query and transforms to relationField data entries', () => {
const result = transformDataToWhereQuery({ data: { id: 1, thread: { disconnect: { id: 0, text: 'a' } } }, where: { id: 0 } },
'Post'
)
expect(result.data).toEqual({ id: 1, threadId: 0 })
expect(result.where).toEqual({ id: 0, thread: { text: 'a' } })
})
})

0 comments on commit a327b0e

Please sign in to comment.