import { VERSION_3_0 , VERSION_2_0 , VERSION_4_0 , $COUNT , $INLINECOUNT , } from './constants' ; import { ODataMetadataType } from './types' ; export const COLLECTION = /Collection\(([\w\.]+)\)/ ; export const PROPERTY = /([\w\d\-_]+)\(([\'\w\d\-_=]+)\)/ ; export const EXPAND = /([\w\d\-_]+)\(([\w\d\,\(\)]+)\)/ ; export type ODataContext = { serviceRootUrl ? : string ; metadataUrl ? : string ; entitySet ? : string ; key ? : string ; expand ? : string ; type ? : string ; property ? : string ; entity ? : boolean ; } ; export interface ODataVersionHelper { VALUE : string ; ODATA_ANNOTATION_PREFIX : string ; ODATA_FUNCTION_PREFIX : string ; ODATA_ID : string ; ODATA_COUNT : string ; ODATA_ETAG : string ; ODATA_CONTEXT : string ; ODATA_MEDIA_ETAG : string ; entity ( value ) : any ; entities ( value ) : any ; property ( value ) : any ; annotations ( value ) : { [ name ] : any ; } ; attributes ( value , metadata ) : any ; id ( value , id ? ) : string | undefined ; etag ( value , etag ? ) : string | undefined ; type ( value , type ? ) : string | undefined ; count ( value ) : number | undefined ; context ( value ) : ODataContext ; functions ( value ) : { [ name ] : any ; } ; properties ( value ) : { [ name ] : any ; } ; mediaEtag ( value ) : string | undefined ; metadataEtag ( value ) : string | undefined ; nextLink ( value ) : string | undefined ; readLink ( value ) : string | undefined ; mediaReadLink ( value ) : string | undefined ; editLink ( value ) : string | undefined ; mediaEditLink ( value ) : string | undefined ; mediaContentType ( value ) : string | undefined ; deltaLink ( value ) : string | undefined ; countParam ( ) : { [ name ] : string ; } ; } const ODataVersionBaseHelper = < any > { entity ( data ) { return data ; } , entities ( data ) { return data [ this . VALUE ] ; } , property ( data ) { return this . VALUE in data ? data [ this . VALUE ] : data ; } , functions ( value ) { return Object . keys ( value ) . filter ( ( k ) => k . startsWith ( this . ODATA_FUNCTION_PREFIX ) ) . reduce ( ( acc , key ) => Object . assign ( acc , { [ key . substr ( 1 ) ] : value [ key ] } ) , { } ) ; } , properties ( value ) { return Object . keys ( value ) . filter ( ( k ) => k . indexOf ( this . ODATA_ANNOTATION_PREFIX ) > 0 ) . reduce ( ( acc , key ) => { let name = key . substr ( 0 , key . indexOf ( this . ODATA_ANNOTATION_PREFIX ) ) ; if ( ! ( name in acc ) ) { acc [ name ] = { } ; } Object . assign ( acc [ name ] , { [ key . substr ( key . indexOf ( this . ODATA_ANNOTATION_PREFIX ) ) ] : value [ key ] , } ) ; return acc ; } , { } ) ; } , id ( value , id ? ) { if ( id !== undefined ) value [ this . ODATA_ID ] = id ; return this . ODATA_ID in value ? ( value [ this . ODATA_ID ] as string ) : undefined ; } , etag ( value , etag ? ) { if ( etag !== undefined ) value [ this . ODATA_ETAG ] = etag ; return this . ODATA_ETAG in value ? ( value [ this . ODATA_ETAG ] as string ) : undefined ; } , type ( value , type ? ) { if ( type !== undefined ) value [ this . ODATA_TYPE ] = `#${ type }` ; if ( ! ( this . ODATA_TYPE in value ) ) return undefined ; const t = value [ this . ODATA_TYPE ] . substr ( 1 ) ; const matches = COLLECTION . exec ( t ) ; if ( matches ) return matches [ 1 ] . indexOf ( '.' ) === - 1 ? `Edm.${ matches [ 1 ] }` : matches [ 1 ] ; return t ; } , mediaEtag ( value ) { return this . ODATA_MEDIA_ETAG in value ? decodeURIComponent ( value [ this . ODATA_MEDIA_ETAG ] as string ) : undefined ; } , metadataEtag ( value ) { return this . ODATA_METADATA_ETAG in value ? decodeURIComponent ( value [ this . ODATA_METADATA_ETAG ] as string ) : undefined ; } , count ( value ) { return this . ODATA_COUNT in value ? Number ( value [ this . ODATA_COUNT ] ) : undefined ; } , annotations ( value ) { return Object . keys ( value ) . filter ( ( key ) => key . indexOf ( this . ODATA_ANNOTATION_PREFIX ) !== - 1 || key . startsWith ( this . ODATA_FUNCTION_PREFIX ) ) . reduce ( ( acc , key ) => Object . assign ( acc , { [ key ] : value [ key ] } ) , { } ) ; } , attributes ( value , metadata ) { return Object . entries ( value ) . filter ( ( [ k ] ) => metadata === 'none' || ( metadata === 'minimal' && ( k . indexOf ( this . ODATA_ANNOTATION_PREFIX ) === - 1 || k . startsWith ( this . ODATA_ANNOTATION_PREFIX ) ) && ! k . startsWith ( this . ODATA_FUNCTION_PREFIX ) ) || ( metadata === 'full' && k . indexOf ( this . ODATA_ANNOTATION_PREFIX ) === - 1 && ! k . startsWith ( this . ODATA_FUNCTION_PREFIX ) ) ) . reduce ( ( acc , e ) => ( { ... acc , [ e [ 0 ] ] : e [ 1 ] } ) , { } ) ; } , nextLink ( value ) { return this . ODATA_NEXTLINK in value ? decodeURIComponent ( value [ this . ODATA_NEXTLINK ] as string ) : undefined ; } , readLink ( value ) { return this . ODATA_READLINK in value ? decodeURIComponent ( value [ this . ODATA_READLINK ] as string ) : undefined ; } , mediaReadLink ( value ) { return this . ODATA_MEDIA_READLINK in value ? decodeURIComponent ( value [ this . ODATA_MEDIA_READLINK ] as string ) : undefined ; } , editLink ( value ) { return this . ODATA_EDITLINK in value ? decodeURIComponent ( value [ this . ODATA_EDITLINK ] as string ) : undefined ; } , mediaEditLink ( value ) { return this . ODATA_MEDIA_EDITLINK in value ? decodeURIComponent ( value [ this . ODATA_MEDIA_EDITLINK ] as string ) : undefined ; } , deltaLink ( value ) { return this . ODATA_DELTALINK in value ? decodeURIComponent ( value [ this . ODATA_DELTALINK ] as string ) : undefined ; } , mediaContentType ( value ) { return this . ODATA_MEDIA_CONTENTTYPE in value ? decodeURIComponent ( value [ this . ODATA_MEDIA_CONTENTTYPE ] as string ) : undefined ; } , } ; export const ODataHelper = { [ VERSION_4_0 ] : < ODataVersionHelper > Object . assign ( { } , ODataVersionBaseHelper , { VALUE : 'value' , ODATA_ANNOTATION_PREFIX : '@odata' , ODATA_FUNCTION_PREFIX : '#' , ODATA_ID : '@odata.id' , ODATA_COUNT : '@odata.count' , ODATA_CONTEXT : '@odata.context' , ODATA_ETAG : '@odata.etag' , ODATA_METADATA_ETAG : '@odata.metadataEtag' , ODATA_TYPE : '@odata.type' , ODATA_NEXTLINK : '@odata.nextLink' , ODATA_DELTALINK : '@odata.deltaLink' , ODATA_READLINK : '@odata.readLink' , ODATA_EDITLINK : '@odata.editLink' , ODATA_ASSOCIATIONLINK : '@odata.associationLink' , ODATA_NAVIGATIONLINK : '@odata.navigationLink' , ODATA_MEDIA_ETAG : '@odata.mediaEtag' , ODATA_MEDIA_CONTENTTYPE : '@odata.mediaContentType' , ODATA_MEDIA_READLINK : '@odata.mediaReadLink' , ODATA_MEDIA_EDITLINK : '@odata.mediaEditLink' , context ( value ) { let ctx = { } ; if ( this . ODATA_CONTEXT in value ) { const str = value [ this . ODATA_CONTEXT ] as string ; let index = str . indexOf ( '$metadata' ) ; ctx . serviceRootUrl = str . substr ( 0 , index ) ; index = str . indexOf ( '#' ) ; ctx . metadataUrl = str . substr ( 0 , index ) ; const parts = str . substr ( index + 1 ) . split ( '/' ) ; const col = COLLECTION . exec ( parts [ 0 ] ) ; if ( col ) { ctx . type = col [ 1 ] ; } else if ( parts [ 0 ] . indexOf ( '.' ) !== - 1 ) { ctx . type = parts [ 0 ] ; } else { const property = parts [ 0 ] . match ( PROPERTY ) ; const expand = parts [ 0 ] . match ( EXPAND ) ; ctx . entity = parts [ 1 ] === '$entity' ; if ( property ) { ctx . entitySet = property [ 1 ] ; ctx . key = property [ 2 ] ; ctx . property = parts [ 1 ] ; } else if ( expand ) { ctx . entitySet = expand [ 1 ] ; ctx . expand = expand [ 2 ] ; } else { ctx . entitySet = parts [ 0 ] ; } } } return ctx ; } , countParam ( ) { return { [ $COUNT ] : 'true' } ; } , } ) , [ VERSION_3_0 ] : < ODataVersionHelper > Object . assign ( { } , ODataVersionBaseHelper , { ODATA_ANNOTATION_PREFIX : 'odata.' , ODATA_FUNCTION_PREFIX : '' , ODATA_ID : 'odata.id' , ODATA_ETAG : 'odata.etag' , ODATA_CONTEXT : 'odata.metadata' , ODATA_NEXTLINK : 'odata.nextLink' , ODATA_TYPE : 'odata.type' , ODATA_COUNT : 'odata.count' , VALUE : 'value' , context ( value ) { let ctx = { } ; if ( this . ODATA_CONTEXT in value ) { const str = value [ this . ODATA_CONTEXT ] as string ; let index = str . indexOf ( '$metadata' ) ; ctx . serviceRootUrl = str . substr ( 0 , index ) ; index = str . indexOf ( '#' ) ; ctx . metadataUrl = str . substr ( 0 , index ) ; const parts = str . substr ( index + 1 ) . split ( '/' ) ; ctx . entitySet = parts [ 0 ] ; } return ctx ; } , countParam ( ) { return { [ $INLINECOUNT ] : 'allpages' } ; } , } ) , [ VERSION_2_0 ] : < ODataVersionHelper > Object . assign ( { } , ODataVersionBaseHelper , { ODATA_ID : 'id' , ODATA_ETAG : 'etag' , ODATA_ANNOTATION : '__metadata' , ODATA_NEXTLINK : '__next' , ODATA_COUNT : '__count' , ODATA_DEFERRED : '__deferred' , ODATA_TYPE : 'type' , VALUE : 'results' , annotations ( value ) { if ( this . ODATA_ANNOTATION in value ) return value [ this . ODATA_ANNOTATION ] ; return value ; } , attributes ( value , metadata ) { return value ; } , countParam ( ) { return { [ $INLINECOUNT ] : 'allpages' } ; } , } ) , } ;