import md5 from 'blueimp-md5' ; const API_PUBLIC = '298bab46381a6daaaee19aa5c8cafea5' ; const API_PRIVATE = 'b0223681fced28de0fe97e6b9cd091dd36a5b71d' ; const BASE_URL = 'https://gateway.marvel.com' ; export interface CharacterCategory { available : number ; collectionURI : string ; items : [ { resourceURI : string ; name : string ; type ? : string ; } ] ; returned : number ; } export interface Character { id : number ; name : string ; description : string ; modified : string ; thumbnail : { path : string ; extension : string ; } ; resourceURI : string ; comics : CharacterCategory ; series : CharacterCategory ; stories : CharacterCategory ; events : CharacterCategory ; urls : [ { type : string ; url : string ; } ] ; [ index ] : CharacterCategory | string | number | Record < string , unknown > | Record < string , unknown > [ ] ; } export type Characters = Character [ ] ; export function getQueryParams ( offset ? ) { const ts = Date . now ( ) ; const params = { ts , apikey : API_PUBLIC , hash : md5 ( ts + API_PRIVATE + API_PUBLIC ) , limit : offset !== undefined ? 50 : undefined , offset } ; return ( Object . keys ( params ) as ( keyof typeof params ) [ ] ) . filter ( key => params [ key ] !== undefined ) . map ( key => `${ encodeURIComponent ( key ) }=${ encodeURIComponent ( params [ key ] ! ) }` ) . join ( '&' ) ; } export async function fetchCharacters ( offset ) { const response = await fetch ( `${ BASE_URL }/v1/public/characters?${ getQueryParams ( offset ) }` ) ; if ( ! response . ok ) throw new Error ( response . statusText ) ; const data = await response . json ( ) ; return data . data . results as Characters ; } export async function fetchCharacter ( id ) { const response = await fetch ( `${ BASE_URL }/v1/public/characters/${ id }?${ getQueryParams ( ) }` ) ; if ( ! response . ok ) throw new Error ( response . statusText ) ; const data = await response . json ( ) ; return data . data . results [ 0 ] as Character ; }