albertyw/codemancer

View on GitHub
server/location.ts

Summary

Maintainability
A
25 mins
Test Coverage
import {Client as GoogleMapsClient, ReverseGeocodeResponse} from '@googlemaps/google-maps-services-js';

import getRollbar from '../codemancer/js/rollbar.js';
import { unique } from '../codemancer/js/util.js';
import varsnap from '../codemancer/js/varsnap.js';

export interface LocationData {
  wfo: string;
  x: string;
  y: string;
  lat: number;
  lng: number;
  timezone: string;
  displayName: string;
}

const sanFranciscoLocation: LocationData = {
  // Generated from https://api.weather.gov/points/37.78,-122.41
  wfo: 'MTR', x: '85', y: '105',
  lat: 37.78, lng: -122.41,
  timezone: 'America/Los_Angeles',
  displayName: '',
};
export const targetLocation = sanFranciscoLocation;

const googleMapsClient = new GoogleMapsClient({});

export const Location = {
  getLocation: function(): Promise<LocationData> {
    return googleMapsClient.reverseGeocode({
      params: {
        latlng: [targetLocation.lat, targetLocation.lng],
        key: process.env.GEOCODING_API_KEY_BACKEND,
      },
    }).then((response: ReverseGeocodeResponse) => {
      if (response.data.status === 'OK') {
        targetLocation.displayName = Location.parseDisplayName(response.data);
      } else {
        getRollbar().error('Failed to geocode', response);
      }
      return targetLocation;
    }, (error) => {
      getRollbar().error('Failed to geocode', error);
      return targetLocation;
    }).catch((error) => {
      getRollbar().error('Failed to geocode', error);
      return targetLocation;
    });
  },

  parseDisplayName: varsnap(function parseDisplayName(data: any): string {
    const result=data.results[0].address_components;
    const info=[];
    for(let i=0;i<result.length;++i) {
      const type = result[i].types[0];
      if(type==='country'){
        info.push(result[i].long_name);
      } else if(type==='administrative_area_level_1'){
        info.push(result[i].short_name);
      } else if(type==='locality'){
        info.unshift(result[i].long_name);
      }
    }
    const locData = unique(info);
    if (locData.length === 3) {
      locData.pop();
    }
    return locData.join(', ');
  }),
};