export interface LinkDefinition { targetType : string ; targetFieldName : string ; sourceField : string ; argumentSources : LinkFieldArgumentSourceDefinition [ ] ; } export interface LinkFieldArgumentSourceDefinition { name : string ; type : "objectField" | "fieldArgument" ; path : string [ ] ; } class LinkBuilder < T , R extends { } = { } , TT = { } > { constructor ( current = { } , sourceField , targetType , targetField ) { this . current = current ; this . sourceField = sourceField ; this . targetType = targetType ; this . targetField = targetField ; } private readonly sourceField : string ; private readonly targetType : string ; private readonly targetField : string ; private current : R = { } ; argument < P extends Exclude < keyof T , keyof R > , V extends T [ P ] , S extends "fieldArgument" | "objectField" > ( key , source , value , ... extraPath ) { const extra = { [ key ] : { source , path : [ value , ... extraPath ] } } ; const instance = { ... ( this . current as object ) , ... extra , } as R & Pick < T , P > ; return new LinkBuilder < T , R & Pick < T , P > , TT > ( instance , this . sourceField , this . targetType , this . targetField ) ; } build = ( ) : LinkDefinition => { const args = this . current as { [ key ] : { path : string [ ] ; source : "fieldArgument" | "objectField" ; } ; } ; return { argumentSources : Object . keys ( args ) . map ( ( key ) => ( { name : key , type : args [ key ] . source , path : args [ key ] . path , } ) ) , targetType : this . targetType , sourceField : this . sourceField , targetFieldName : this . targetField , } ; } ; } export const sourceStep = < T extends { } , R extends { } > ( ) => ( { source : < F extends keyof T > ( field ) => { return targetStep < T , F , R > ( field ) ; } , } ) ; const targetStep = < T , F extends keyof T , R > ( field ) => ( { target : < r extends keyof R > ( targetType , targetField ) => { return new LinkBuilder < T [ F ] , { } , R [ r ] > ( { } , field as string , targetType as string , targetField ) ; } , } ) ; interface TargetTypes { db_UsersCountOutputType : "messages" ; db_users : "id" | "email" | "name" | "updatedat" | "lastlogin" | "messages" | "_count" ; db_messages : "id" | "user_id" | "message" | "users" ; db_MessagesCountAggregateOutputType : "id" | "user_id" | "message" | "_all" ; db_MessagesAvgAggregateOutputType : "id" | "user_id" ; db_MessagesSumAggregateOutputType : "id" | "user_id" ; db_MessagesMinAggregateOutputType : "id" | "user_id" | "message" ; db_MessagesMaxAggregateOutputType : "id" | "user_id" | "message" ; db_AggregateMessages : "_count" | "_avg" | "_sum" | "_min" | "_max" ; db_MessagesGroupByOutputType : "id" | "user_id" | "message" | "_count" | "_avg" | "_sum" | "_min" | "_max" ; db_UsersCountAggregateOutputType : "id" | "email" | "name" | "updatedat" | "lastlogin" | "_all" ; db_UsersAvgAggregateOutputType : "id" ; db_UsersSumAggregateOutputType : "id" ; db_UsersMinAggregateOutputType : "id" | "email" | "name" | "updatedat" | "lastlogin" ; db_UsersMaxAggregateOutputType : "id" | "email" | "name" | "updatedat" | "lastlogin" ; db_AggregateUsers : "_count" | "_avg" | "_sum" | "_min" | "_max" ; db_UsersGroupByOutputType : "id" | "email" | "name" | "updatedat" | "lastlogin" | "_count" | "_avg" | "_sum" | "_min" | "_max" ; db_AffectedRowsOutput : "count" ; } interface SourceFields { db_findFirstmessages : { where : null ; orderBy : null ; cursor : null ; take : null ; skip : null ; distinct : null ; } ; db_findManymessages : { where : null ; orderBy : null ; cursor : null ; take : null ; skip : null ; distinct : null ; } ; db_aggregatemessages : { where : null ; orderBy : null ; cursor : null ; take : null ; skip : null ; } ; db_groupBymessages : { where : null ; orderBy : null ; by : null ; having : null ; take : null ; skip : null ; } ; db_findUniquemessages : { where : null ; } ; db_findFirstusers : { where : null ; orderBy : null ; cursor : null ; take : null ; skip : null ; distinct : null ; } ; db_findManyusers : { where : null ; orderBy : null ; cursor : null ; take : null ; skip : null ; distinct : null ; } ; db_aggregateusers : { where : null ; orderBy : null ; cursor : null ; take : null ; skip : null ; } ; db_groupByusers : { where : null ; orderBy : null ; by : null ; having : null ; take : null ; skip : null ; } ; db_findUniqueusers : { where : null ; } ; } const linkBuilder = sourceStep < SourceFields , TargetTypes > ( ) ; export default linkBuilder ;