import { action , computed , extendObservable , IComputedValue , isObservableArray } from 'mobx' ; import { IModel } from 'mobx-collection-store' ; import IDictionary from './interfaces/IDictionary' ; import IHeaders from './interfaces/IHeaders' ; import IRawResponse from './interfaces/IRawResponse' ; import IRequestOptions from './interfaces/IRequestOptions' ; import IResponseHeaders from './interfaces/IResponseHeaders' ; import * as JsonApi from './interfaces/JsonApi' ; import { NetworkStore } from './NetworkStore' ; import { Record } from './Record' ; import { Store } from './Store' ; import { flattenRecord , keys } from './utils' ; import { fetchLink , read } from './NetworkUtils' ; export class Response { type { ( IModel | Array < IModel > ) } memberOf public data ? : IModel | Array < IModel > ; type { object } memberOf public meta ? : object ; type { object } memberOf public links ? : IDictionary < JsonApi . ILink > ; type { JsonApi . IJsonApiObject } memberOf public jsonapi ? : JsonApi . IJsonApiObject ; type { IResponseHeaders } memberOf public headers ? : IResponseHeaders ; type { IHeaders } memberOf public requestHeaders ? : IHeaders ; type { ( Array < JsonApi . IError > | Error ) } memberOf public error ? : Array < JsonApi . IError > | Error ; type { Promise < Response > } memberOf public first : Promise < Response > ; type { Promise < Response > } memberOf public prev : Promise < Response > ; type { Promise < Response > } memberOf public next : Promise < Response > ; type { Promise < Response > } memberOf public last : Promise < Response > ; type { number } memberOf public status : number ; private type { Store } memberOf private __store : Store ; private type { IRequestOptions } memberOf private __options : IRequestOptions ; private type { IRawResponse } memberOf private __response : IRawResponse ; private type { IDictionary < Promise < Response > > } memberOf private __cache : IDictionary < Promise < Response > > = { } ; constructor ( response , store ? , options ? , overrideData ? ) { this . __store = store ; this . __options = options ; this . __response = response ; this . status = response . status ; if ( store ) { this . data = overrideData ? store . add ( overrideData ) : store . sync ( response . data ) ; } else if ( response . data ) { const resp = response . data ; if ( resp . data instanceof Array ) { throw new Error ( 'A save/remove operation should not return an array of results' ) ; } this . data = overrideData || new Record ( flattenRecord ( resp . data ) ) ; } this . meta = ( response . data && response . data . meta ) || { } ; this . links = ( response . data && response . data . links ) || { } ; this . jsonapi = ( response . data && response . data . jsonapi ) || { } ; this . headers = response . headers ; this . requestHeaders = response . requestHeaders ; this . error = ( response . data && response . data . errors ) || response . error ; const linkGetter = { } ; Object . keys ( this . links ) . forEach ( ( link ) => { linkGetter [ link ] = computed ( ( ) => this . __fetchLink ( link ) ) ; } ) ; extendObservable ( this , linkGetter ) ; Object . freeze ( this ) ; if ( this . error ) { throw this ; } } param { IModel } data returns { Response } memberOf @ action public replaceData ( data ) { const record = this . data as Record ; if ( record === data ) { return this ; } const oldId = data . getRecordId ( ) ; const newId = record . getRecordId ( ) ; const type = record . getRecordType ( ) ; if ( this . __store ) { this . __store . remove ( type , newId ) ; } data . update ( record . toJS ( ) ) ; data [ '__internal' ] . id = newId ; this . __updateStoreReferences ( type , oldId , newId ) ; return new Response ( this . __response , this . __store , this . __options , data ) ; } private param { any } type param { any } oldId param { any } newId memberof private __updateStoreReferences ( type , oldId , newId ) { if ( this . __store ) { const modelHash = this . __store [ '__modelHash' ] [ type ] ; const oldModel = modelHash [ oldId ] ; modelHash [ newId ] = oldModel ; delete modelHash [ oldId ] ; this . __updateReferences ( type , oldId , newId ) ; } } private param { any } oldId param { any } newId memberof private __updateReferences ( type , oldId , newId ) { this . __store [ '__data' ] . map ( ( model ) => { const keyList = keys ( model [ '__data' ] ) ; keyList . map ( ( key ) => { const keyId = `${ key }Id` ; const refs = model . __refs || model . static . refs ; const refsType = refs && refs [ key ] ; if ( key in model && keyId in model && refsType === type ) { if ( isObservableArray ( model [ keyId ] ) ) { const index = model [ keyId ] . indexOf ( oldId ) ; if ( index > - 1 ) { model [ keyId ] [ index ] = newId ; } } else if ( model [ keyId ] === oldId ) { model [ keyId ] = newId ; } } } ) ; } ) ; } private param { any } name returns memberOf private __fetchLink ( name ) { if ( ! this . __cache [ name ] ) { const link = name in this . links ? this . links [ name ] : null ; this . __cache [ name ] = fetchLink ( link , this . __store , this . requestHeaders , this . __options ) ; } return this . __cache [ name ] ; } }