import firebase from 'firebase/app' ; import { GraphQLSelectionSet } from '../types/GraphQL' ; import { FiregraphResult } from '../types/Firegraph' ; import { resolveCollection } from './Collection' ; import { CacheManager } from './CacheManager' ; param store param documentPath param selectionSet param cacheManager export async function resolveDocument ( store , documentPath , selectionSet , cacheManager , fetchedDocument ? ) { let data ; let doc ; let docResult = { } ; let cachedDoc = cacheManager . getDocument ( documentPath ) ; if ( cachedDoc != undefined ) { doc = cachedDoc ; data = doc . data ( ) ; } else if ( fetchedDocument ) { doc = fetchedDocument ; data = fetchedDocument . data ( ) ; } else { doc = await store . doc ( documentPath ) . get ( ) ; data = doc . data ( ) ; cacheManager . saveDocument ( documentPath , doc ) ; } if ( selectionSet && selectionSet . selections ) { const fieldsToRetrieve = selectionSet . selections ; for ( let field of fieldsToRetrieve ) { let args = { } ; for ( let arg of field . arguments ! ) { args [ ( arg as any ) . name . value ] = ( arg as any ) . value . value ; } const fieldName = ( field as any ) . name . value ; const { selectionSet } = field ; const { alias } = field ; if ( selectionSet && selectionSet . selections ) { let nestedPath ; if ( typeof data [ fieldName ] == 'string' ) { const docId = data [ fieldName ] ; const { path } = args ; let documentParentPath = path ? path : '' ; nestedPath = `${ documentParentPath }${ docId }` ; const nestedResult = await resolveDocument ( store , nestedPath , selectionSet , cacheManager ) ; if ( alias != undefined ) docResult [ ( alias as any ) . value ] = nestedResult ; else docResult [ fieldName ] = nestedResult ; } else if ( data [ fieldName ] != undefined && data [ fieldName ] . constructor ! . name ! . startsWith ( 'DocumentReference' ) ) { nestedPath = `${ data [ fieldName ] . path }` ; const nestedResult = await resolveDocument ( store , nestedPath , selectionSet , cacheManager ) ; if ( alias != undefined ) docResult [ ( alias as any ) . value ] = nestedResult ; else docResult [ fieldName ] = nestedResult ; } else { nestedPath = `${ documentPath }/${ fieldName }` ; const nestedResult = await resolveCollection ( store , nestedPath , args , selectionSet , cacheManager ) ; if ( alias != undefined ) docResult [ ( alias as any ) . value ] = nestedResult . docs ; else docResult [ fieldName ] = nestedResult . docs ; } } else { if ( fieldName === 'id' ) { docResult [ fieldName ] = doc . id ; } else { if ( alias != undefined ) docResult [ ( alias as any ) . value ] = data [ fieldName ] ; else docResult [ fieldName ] = data [ fieldName ] ; } } } } return docResult ; }