@@ -6,13 +6,11 @@ import {
66 usaEpa ,
77} from '@shootismoke/convert' ;
88import { format , utcToZonedTime } from 'date-fns-tz' ;
9- import * as E from 'fp-ts/lib/Either' ;
10- import { pipe } from 'fp-ts/lib/pipeable' ;
119
1210import { OpenAQResults } from '../../types' ;
1311import { getCountryCode , providerError } from '../../util' ;
1412import sanitized from './sanitized.json' ;
15- import type { AqicnStaton } from './validation' ;
13+ import type { AqicnData } from './validation' ;
1614
1715/**
1816 * Sanitize the country we get here from aqicn. For example, for China, the
@@ -32,28 +30,20 @@ export function sanitizeCountry(input: string): string {
3230}
3331
3432/**
35- * Normalize aqicn byGps data
33+ * Normalize aqicn byGps data. Throws an error if the data cannot be normalized.
3634 *
3735 * @param data - The data to normalize
3836 */
39- export function normalize ( data : AqicnStaton ) : E . Either < Error , OpenAQResults > {
40- if ( ! data || typeof data === 'string' ) {
41- return E . left (
42- providerError ( 'aqicn' , `Cannot normalized ${ data || 'undefined' } ` )
43- ) ;
44- }
45-
37+ export function normalize ( data : AqicnData ) : OpenAQResults {
4638 const stationId = `aqicn|${ data . idx } ` ;
4739
4840 // Sometimes we don't get geo
4941 if ( ! data . city . geo ) {
50- return E . left (
51- providerError (
52- 'aqicn' ,
53- `Cannot normalize station ${ stationId } , no city: ${ JSON . stringify (
54- data
55- ) } `
56- )
42+ throw providerError (
43+ 'aqicn' ,
44+ `Cannot normalize station ${ stationId } , no city: ${ JSON . stringify (
45+ data
46+ ) } `
5747 ) ;
5848 }
5949
@@ -63,27 +53,21 @@ export function normalize(data: AqicnStaton): E.Either<Error, OpenAQResults> {
6353 usaEpa . pollutants . includes ( pol as Pollutant )
6454 ) ;
6555 if ( ! pollutants . length ) {
66- return E . left (
67- providerError (
68- 'aqicn' ,
69- `Cannot normalize station ${ stationId } , no pollutants currently tracked: ${ JSON . stringify (
70- data
71- ) } `
72- )
56+ throw providerError (
57+ 'aqicn' ,
58+ `Cannot normalize station ${ stationId } , no pollutants currently tracked: ${ JSON . stringify (
59+ data
60+ ) } `
7361 ) ;
7462 }
7563 // We now need to get the country from AQICN response. The only place I found
7664 // is city.url...
7765 // Example: https://aqicn.org/city/france/lorraine/thionville-nord/garche/
7866 const AQICN_DOMAIN = 'aqicn.org/city/' ;
7967 if ( ! data . city . url || ! data . city . url . includes ( AQICN_DOMAIN ) ) {
80- return E . left (
81- providerError (
82- 'aqicn' ,
83- `Cannot extract country, got city.url: ${
84- data . city . url as string
85- } `
86- )
68+ throw providerError (
69+ 'aqicn' ,
70+ `Cannot extract country, got city.url: ${ data . city . url as string } `
8771 ) ;
8872 }
8973 const countryRaw = sanitizeCountry (
@@ -99,44 +83,43 @@ export function normalize(data: AqicnStaton): E.Either<Error, OpenAQResults> {
9983 "yyyy-MM-dd'T'HH:mm:ss.SSSxxx"
10084 ) ;
10185
102- return pipe (
103- getCountryCode ( countryRaw ) ,
104- E . fromOption ( ( ) =>
105- providerError ( 'aqicn' , `Cannot get code from country ${ countryRaw } ` )
106- ) ,
107- E . map (
108- ( country ) =>
109- pollutants . map ( ( [ pol , { v } ] ) => {
110- const pollutant = pol as Pollutant ;
86+ const countryCode = getCountryCode ( countryRaw ) ;
87+ if ( ! countryCode ) {
88+ throw providerError (
89+ 'aqicn' ,
90+ `Cannot get code from country ${ countryRaw } `
91+ ) ;
92+ }
11193
112- if ( ! data . city . geo ) {
113- throw new Error (
114- 'We returned TE.left if data.city.geo was not defined. qed.'
115- ) ;
116- }
94+ return pollutants . map ( ( [ pol , { v } ] ) => {
95+ const pollutant = pol as Pollutant ;
11796
118- return {
119- attribution : data . attributions ,
120- averagingPeriod : {
121- unit : 'day' ,
122- value : 1 ,
123- } ,
124- city : data . city . name ,
125- coordinates : {
126- latitude : + data . city . geo [ 0 ] ,
127- longitude : + data . city . geo [ 1 ] ,
128- } ,
129- country,
130- date : { local, utc } ,
131- location : stationId ,
132- isMobile : false ,
133- parameter : pollutant ,
134- sourceName : 'aqicn' ,
135- entity : 'other' ,
136- value : convert ( pollutant , 'usaEpa' , ugm3 , v ) ,
137- unit : getPollutantMeta ( pollutant ) . preferredUnit ,
138- } ;
139- } ) as OpenAQResults
140- )
141- ) ;
97+ if ( ! data . city . geo ) {
98+ throw new Error (
99+ 'We returned TE.left if data.city.geo was not defined. qed.'
100+ ) ;
101+ }
102+
103+ return {
104+ attribution : data . attributions ,
105+ averagingPeriod : {
106+ unit : 'day' ,
107+ value : 1 ,
108+ } ,
109+ city : data . city . name ,
110+ coordinates : {
111+ latitude : + data . city . geo [ 0 ] ,
112+ longitude : + data . city . geo [ 1 ] ,
113+ } ,
114+ country : countryCode ,
115+ date : { local, utc } ,
116+ location : stationId ,
117+ isMobile : false ,
118+ parameter : pollutant ,
119+ sourceName : 'aqicn' ,
120+ entity : 'other' ,
121+ value : convert ( pollutant , 'usaEpa' , ugm3 , v ) ,
122+ unit : getPollutantMeta ( pollutant ) . preferredUnit ,
123+ } ;
124+ } ) as OpenAQResults ;
142125}
0 commit comments