import { camelCase , pascalCase } from 'change-case' ; import { Cookie , CookieManager } from './types' ; interface IndexableCookie extends Cookie { [ key ] : string | boolean | undefined ; } interface Serializer { ( cookie ) : string ; } interface Deserializer { ( cookieString ) : Cookie ; } export const serialize = ( cookie ) => { const ic = < IndexableCookie > cookie ; const tokens = [ `${ ic . name }=${ ic . value }` ] ; const keyVals = [ 'expires' , 'domain' , 'path' ] ; keyVals . filter ( ( key ) => ic [ key ] ) . forEach ( ( key ) => { tokens . push ( `${ pascalCase ( key ) }=${ ic [ key ] }` ) ; } ) ; const bools = [ 'secure' , 'httpOnly' ] ; bools . filter ( ( key ) => ic [ key ] ) . forEach ( ( key ) => { tokens . push ( pascalCase ( key ) ) ; } ) ; return tokens . join ( '; ' ) ; } ; export const deserialize = ( cookieString ) => { const [ nameVal , ... others ] = cookieString . split ( ';' ) . map ( ( token ) => token . trim ( ) ) ; const [ name , value ] = nameVal . split ( '=' ) ; const cookie = { name , value , } ; others . map ( ( keyVal ) => keyVal . split ( '=' ) ) . forEach ( ( [ key , val ] ) => { const prop = camelCase ( key ) ; switch ( prop ) { case 'expires' : case 'domain' : case 'path' : cookie [ prop ] = val ; break ; case 'secure' : case 'httpOnly' : cookie [ prop ] = true ; break ; } } ) ; return cookie ; } ; interface ToughCookie { toString : ( ) => string ; } export interface ToughCookieJar { getCookieString : ( url : string ) => Promise < string > ; getCookies : ( url : string ) => Promise < ToughCookie [ ] > ; setCookie : ( cookie : string , url : string ) => Promise < any > ; removeAllCookies : ( ) => Promise < void > ; } export const wrapToughCookie = ( jar ) : CookieManager => ( { getCookieString : ( url ) => jar . getCookieString ( url ) , getCookies : async ( url ) => { const cookies = await jar . getCookies ( url ) ; return cookies . map ( ( cookie ) => deserialize ( cookie . toString ( ) ) ) ; } , setCookie : async ( cookie , url ) => { await jar . setCookie ( serialize ( cookie ) , url ) ; } , setCookieString : async ( cookieString , url ) => { await jar . setCookie ( cookieString , url ) ; } , clearAll : ( ) => jar . removeAllCookies ( ) , } ) ; interface RNCookies { [ key ] : Cookie ; } export interface RNCookieManager { set ( url , cookie , useWebKit ? ) : Promise < boolean > ; setFromResponse ( url , cookie ) : Promise < boolean > ; get ( url , useWebKit ? ) : Promise < RNCookies > ; clearAll ( useWebKit ? ) : Promise < boolean > ; } export const wrapReactNativeCookieManager = ( rnc ) : CookieManager => ( { clearAll : ( ) => rnc . clearAll ( ) . then ( ) , getCookieString : async ( url ) => { const cookies = await rnc . get ( url ) ; return Object . values ( cookies ) . map ( ( c ) => `${ c . name }=${ c . value }` ) . join ( '; ' ) ; } , getCookies : async ( url ) => { const cookies = await rnc . get ( url ) ; return Object . values ( cookies ) ; } , setCookie : async ( cookie , url ) => { await rnc . setFromResponse ( url , serialize ( cookie ) ) ; } , setCookieString : async ( cookieString , url ) => { await rnc . setFromResponse ( url , cookieString ) ; } , } ) ;