import { Observable , throwError } from 'rxjs' ; import { map } from 'rxjs/operators' ; import { ODataApi } from '../../api' ; import { ODataModel } from '../../models' ; import { ODataStructuredType } from '../../schema/structured-type' ; import { PathSegmentNames , QueryOptionNames } from '../../types' ; import { ODataPathSegments } from '../path' ; import { ODataQueryOptions } from '../query' ; import { ODataResource } from '../resource' ; import { ODataEntity } from '../responses/types' ; import { ODataActionResource } from './action' ; import { ODataFunctionResource } from './function' ; import { ODataMediaResource } from './media' ; import { ODataNavigationPropertyResource } from './navigation-property' ; import { ODataOptions } from './options' ; import { ODataPropertyResource } from './property' ; export class ODataEntityResource < T > extends ODataResource < T > { static factory < E > ( api , { schema , segments , query , } ) { query ?. keep ( QueryOptionNames . expand , QueryOptionNames . select , QueryOptionNames . format ) ; return new ODataEntityResource < E > ( api , { segments , query , schema } ) ; } key ( value ) { const entity = this . clone < ODataEntityResource < T > > ( ) ; var key = this . resolveKey ( value ) ; if ( key !== undefined ) entity . segment ( ( s ) => s . entitySet ( ) . key ( key ) ) ; return entity ; } keys ( values ) { const entity = this . clone < ODataEntityResource < T > > ( ) ; const types = this . pathSegments . types ( { key : true } ) ; const keys = values . map ( ( value , index ) => ODataResource . resolveKey ( value , this . api . findStructuredTypeForType < T > ( types [ index ] ) ) ) ; entity . segment ( ( s ) => s . keys ( keys ) ) ; return entity ; } media ( ) { return ODataMediaResource . factory < T > ( this . api , { segments : this . cloneSegments ( ) , query : this . cloneQuery < T > ( ) , } ) ; } navigationProperty < N > ( path ) { return ODataNavigationPropertyResource . fromResource < N > ( this , path ) ; } property < P > ( path ) { return ODataPropertyResource . fromResource < P > ( this , path ) ; } action < P , R > ( path ) { return ODataActionResource . fromResource < P , R > ( this , path ) ; } function < P , R > ( path ) { return ODataFunctionResource . fromResource < P , R > ( this , path ) ; } cast < C > ( type ) { const baseSchema = this . schema as ODataStructuredType < T > ; const castSchema = this . api . findStructuredTypeForType < C > ( type ) ; if ( castSchema !== undefined && baseSchema !== undefined && ! castSchema . isSubtypeOf ( baseSchema ) ) throw new Error ( `Cannot cast to ${ type }` ) ; const segments = this . cloneSegments ( ) ; segments . add ( PathSegmentNames . type , type ) . type ( type ) ; return new ODataEntityResource < C > ( this . api , { segments , schema : castSchema , query : this . cloneQuery < C > ( ) , } ) ; } protected override post ( attrs , options = { } ) { return super . post ( attrs , { responseType : 'entity' , ... options } ) ; } protected override put ( attrs , options = { } ) { return super . put ( attrs , { responseType : 'entity' , ... options } ) ; } protected override patch ( attrs , options = { } ) { return super . patch ( attrs , { responseType : 'entity' , ... options } ) ; } protected override delete ( options = { } ) { return super . delete ( { responseType : 'entity' , ... options } ) ; } protected override get ( options = { } ) { return super . get ( { responseType : 'entity' , ... options } ) ; } create ( attrs , options ? ) { return this . post ( attrs , options ) ; } update ( attrs , options ? ) { return this . put ( attrs , options ) ; } modify ( attrs , options ? ) { return this . patch ( attrs , options ) ; } destroy ( options ? ) { return this . delete ( options ) ; } fetch ( options ? ) { if ( ! this . hasKey ( ) ) return throwError ( 'Entity resource without key' ) ; return this . get ( options ) ; } fetchEntity ( options ? ) { return this . fetch ( options ) . pipe ( map ( ( { entity } ) => entity ) ) ; } fetchModel < M extends ODataModel < T > > ( options ? ) { return this . fetch ( options ) . pipe ( map ( ( { entity , annots } ) => entity ? this . asModel < M > ( entity , { annots , reset : true } ) : null ) ) ; } }