import * as uutil from "@adpt/utils" ; import * as fs from "fs" ; import { execute as gqlExecute , GraphQLSchema } from "graphql" ; import { makeExecutableSchema } from "graphql-tools" ; import * as path from "path" ; import { ObserverNeedsData } from "./errors" ; import { ExecutedQuery } from "./obs_manager_deployment" ; import { ObserverPlugin , ObserverResponse } from "./plugin" ; import { MockObject , Resolvers } from "../../generated/src/observers/mock_observer_schema_types" ; import { registerObserver } from "./registry" ; const schemaFile = path . join ( __dirname , "mock_observer.graphql" ) ; const schemaStr = fs . readFileSync ( schemaFile ) . toString ( ) ; type CachedObject = Partial < MockObject > & { id : string ; numericId : number ; } ; interface CachedData { mockObjects : CachedObject [ ] ; } const queryCacheResolvers = { Query : { mockById : async ( _obj , args , cache , _info ) => { await uutil . sleep ( 0 ) ; const ret = cache ? cache . mockObjects . find ( ( o ) => o . id === args . id ) : undefined ; if ( ret !== undefined ) return ret ; const id = Number ( args . id ) ; if ( Number . isNaN ( id ) ) return null ; if ( Math . floor ( id ) !== id ) return null ; throw new ObserverNeedsData ( ) ; } , } } ; const observeResolvers = { Query : { mockById : async ( _obj , args , cache , _info ) => { await uutil . sleep ( 0 ) ; const id = Number ( args . id ) ; await uutil . sleep ( Math . min ( id , 10 ) ) ; if ( Number . isNaN ( id ) ) return null ; if ( Math . floor ( id ) !== id ) return null ; let ret = cache && cache . mockObjects . find ( ( o ) => o . id === args . id ) ; if ( ret === undefined ) { ret = { id : id . toString ( ) , numericId : id } ; cache . mockObjects . push ( ret ) ; } return ret ; } } , MockObject : { idSquared : async ( inObj , _args , _context , _info ) => { const obj = inObj as CachedObject ; obj . idSquared = obj . numericId * obj . numericId ; return obj . idSquared ; } , idPlusOne : async ( inObj , _args , _context , _info ) => { const obj = inObj as CachedObject ; obj . idPlusOne = obj . numericId + 1 ; return obj . idPlusOne ; } } } ; export class MockObserver implements ObserverPlugin < undefined , CachedData > { static observerName : string ; static schema_ = makeExecutableSchema ( { typeDefs : schemaStr , resolvers : queryCacheResolvers } ) ; static fetchSchema_ = makeExecutableSchema ( { typeDefs : schemaStr , resolvers : observeResolvers } ) ; constructor ( public neverObserve = false ) { } get schema ( ) : GraphQLSchema { return MockObserver . schema_ ; } observe = async ( possibleQueries ) : Promise < ObserverResponse < undefined , CachedData > > => { const cache = { mockObjects : [ ] } ; if ( ! this . neverObserve ) { const waitFor = possibleQueries . map ( ( q ) => Promise . resolve ( gqlExecute ( MockObserver . fetchSchema_ , q . query , null , cache , q . variables ) ) ) ; await Promise . all ( waitFor ) ; } return { context : cache } ; } ; } export default MockObserver ; registerObserver ( new MockObserver ( ) ) ;