11import {
22 PluginError ,
33 PluginOptions ,
4+ RUNTIME_PACKAGE ,
45 createProject ,
56 ensureEmptyDir ,
67 generateModelMeta ,
@@ -9,13 +10,13 @@ import {
910 resolvePath ,
1011 saveProject ,
1112} from '@zenstackhq/sdk' ;
12- import { DataModel , Model } from '@zenstackhq/sdk/ast' ;
13+ import { DataModel , DataModelFieldType , Model , isEnum } from '@zenstackhq/sdk/ast' ;
1314import { getPrismaClientImportSpec , type DMMF } from '@zenstackhq/sdk/prisma' ;
1415import { paramCase } from 'change-case' ;
1516import { lowerCaseFirst } from 'lower-case-first' ;
1617import path from 'path' ;
1718import { Project , SourceFile , VariableDeclarationKind } from 'ts-morph' ;
18- import { match } from 'ts-pattern' ;
19+ import { P , match } from 'ts-pattern' ;
1920import { upperCaseFirst } from 'upper-case-first' ;
2021import { name } from '.' ;
2122
@@ -261,6 +262,62 @@ function generateMutationHook(
261262 func . addStatements ( 'return mutation;' ) ;
262263}
263264
265+ function generateCheckHook (
266+ target : string ,
267+ version : TanStackVersion ,
268+ sf : SourceFile ,
269+ model : DataModel ,
270+ prismaImport : string
271+ ) {
272+ const mapFilterType = ( type : DataModelFieldType ) => {
273+ return match ( type . type )
274+ . with ( P . union ( 'Int' , 'BigInt' ) , ( ) => 'number' )
275+ . with ( 'String' , ( ) => 'string' )
276+ . with ( 'Boolean' , ( ) => 'boolean' )
277+ . otherwise ( ( ) => undefined ) ;
278+ } ;
279+
280+ const filterFields : Array < { name : string ; type : string } > = [ ] ;
281+ const enumsToImport = new Set < string > ( ) ;
282+
283+ // collect filterable fields and enums to import
284+ model . fields . forEach ( ( f ) => {
285+ if ( isEnum ( f . type . reference ?. ref ) ) {
286+ enumsToImport . add ( f . type . reference . $refText ) ;
287+ filterFields . push ( { name : f . name , type : f . type . reference . $refText } ) ;
288+ }
289+
290+ const mappedType = mapFilterType ( f . type ) ;
291+ if ( mappedType ) {
292+ filterFields . push ( { name : f . name , type : mappedType } ) ;
293+ }
294+ } ) ;
295+
296+ if ( enumsToImport . size > 0 ) {
297+ // import enums
298+ sf . addStatements ( `import type { ${ Array . from ( enumsToImport ) . join ( ', ' ) } } from '${ prismaImport } ';` ) ;
299+ }
300+
301+ const whereType = `{ ${ filterFields . map ( ( { name, type } ) => `${ name } ?: ${ type } ` ) . join ( '; ' ) } }` ;
302+
303+ const func = sf . addFunction ( {
304+ name : `useCheck${ model . name } ` ,
305+ isExported : true ,
306+ typeParameters : [ 'TError = DefaultError' ] ,
307+ parameters : [
308+ { name : 'args' , type : `{ operation: PolicyCrudKind; where?: ${ whereType } ; }` } ,
309+ { name : 'options?' , type : makeQueryOptions ( target , 'boolean' , 'boolean' , false , false , version ) } ,
310+ ] ,
311+ } ) ;
312+
313+ func . addStatements ( [
314+ makeGetContext ( target ) ,
315+ `return useModelQuery<boolean, boolean, TError>('${ model . name } ', \`\${endpoint}/${ lowerCaseFirst (
316+ model . name
317+ ) } /check\`, args, options, fetch);`,
318+ ] ) ;
319+ }
320+
264321function generateModelHooks (
265322 target : TargetFramework ,
266323 version : TanStackVersion ,
@@ -494,6 +551,11 @@ function generateModelHooks(
494551 `TArgs extends { select: any; } ? TArgs['select'] extends true ? number : Prisma.GetScalarType<TArgs['select'], Prisma.${ modelNameCap } CountAggregateOutputType> : number`
495552 ) ;
496553 }
554+
555+ {
556+ // extra `check` hook for ZenStack's permission checker API
557+ generateCheckHook ( target , version , sf , model , prismaImport ) ;
558+ }
497559}
498560
499561function generateIndex (
@@ -538,6 +600,7 @@ function makeBaseImports(target: TargetFramework, version: TanStackVersion) {
538600 const shared = [
539601 `import { useModelQuery, useInfiniteModelQuery, useModelMutation } from '${ runtimeImportBase } /${ target } ';` ,
540602 `import type { PickEnumerable, CheckSelect, QueryError, ExtraQueryOptions, ExtraMutationOptions } from '${ runtimeImportBase } ';` ,
603+ `import type { PolicyCrudKind } from '${ RUNTIME_PACKAGE } '` ,
541604 `import metadata from './__model_meta';` ,
542605 `type DefaultError = QueryError;` ,
543606 ] ;
0 commit comments