import * as fs from 'fs' ; import * as IO from 'fp-ts/IO' ; import { pipe } from 'fp-ts/function' ; class Employee { constructor ( readonly lastName , readonly firstName , readonly dateOfBirth , readonly email ) { } isBirthday ( today ) { return ( this . dateOfBirth . getMonth ( ) === today . getMonth ( ) && this . dateOfBirth . getDate ( ) === today . getDate ( ) ) ; } } class Email { constructor ( readonly from , readonly subject , readonly body , readonly recipient ) { } } interface MonadEmail { readonly sendMessage : ( email : Email ) => IO . IO < void > ; } interface MonadFileSystem { readonly read : ( fileName : string ) => IO . IO < string > ; } interface MonadApp extends MonadEmail , MonadFileSystem { } const toEmail = ( employee ) : Email => { const recipient = employee . email ; const body = `Happy Birthday, dear ${ employee . firstName }!` ; const subject = 'Happy Birthday!' ; return new Email ( 'sender@here.com' , subject , body , recipient ) ; } ; const getGreetings = ( today , employees ) : ReadonlyArray < Email > => { return employees . filter ( ( e ) => e . isBirthday ( today ) ) . map ( toEmail ) ; } ; const parse = ( input ) : ReadonlyArray < Employee > => { const lines = input . split ( '\n' ) . slice ( 1 ) ; return lines . map ( ( line ) => { const employeeData = line . split ( ', ' ) ; return new Employee ( employeeData [ 0 ] , employeeData [ 1 ] , new Date ( employeeData [ 2 ] ) , employeeData [ 3 ] ) ; } ) ; } ; const sendGreetings = ( M ) => ( fileName , today ) : IO . IO < void > => { return pipe ( M . read ( fileName ) , IO . map ( ( input ) => getGreetings ( today , parse ( input ) ) ) , IO . chain ( IO . traverseArray ( M . sendMessage ) ) , IO . map ( ( ) => undefined ) ) ; } ; const getMonadApp = ( smtpHost , smtpPort ) : MonadApp => { return { sendMessage : ( email ) => ( ) => console . log ( smtpHost , smtpPort , email ) , read : ( fileName ) => ( ) => fs . readFileSync ( fileName , { encoding : 'utf8' } ) } ; } ; const program = sendGreetings ( getMonadApp ( 'localhost' , 80 ) ) ; program ( 'src/onion-architecture/employee_data.txt' , new Date ( 2008 , 9 , 8 ) ) ( ) ;