Skip to content

Commit d4640c4

Browse files
committed
doc(readme): Improve yet again the readme
1 parent d2beda0 commit d4640c4

1 file changed

Lines changed: 41 additions & 12 deletions

File tree

README.md

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -149,17 +149,22 @@ This plugin will try its best to provide typing to the rules.
149149
- If creating generic or partial rules, use the appropriate helpers (see below).
150150

151151
```typescript
152+
export type Context = {
153+
user?: { id: string };
154+
};
155+
152156
export const Product = objectType({
153157
name: 'Product',
154158
definition(t) {
155159
t.id('id');
160+
t.string('ownerId');
156161
t.string('prop', {
157162
args: {
158163
filter: stringArg({ nullable: false }),
159164
},
160165
shield: ruleType({
161166
resolve: (root, args, ctx) => {
162-
// root => { id: string }, args => { filter: string }
167+
// root => { id: string }, args => { filter: string }, ctx => Context
163168
return true;
164169
},
165170
}),
@@ -171,42 +176,66 @@ export const Product = objectType({
171176
#### Generic rules
172177

173178
- Generic rules are rules that do not depend on the type of the `root` or `args`.
174-
- The wrapper `Generic` is provided for this purpose. It will wrap your rule in a generic function.
179+
- The wrapper `generic` is provided for this purpose. It will wrap your rule in a generic function.
175180

176181
```typescript
177182
const isAuthenticated = generic(
178183
ruleType({
179184
resolve: (root, args, ctx) => {
180185
// Only ctx is typed
181-
return true;
186+
return !!ctx.user;
182187
},
183188
})
184189
);
185190

186-
// Note that `isAuthenticated` is a function
187-
const viewerIsAuthorized = generic(chain(isAuthenticated()));
191+
// Usage
192+
t.string('prop', {
193+
shield: isAuthenticated(),
194+
});
188195
```
189196

190-
#### Partial rules:
197+
#### Partial rules
191198

192199
- Generic rules are rules that depend only on the type of the `root`.
193-
- The wrapper `Partial` is provided for this purpose. It will wrap your rule in a generic function.
200+
- The wrapper `partial` is provided for this purpose. It will wrap your rule in a generic function.
194201

195202
```typescript
196-
const isAuthenticated = partial(
203+
const viewerIsOwner = partial(
197204
ruleType({
198-
type: Product.name, // or 'Product'
205+
type: 'Product' // It is also possible to use the generic parameter of `partial`
199206
resolve: (root, args, ctx) => {
200207
// Both root and ctx are typed
201-
return true;
208+
return root.ownerId === ctx.user.id;
202209
},
203210
})
204211
);
205212

206-
// Note that `isAuthenticated` is a function
207-
const viewerIsAuthorized = partial(chain(isAuthenticated()));
213+
// Usage
214+
t.string('prop', {
215+
shield: viewerIsOwner(),
216+
});
217+
```
218+
219+
#### Combining rules
220+
221+
If you mix and match generic rules with partial rules, you will need to specify the type in the parent helper.
222+
223+
```typescript
224+
const viewerIsAuthorized = partial<'Product'>(
225+
chain(isAuthenticated(), viewerIsOwner())
226+
);
227+
```
228+
229+
However, if you specify it directly in the `shield` field, there is not need for an hlper thus no need for a parameter.
230+
231+
```typescript
232+
t.string('prop', {
233+
shield: chain(isAuthenticated(), viewerIsOwner()),
234+
});
208235
```
209236

210237
### Known issues / limitations
211238

212239
- It is not possible to pass directly an `objectType` to the parameter `type` of a `ruleType`. Tracked by issue: https://github.com/graphql-nexus/schema/issues/451
240+
241+
- The helpers are necessary to provide strong typing and avoid the propagation of `any`. See [this StackOverflow issue](https://stackoverflow.com/questions/62363077/combining-typescript-generics-with-any-without-losing-type/62435780#62435780) for more on the subject.

0 commit comments

Comments
 (0)