Skip to content

Commit

Permalink
implement namespaced routers support
Browse files Browse the repository at this point in the history
  • Loading branch information
omar-dulaimi committed Jan 13, 2023
1 parent 73397cd commit 566eacf
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 18 deletions.
29 changes: 27 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ const permissions = shield<Context>({
mutation: {
addFruitToBasket: isAuthenticated,
},
})
});

export const t = trpc.initTRPC.context<Context>().create();

Expand All @@ -128,7 +128,32 @@ export const shieldedProcedure = t.procedure.use(permissionsMiddleware);
For a fully working example, [go here](https://github.com/omar-dulaimi/trpc-shield/tree/master/example).
## Documentation

### `shield(rules?, options?)`
### Namespaced routers

```ts
export const permissions = shield<Context>({
user: {
query: {
aggregateUser: allow,
findFirstUser: allow,
findManyUser: isAuthenticated,
findUniqueUser: allow,
groupByUser: allow,
},
mutation: {
createOneUser: isAuthenticated,
deleteManyUser: allow,
deleteOneUser: allow,
updateManyUser: allow,
updateOneUser: allow,
upsertOneUser: allow,
},
},
});
```

### API
#### `shield(rules?, options?)`

> Generates tRPC Middleware layer from your rules.
Expand Down
42 changes: 27 additions & 15 deletions src/generator.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { IOptions, IRules } from './types'
import { IOptions, IRules } from './types';

/**
*
Expand All @@ -20,23 +20,35 @@ export function generateMiddlewareFromRuleTree<TContext extends Record<string, u
input,
rawInput,
}: {
next: Function
ctx: { [name: string]: any }
type: string
path: string
input: { [name: string]: any }
rawInput: unknown
next: Function;
ctx: { [name: string]: any };
type: string;
path: string;
input: { [name: string]: any };
rawInput: unknown;
}) => {
const opWithPath: Array<string> = path.split('.')
const opName: string = opWithPath[opWithPath.length - 1]
const rule = ruleTree?.[type]?.[opName] || options.fallbackRule
const opWithPath: Array<string> = path.split('.');
const opName: string = opWithPath[opWithPath.length - 1];
const keys = Object.keys(ruleTree);
let rule;
if (keys.includes('query') || keys.includes('mutation')) {
rule = ruleTree?.[type]?.[opName] || options.fallbackRule;
} else {
for (const key of keys) {
const namespace = ruleTree[key];
if (namespace?.[type]?.[opName]) {
rule = namespace?.[type]?.[opName] || options.fallbackRule;
break;
}
}
}

if (rule) {
return rule?.resolve(ctx, type, path, input, rawInput, options).then((result: any) => {
if (!result) throw options.fallbackError
return next()
})
if (!result) throw options.fallbackError;
return next();
});
}
return next()
}
return next();
};
}
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export interface IRuleConstructorOptions {}
// Rules Definition Tree

export interface IRuleTypeMap<TContext> {
[key: string]: ShieldRule<TContext> | IRuleFieldMap<TContext>
[key: string]: ShieldRule<TContext> | IRuleFieldMap<TContext> | IRuleTypeMap<TContext>
}

export interface IRuleFieldMap<TContext> {
Expand Down

0 comments on commit 566eacf

Please sign in to comment.