Skip to content

Commit

Permalink
fix: 🐛 deep merge nested rule relations
Browse files Browse the repository at this point in the history
  • Loading branch information
dennemark committed Nov 27, 2024
1 parent 636bcd2 commit bb933e1
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 4 deletions.
9 changes: 5 additions & 4 deletions src/applyRuleRelationsQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { rulesToAST } from '@casl/ability/extra';
import { createPrismaAbility, PrismaQuery } from '@casl/prisma';
import { Prisma } from '@prisma/client';
import { convertCreationTreeToSelect, CreationTree } from './convertCreationTreeToSelect';
import { deepMerge } from './deepMerge';
import { getRuleRelationsQuery } from './getRuleRelationsQuery';
import { relationFieldsByModel } from './helpers';

Expand Down Expand Up @@ -174,10 +175,10 @@ function getNestedQueryRelations(args: any, abilities: PureAbility<AbilityTuple,
const relationField = relationFieldsByModel[model][relation]

if (relationField) {
const nestedQueryRelations = {
...getNestedQueryRelations(args[method][relation], abilities, action === 'all' ? 'all' : 'read', relationField.type as Prisma.ModelName),
...(queryRelations[relation]?.select ?? {})
}
const nestedQueryRelations = deepMerge(
getNestedQueryRelations(args[method][relation], abilities, action === 'all' ? 'all' : 'read', relationField.type as Prisma.ModelName),
(typeof queryRelations[relation]?.select === 'object' ? queryRelations[relation]?.select : {})
)
if (nestedQueryRelations && Object.keys(nestedQueryRelations).length > 0) {
queryRelations[relation] = {
...(queryRelations[relation] ?? {}),
Expand Down
32 changes: 32 additions & 0 deletions src/deepMerge.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* Simple object check.
* @param item
* @returns {boolean}
*/
export function isObject(item: any) {
return (item && typeof item === 'object' && !Array.isArray(item));
}

/**
* https://stackoverflow.com/questions/27936772/how-to-deep-merge-instead-of-shallow-merge
* Deep merge two objects.
* @param target
* @param ...sources
*/
export function deepMerge(target: any, ...sources: any[]) {
if (!sources.length) return target;
const source = sources.shift();

if (isObject(target) && isObject(source)) {
for (const key in source) {
if (isObject(source[key])) {
if (!target[key]) Object.assign(target, { [key]: {} });
deepMerge(target[key], source[key]);
} else {
Object.assign(target, { [key]: source[key] });
}
}
}

return deepMerge(target, ...sources);
}

0 comments on commit bb933e1

Please sign in to comment.