import { IBase } from "../../@types/utils" ; import { Base } from "./base" ; import { Batch } from "./batch" ; import { ContextInfo } from "../lib" ; import { Helper } from "./helper" ; import { Mapper , Mapper_Custom } from "../mapper" ; import { RequestType } from "./requestType" ; import { TargetInfo } from "./targetInfo" ; import { XHRRequest } from "./xhrRequest" ; /**
 * Request
 */ export const Request = { addMethods : ( base , data , graphType ? ) => { let obj = base ; let isCollection = data . results && data . results . length > 0 ; let methods = null ; let metadata = isCollection ? data . results [ 0 ] . __metadata : data . __metadata ; let objType = metadata && metadata . type ? metadata . type : obj . targetInfo . endpoint ; if ( ( methods = Mapper [ objType + ( isCollection ? ".Collection" : "" ) ] ) == null ) { objType = objType . split ( '/' ) ; objType = ( objType [ objType . length - 1 ] ) ; objType = objType . split ( '.' ) ; objType = ( objType [ objType . length - 1 ] ) . toLowerCase ( ) ; objType += isCollection ? "s" : "" ; if ( /^graph/ . test ( objType ) ) { } else if ( ( /^field/ . test ( objType ) || /fields?$/ . test ( objType ) ) && objType != "fieldlinks" && objType != "fields" ) { objType = "field" + ( isCollection ? "s" : "" ) ; } else if ( /item$/ . test ( objType ) ) { objType = "listitem" ; } else if ( /items$/ . test ( objType ) ) { objType = "items" ; } else if ( /corporatecatalogappmetadata/ . test ( objType ) ) { objType = "tenantapp" ; } else if ( /corporatecatalogappmetadatas/ . test ( objType ) ) { objType = "tenantapps" ; } methods = Mapper_Custom [ objType ] ; } if ( methods ) { for ( let methodName in methods ) { let methodInfo = methods [ methodName ] ? methods [ methodName ] : { } ; if ( methodName == "properties" ) { for ( let property of methodInfo ) { let propInfo = property . split ( "|" ) ; let propName = propInfo [ 0 ] ; let propType = propInfo . length > 1 ? propInfo [ 1 ] : null ; let subPropName = propInfo . length > 2 ? propInfo [ 2 ] : null ; let subPropType = propInfo . length > 3 ? propInfo [ 3 ] : null ; if ( obj [ propName ] == null || ( obj [ propName ] . __deferred && obj [ propName ] . __deferred . uri ) ) { if ( propInfo . length == 4 ) { subPropName = subPropName . replace ( /'/g , "\\'" ) ; obj [ propName ] = new Function ( "name" , "name = name ? '" + propName + subPropName + "'.replace(/\\[Name\\]/g, name.toString().replace(/\'/g, \"''\")) : null;" + "return this.getProperty(name ? name : '" + propName + "', name ? '" + subPropType + "' : '" + propType + "');" ) ; } else { obj [ propName ] = new Function ( "return this.getProperty('" + propName + "', '" + propType + "');" ) ; } } } continue ; } if ( typeof ( methodInfo . metadataType ) === "function" ) { methodInfo = JSON . parse ( JSON . stringify ( methodInfo ) ) ; methodInfo . metadataType = methods [ methodName ] . metadataType ( obj ) ; } obj [ methodName ] = new Function ( "return this.executeMethod('" + methodName + "', " + JSON . stringify ( methodInfo ) + ", arguments);" ) ; } } } , addProperties : ( base , data ) => { for ( var key in data ) { let value = data [ key ] ; if ( key == "__metadata" || key == "results" ) { continue ; } if ( value && value . __deferred && value . __deferred . uri ) { base [ "get_" + key ] = base [ "get_" + key ] ? base [ "get_" + key ] : new Function ( "return this.getCollection('" + key + "', arguments);" ) ; } else { switch ( key ) { case "ClientPeoplePickerResolveUser" : case "ClientPeoplePickerSearchUser" : base [ key ] = JSON . parse ( value ) ; break ; default : base [ key ] = value ; break ; } if ( base [ key ] && base [ key ] . results ) { if ( base [ key ] . results . length == 0 || typeof ( base [ key ] . results [ 0 ] ) === "object" ) { let objCollection = new Base ( base . targetInfo ) ; objCollection [ "results" ] = base [ key ] . results ; if ( objCollection [ "results" ] . length == 0 ) { objCollection [ "__metadata" ] = { type : key } ; } objCollection . targetInfo . endpoint = ( objCollection . targetInfo . endpoint . split ( "?" ) [ 0 ] + "/" + key ) . replace ( /\//g , "/" ) ; Request . addMethods ( objCollection , objCollection ) ; Helper . updateDataCollection ( base , objCollection [ "results" ] ) ; Helper . updateExpandedProperties ( base ) ; base [ key ] = objCollection ; } } } } } , execute : ( base , args ) => { let reject = null ; let resolve = null ; let waitFl = false ; for ( let i = 0 ; i < args . length ; i ++ ) { let arg = args [ i ] ; switch ( typeof ( arg ) ) { case "boolean" : waitFl = arg ; break ; case "function" : if ( resolve ) { reject = arg ; } else { resolve = arg ; } break ; } } base . base = base . base || base ; base . base . responses = base . base . responses || [ ] ; base . base . waitFlags = base . base . waitFlags || [ ] ; base . responseIndex = base . base . responses . length ; base . base . responses . push ( base ) ; if ( waitFl ) { Request . waitForRequestsToComplete ( base , ( ) => { Request . executeRequest ( base , true , ( response , errorFl ) => { if ( errorFl ) { base . base . waitFlags [ base . responseIndex ] = true ; reject ? reject ( response ) : null ; } else if ( resolve ) { let returnVal = resolve ( response ) ; let waitFunc = returnVal ? returnVal . done || returnVal . then : null ; if ( waitFunc && typeof ( waitFunc ) === "function" ) { waitFunc ( ( ) => { base . base . waitFlags [ base . responseIndex ] = true ; base . base = base as any ; base . base . responses = [ ] ; base . base . waitFlags = [ ] ; base . base = ( base . parent ? base . parent . base : null ) || base . base ; } ) ; return ; } base . base . waitFlags [ base . responseIndex ] = true ; base . base = base as any ; base . base . responses = [ ] ; base . base . waitFlags = [ ] ; base . base = ( base . parent ? base . parent . base : null ) || base . base ; } else { base . base . waitFlags [ base . responseIndex ] = true ; } } ) ; } , base . responseIndex ) ; } else { Request . executeRequest ( base , true , ( response , errorFl ) => { if ( errorFl ) { base . base . waitFlags [ base . responseIndex ] = true ; reject ? reject ( response ) : null ; } else { let returnVal = resolve ? resolve ( response ) : null ; if ( returnVal && typeof ( returnVal . done ) === "function" ) { returnVal . done ( ( ) => { base . base . waitFlags [ base . responseIndex ] = true ; } ) ; } else { base . base . waitFlags [ base . responseIndex ] = true ; } } } ) ; } if ( base . targetInfo . requestType == RequestType . OData ) { return base . parent ; } return base ; } , executeRequest : ( base , asyncFl , callback ? ) => { let isBatchRequest = base . base && base . base . batchRequests && base . base . batchRequests . length > 0 ; let targetInfo = isBatchRequest ? Batch . getTargetInfo ( base . base . batchRequests ) : new TargetInfo ( base . targetInfo ) ; if ( asyncFl ) { if ( base . xhr && ! isBatchRequest ) { callback ? callback ( base , false ) : null ; } else { base . xhr = new XHRRequest ( asyncFl , targetInfo , ( ) => { base . response = base . xhr . response ; base . status = base . xhr . status ; let errorFl = ! ( base . status >= 200 && base . status < 300 ) ; if ( base . requestType == RequestType . GetBuffer ) { callback ? callback ( base . response , errorFl ) : null ; } else { Request . updateDataObject ( base , isBatchRequest , callback as any ) ; if ( ! isBatchRequest ) { if ( base . xml ) { callback ? callback ( base , errorFl ) : null ; } else { Request . validateDataCollectionResults ( base ) . then ( ( ) => { callback ? callback ( base , errorFl ) : null ; } ) ; } } } } ) ; } } else if ( base . xhr ) { return base ; } else { base . xhr = new XHRRequest ( asyncFl , targetInfo ) ; base . response = base . xhr . response ; base . status = base . xhr . status ; if ( base . requestType == RequestType . GetBuffer ) { return base . response ; } Request . updateDataObject ( base , isBatchRequest , callback as any ) ; if ( base [ "d" ] && base [ "d" ] . __next ) { base [ "next" ] = new Function ( "return this.getNextSetOfResults();" ) ; } return base ; } } , parseXML : ( xml ) : any => { let objData = { } ; do { let idxStart = xml . indexOf ( "<d:" ) ; let idxEnd = xml . indexOf ( ">" , idxStart ) ; if ( idxEnd > idxStart && idxStart > - 1 ) { let propName = xml . substr ( idxStart + 3 , idxEnd - idxStart - 3 ) ; propName = propName . split ( ' ' ) [ 0 ] ; if ( propName == "element" ) { idxEnd = xml . indexOf ( "</d:" + propName , idxStart ) ; xml = xml . substr ( idxEnd + propName . length + 4 ) ; continue ; } if ( xml [ idxEnd - 1 ] == "/" ) { objData [ propName ] = null ; xml = xml . substr ( idxEnd + 1 ) ; } else { idxStart = idxEnd ; idxEnd = xml . indexOf ( "</d:" + propName , idxStart ) ; let value = xml . substr ( idxStart + 1 , idxEnd - idxStart - 1 ) ; if ( value . indexOf ( "<d:" ) == 0 && idxEnd > idxStart ) { objData [ propName ] = Request . parseXML ( value ) ; } else { objData [ propName ] = value ; } idxEnd = xml . indexOf ( ">" , idxStart + 1 ) ; xml = xml . substr ( idxEnd + 1 ) ; } } else { break ; } } while ( xml . length > 0 ) ; return objData ; } , updateDataObject : ( base , isBatchRequest = false , batchCallback ? ) => { if ( base . status >= 200 && base . status < 300 ) { if ( base . requestType == RequestType . GetBuffer ) { return ; } let batchIdx = 0 ; let batchRequestIdx = 0 ; let responses = isBatchRequest ? base . response . split ( "\n" ) : [ base . response ] ; for ( let i = 0 ; i < responses . length ; i ++ ) { let data = null ; let response = responses [ i ] ; response = response === "" && ! isBatchRequest ? "{}" : response ; let isXML = response . indexOf ( "<?xml" ) == 0 ; if ( isXML ) { while ( responses [ i + 1 ] && responses [ i + 1 ] . indexOf ( "--batchresponse" ) != 0 ) { response += responses [ ++ i ] ; } } try { data = isXML ? response : JSON . parse ( response ) ; } catch ( ex ) { continue ; } let obj = isBatchRequest ? Object . create ( base ) : base ; obj [ "existsFl" ] = typeof ( obj [ "Exists" ] ) === "boolean" ? obj [ "Exists" ] : data . error == null ; if ( isXML ) { let objData ; let idxStart = data . indexOf ( "<m:properties>" ) ; let idxEnd = data . indexOf ( "</m:properties" ) ; let idxDelStart = data . indexOf ( "<d:DeleteObject" ) ; let idxDelEnd = data . indexOf ( 'm:null="true" />' ) ; let properties = idxEnd > idxStart ? data . substr ( idxStart , idxEnd ) : null ; properties = properties == null && idxDelEnd > idxDelStart ? data . substr ( idxDelStart , idxDelEnd ) : properties ; if ( properties ) { objData = Request . parseXML ( properties ) ; Helper . updateMetadata ( obj , objData ) ; Request . addProperties ( obj , objData ) ; Request . addMethods ( obj , objData , objData [ "@odata.context" ] ) ; Helper . updateDataCollection ( obj , objData [ "results" ] ) ; Helper . updateExpandedProperties ( obj ) ; } else { obj = data ; } } else if ( data . d ) { obj [ "d" ] = data . d ; Helper . updateMetadata ( obj , data . d ) ; Request . addProperties ( obj , data . d ) ; Request . addMethods ( obj , data . d , data [ "@odata.context" ] ) ; Helper . updateDataCollection ( obj , data . d . results ) ; Helper . updateExpandedProperties ( obj ) ; } else { Request . addProperties ( obj , data ) ; } if ( isBatchRequest ) { let batchRequest = base . base . batchRequests [ batchIdx ] [ batchRequestIdx ++ ] ; if ( batchRequest == null ) { batchIdx ++ ; batchRequestIdx = 0 ; if ( base . base . batchRequests [ batchIdx ] ) { let batch = base . base . batchRequests [ batchIdx ] ; batchRequest = batch ? batch [ batchRequestIdx ++ ] : null ; } else { break ; } } if ( batchRequest ) { batchRequest . response = obj ; } } } if ( isBatchRequest ) { Batch . processCallbacks ( base . base . batchRequests ) ; batchCallback ? batchCallback ( base . base . batchRequests ) : null ; base . base . batchRequests = null ; } } } , validateDataCollectionResults : ( base ) : PromiseLike < void > => { return new Promise ( ( resolve , reject ) => { let request = ( xhr , resolve ) => { if ( xhr && xhr . status < 400 && typeof ( xhr . response ) === "string" && xhr . response . length > 0 ) { let data = JSON . parse ( xhr . response ) ; base . nextFl = data . d && data . d . __next ; if ( base . nextFl ) { if ( base . getAllItemsFl ) { let targetInfo = Object . create ( base . targetInfo ) ; targetInfo . endpoint = "" ; targetInfo . url = data . d . __next ; new XHRRequest ( true , new TargetInfo ( targetInfo ) , ( xhr ) => { let data = JSON . parse ( xhr . response ) ; if ( data . d ) { Helper . updateDataCollection ( base as any , data . d . results ) ; Helper . updateExpandedProperties ( base ) ; base [ "d" ] . results = base [ "d" ] . results . concat ( data . d . results ) ; request ( xhr , resolve ) ; } else { resolve ( ) ; } } ) ; } else { base [ "next" ] = new Function ( "return this.getNextSetOfResults();" ) ; resolve ( ) ; } } else { resolve ( ) ; } } else { resolve ( ) ; } } ; request ( base . xhr , resolve ) ; } ) ; } , waitForRequestsToComplete : ( base , callback , requestIdx ? ) => { if ( typeof ( callback ) === "function" ) { let intervalId = ContextInfo . window . setInterval ( ( ) => { let counter = 0 ; for ( let i = 0 ; i < base . base . responses . length ; i ++ ) { let response = base . base . responses [ i ] ; if ( requestIdx == counter ++ ) { break ; } if ( response . xhr == null || ! response . xhr . completedFl ) { return ; } if ( counter > 0 && base . base . waitFlags [ counter - 1 ] != true ) { return ; } } ContextInfo . window . clearInterval ( intervalId ) ; callback ( ) ; } , 10 ) ; } } } ;