import { Collection , ComponentRequestTable , ConceptDb , ConceptServer , ConceptServerBuilder , Config , Context , getReturnFields } from '@deja-vu/concept-server' ; import { CreateMarkerInput , MarkerDoc , MarkersInput , UpdateMarkerInput } from './schema' ; import { IResolvers } from 'graphql-tools' ; import { v4 as uuid } from 'uuid' ; const componentRequestTable = { 'show-marker' : ( extraInfo ) => `
    query ShowMarker($id: ID!) {
      marker(id: $id) ${ getReturnFields ( extraInfo ) }
    }
  ` , 'create-marker' : ( extraInfo ) => `
    mutation CreateMarker($input: CreateMarkerInput!) {
      createMarker (input: $input) ${ getReturnFields ( extraInfo ) }
    }
  ` , 'create-marker-from-map' : ( extraInfo ) => `
    mutation CreateMarker($input: CreateMarkerInput!) {
      createMarker (input: $input) ${ getReturnFields ( extraInfo ) }
    }
  ` , 'delete-marker' : ( extraInfo ) => `
    mutation DeleteMarker($id: ID!) {
      deleteMarker (id: $id) ${ getReturnFields ( extraInfo ) }
    }
  ` , 'display-map' : ( extraInfo ) => `
    query DisplayMap($input: MarkersInput!) {
      markers(input: $input) ${ getReturnFields ( extraInfo ) }
    }
  ` , 'show-markers' : ( extraInfo ) => `
    query ShowMarkers($input: MarkersInput!) {
      markers(input: $input) ${ getReturnFields ( extraInfo ) }
    }
  ` , 'show-marker-count' : ( extraInfo ) => `
    query ShowMarkerCount($input: MarkersInput!) {
      markerCount(input: $input) ${ getReturnFields ( extraInfo ) }
    }
  ` , 'update-marker-from-map' : ( extraInfo ) => `
    mutation UpdateMarker($input: UpdateMarkerInput!) {
      updateMarker (input: $input) ${ getReturnFields ( extraInfo ) }
    }
  ` } ; function milesToRadian ( miles ) { const earthRadiusInMiles = 3963.2 ; return miles / earthRadiusInMiles ; } function resolvers ( db , _config ) { const markers = db . collection ( 'markers' ) ; return { Query : { marker : async ( _root , { id } ) => await markers . findOne ( { id } ) , markers : async ( _root , { input } ) => { const filter = { } ; if ( input . ofMapId ) { filter [ 'mapId' ] = input . ofMapId ; } if ( input . centerLat && input . centerLng && input . radius ) { filter [ 'location' ] = { $geoWithin : { $centerSphere : [ [ input . centerLng , input . centerLat ] , milesToRadian ( input . radius ) ] } } ; } if ( input . markerIds ) { filter [ 'id' ] = { $in : input . markerIds } ; } return await markers . find ( filter ) ; } } , Marker : { id : ( marker ) => marker . id , title : ( marker ) => marker . title , latitude : ( marker ) => marker . location . coordinates [ 1 ] , longitude : ( marker ) => marker . location . coordinates [ 0 ] , mapId : ( marker ) => marker . mapId } , Mutation : { createMarker : async ( _root , { input } , context ) => { const newMarker = { id : input . id ? input . id : uuid ( ) , title : input . title ? input . title : '' , location : { type : 'Point' , coordinates : [ input . longitude , input . latitude ] } , mapId : input . mapId } ; return await markers . insertOne ( context , newMarker ) ; } , deleteMarker : async ( _root , { id } , context ) => await markers . deleteOne ( context , { id } ) , updateMarker : async ( _root , { input } , context ) => { const newMarker = { id : input . id , title : input . title ? input . title : '' , location : { type : 'Point' , coordinates : [ input . longitude , input . latitude ] } , mapId : input . mapId } ; return await markers . updateOne ( context , { id : newMarker . id } , { $set : newMarker } , { upsert : true } ) ; } } } ; } const geolocationConcept = new ConceptServerBuilder ( 'geolocation' ) . initDb ( ( db , _config ) : Promise < any > => { const markers = db . collection ( 'markers' ) ; return Promise . all ( [ markers . createIndex ( { id : 1 } , { unique : true , sparse : true } ) , markers . createIndex ( { id : 1 , mapId : 1 , location : '2dsphere' } , { unique : true , sparse : true } ) ] ) ; } ) . componentRequestTable ( componentRequestTable ) . resolvers ( resolvers ) . build ( ) ; geolocationConcept . start ( ) ;