@@ -7,9 +7,12 @@ import { HttpLink } from '@apollo/client/link/http';
77import { isValidEin } from './ein' ;
88import { logger } from './logger' ;
99import { AccessTokenSet , getToken , oidcOptions } from './oidc' ;
10- import { getChangemakers , getSources , postSource } from './pdc-api' ;
10+ import {
11+ getChangemakers , getSources , postChangemakerFieldValue , postChangemakerFieldValueBatch ,
12+ postSource ,
13+ } from './pdc-api' ;
1114import type { CommandModule } from 'yargs' ;
12- import type { Source } from '@pdc/sdk' ;
15+ import type { Changemaker , ChangemakerBundle , Source } from '@pdc/sdk' ;
1316
1417const CN_SHORT_CODE = 'charitynav' ;
1518
@@ -24,8 +27,18 @@ interface NonprofitPublic {
2427 encompassScore ?: number ,
2528 encompassStarRating ?: number
2629 encompassPublicationDate ?: string ,
30+ size ?: string ,
31+ cause ?: string ,
2732}
2833
34+ /** Map from Charity Navigator NonprofitPublic attribute name to PDC base field name */
35+ const baseFieldMap = {
36+ name : 'organization_name' ,
37+ website : 'organization_website' ,
38+ phone : 'organization_phone' ,
39+ mission : 'organization_mission_statement' ,
40+ } ;
41+
2942interface PageInfo {
3043 totalPages : number ;
3144 totalItems : number ;
@@ -72,6 +85,8 @@ NonprofitsPublicVariables
7285 encompassScore
7386 encompassStarRating
7487 encompassPublicationDate
88+ size
89+ cause
7590 }
7691 pageInfo {
7792 totalPages
@@ -205,6 +220,22 @@ const lookupCommand: CommandModule<unknown, LookupCommandArgs> = {
205220 } ,
206221} ;
207222
223+ const getChangemakerByEin = ( ein : string , changemakers : ChangemakerBundle ) : Changemaker | null => {
224+ const matches = changemakers . entries . filter ( ( c ) => c . taxId === ein ) ;
225+ if ( matches . length > 1 ) {
226+ logger . warn ( `Found multiple changemakers with EIN ${ ein } , not returning any.` ) ;
227+ return null ;
228+ }
229+ if ( matches . length < 1 ) {
230+ logger . info ( `Found no changemaker with EIN ${ ein } ` ) ;
231+ return null ;
232+ }
233+ if ( matches . length === 1 && matches [ 0 ] !== undefined ) {
234+ return matches [ 0 ] ;
235+ }
236+ throw new Error ( 'How could this have happened?' ) ;
237+ } ;
238+
208239const getOrCreateSource = async ( baseUrl : string , token : AccessTokenSet ) : Promise < Source > => {
209240 const sources = await getSources ( baseUrl , token ) ;
210241 const filteredSources = sources . entries . filter ( ( s ) => s . dataProviderShortCode === CN_SHORT_CODE ) ;
@@ -262,15 +293,38 @@ const updateAllCommand: CommandModule<unknown, UpdateAllCommandArgs> = {
262293 args . oidcClientId ,
263294 args . oidcClientSecret ,
264295 ) ;
296+ if ( ! charityNavResponse . data ) {
297+ logger . warn ( 'No data found' ) ;
298+ return ;
299+ }
265300 // First, find the existing source. As of this writing, it cannot be created by non-admins.
266301 const source = await getOrCreateSource ( args . pdcApiBaseUrl , token ) ;
267302 logger . info ( source , 'The PDC Source for Charity Navigator was found' ) ;
268303 // Second, post the fields to PDC
269- if ( charityNavResponse . data ) {
270- const { edges } = charityNavResponse . data . nonprofitsPublic ;
271- const nonprofits = edges . filter ( ( e ) : e is NonprofitPublic => isNonprofitPublic ( e ) ) ;
272- logger . info ( nonprofits , 'Found these nonprofits' ) ;
273- }
304+ const { edges } = charityNavResponse . data . nonprofitsPublic ;
305+ const nonprofits = edges . filter ( ( e ) : e is NonprofitPublic => isNonprofitPublic ( e ) ) ;
306+ logger . info ( nonprofits , 'Found these nonprofits' ) ;
307+ // Third, register a batch of changemaker fields to be posted
308+ const fieldBatch = await postChangemakerFieldValueBatch ( args . pdcApiBaseUrl , token , { sourceId : source . id , notes : `data-scripts charityNavigator.ts execution ${ Date . now ( ) } ` } ) ;
309+ // Last, for each nonprofit, for each field, post the field
310+ edges . map ( async ( e ) => {
311+ const changemaker = getChangemakerByEin ( e . ein , changemakers ) ;
312+ if ( changemaker !== null ) {
313+ Object . entries ( baseFieldMap ) . map ( async ( [ cnAttributeName , baseFieldShortCode ] ) => {
314+ const cnAttribute = e [ cnAttributeName as keyof NonprofitPublic ] ;
315+ if ( cnAttribute !== undefined ) {
316+ const fieldValue = await postChangemakerFieldValue ( args . pdcApiBaseUrl , token , {
317+ changemakerId : changemaker . id ,
318+ batchId : fieldBatch . id ,
319+ baseFieldShortCode,
320+ value : cnAttribute . toString ( ) ,
321+ goodAsOf : e . updatedAt ,
322+ } ) ;
323+ logger . info ( `Added changemaker field value: ${ JSON . stringify ( fieldValue ) } ` ) ;
324+ }
325+ } ) ;
326+ }
327+ } ) ;
274328 } ,
275329} ;
276330
0 commit comments