@@ -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+
152156export 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
177182const 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