import { join } from 'aurelia-path' ; import { PLATFORM } from 'aurelia-pal' ; import deepExtend from './deep-extend' ; import { WindowInfo } from './window-info' ; export class Configuration { private environment : string = 'default' ; private environments : string [ ] | null = null ; private directory : string = 'config' ; private config_file : string = 'config.json' ; private cascade_mode : boolean = true ; private base_path_mode : boolean = false ; private window : WindowInfo ; private _config_object : { } | any = { } ; private _config_merge_object : { } | any = { } ; constructor ( ) { this . window = new WindowInfo ( ) ; this . window . hostName = PLATFORM . location . hostname ; this . window . port = PLATFORM . location . port ; if ( PLATFORM . location . pathname && PLATFORM . location . pathname . length > 1 ) { this . window . pathName = PLATFORM . location . pathname ; } } param path setDirectory ( path ) { this . directory = path ; } param name setConfig ( name ) { this . config_file = name ; } param environment setEnvironment ( environment ) { this . environment = environment ; } param environments setEnvironments ( environments = null ) { if ( environments !== null ) { this . environments = environments ; this . check ( ) ; } } param bool setCascadeMode ( bool = true ) { this . cascade_mode = bool ; } param bool setWindow ( window ) { this . window = window ; } param bool setBasePathMode ( bool = true ) { this . base_path_mode = bool ; } returns { V } get obj ( ) { return this . _config_object ; } returns { V } get config ( ) { return this . config_file ; } param environment returns { boolean } is ( environment ) { return environment === this . environment ; } /**
     * Check
     * Looks for a match of the hostName to any of the domain
     * values specified during the configuration bootstrapping
     * phase of Aurelia.
     *
     */ check ( ) { let hostname = this . window . hostName ; if ( this . window . port != '' ) { hostname += ':' + this . window . port ; } if ( this . base_path_mode ) { hostname += this . window . pathName ; } if ( this . environments ) { for ( let env in this . environments ) { let hostnames = this . environments [ env ] ; if ( hostnames ) { for ( let host of hostnames ) { if ( hostname . search ( '(?:^|W)' + host + '(?:$|W)' ) !== - 1 ) { this . setEnvironment ( env ) ; return ; } } } } } } returns { boolean } environmentEnabled ( ) { return ! ( this . environment === 'default' || this . environment === '' || ! this . environment ) ; } returns { boolean } environmentExists ( ) { return this . environment in this . obj ; } param baseObject param key returns { * } getDictValue ( baseObject , key ) { let splitKey = key . split ( '.' ) ; let currentObject = baseObject ; splitKey . forEach ( key => { if ( currentObject [ key ] ) { currentObject = currentObject [ key ] ; } else { throw 'Key ' + key + ' not found' ; } } ) ; return currentObject ; } param key param defaultValue returns { * } get ( key , defaultValue = null ) { let returnVal = defaultValue ; if ( key . indexOf ( '.' ) === - 1 ) { if ( ! this . environmentEnabled ( ) ) { return this . obj [ key ] ? this . obj [ key ] : defaultValue ; } if ( this . environmentEnabled ( ) ) { if ( this . environmentExists ( ) && this . obj [ this . environment ] [ key ] ) { returnVal = this . obj [ this . environment ] [ key ] ; } else if ( this . cascade_mode && this . obj [ key ] ) { returnVal = this . obj [ key ] ; } return returnVal ; } } else { if ( this . environmentEnabled ( ) ) { if ( this . environmentExists ( ) ) { try { return this . getDictValue ( this . obj [ this . environment ] , key ) ; } catch { if ( this . cascade_mode ) { try { return this . getDictValue ( this . obj , key ) ; } catch { } } } } } else { try { return this . getDictValue ( this . obj , key ) ; } catch { } } } return returnVal ; } param key param val set ( key , val ) { if ( key . indexOf ( '.' ) === - 1 ) { this . obj [ key ] = val ; } else { let splitKey = key . split ( '.' ) ; let parent = splitKey [ 0 ] ; let child = splitKey [ 1 ] ; if ( this . obj [ parent ] === undefined ) { this . obj [ parent ] = { } ; } this . obj [ parent ] [ child ] = val ; } } param obj merge ( obj ) { let currentConfig = this . _config_object ; this . _config_object = deepExtend ( currentConfig , obj ) ; } param obj lazyMerge ( obj ) { let currentMergeConfig = this . _config_merge_object || { } ; this . _config_merge_object = deepExtend ( currentMergeConfig , obj ) ; } param obj setAll ( obj ) { this . _config_object = obj ; } returns { V } getAll ( ) { return this . obj ; } returns { Promise } loadConfig ( ) { return this . loadConfigFile ( join ( this . directory , this . config ) , ( data ) => this . setAll ( data ) ) . then ( ( ) => { if ( this . _config_merge_object ) { this . merge ( this . _config_merge_object ) ; this . _config_merge_object = null ; } } ) ; } returns { Promise } loadConfigFile ( path , action ) { return new Promise ( ( resolve , reject ) => { let pathClosure = path . toString ( ) ; let xhr = new XMLHttpRequest ( ) ; if ( xhr . overrideMimeType ) { xhr . overrideMimeType ( 'application/json' ) ; } xhr . open ( 'GET' , pathClosure , true ) ; xhr . onreadystatechange = function ( ) { if ( xhr . readyState == 4 && xhr . status == 200 ) { let data = JSON . parse ( this . responseText ) ; action ( data ) ; resolve ( data ) ; } } ; xhr . onloadend = function ( ) { if ( xhr . status == 404 ) { reject ( 'Configuration file could not be found: ' + path ) ; } } ; xhr . onerror = function ( ) { reject ( `Configuration file could not be found or loaded: ${ pathClosure }` ) ; } ; xhr . send ( null ) ; } ) ; } param path param optional mergeConfigFile ( path , optional ) { return new Promise ( ( resolve , reject ) => { this . loadConfigFile ( path , ( data ) => { this . lazyMerge ( data ) ; resolve ( ) ; } ) . catch ( error => { if ( optional === true ) { resolve ( ) ; } else { reject ( error ) ; } } ) ; } ) ; } }