88 ServeConfig ,
99 LOGGER_DIR ,
1010 IONIC_LAB_URL ,
11- IOS_PLATFORM_PATH ,
12- ANDROID_PLATFORM_PATH
11+ IOS_PLATFORM_PATHS ,
12+ ANDROID_PLATFORM_PATHS
1313} from './serve-config' ;
1414import { Logger } from '../logger/logger' ;
1515import * as proxyMiddleware from 'proxy-middleware' ;
@@ -36,7 +36,7 @@ export function createHttpServer(config: ServeConfig): express.Application {
3636 // Lab routes
3737 app . use ( IONIC_LAB_URL + '/static' , express . static ( path . join ( __dirname , '..' , '..' , 'lab' , 'static' ) ) ) ;
3838 app . get ( IONIC_LAB_URL , LabAppView ) ;
39- app . get ( IONIC_LAB_URL + '/api/v1/cordova' , ApiCordovaProject ) ;
39+ app . get ( IONIC_LAB_URL + '/api/v1/cordova' , ApiCordovaProject ) ;
4040 app . get ( IONIC_LAB_URL + '/api/v1/app-config' , ApiPackageJson ) ;
4141
4242 app . get ( '/cordova.js' , servePlatformResource , serveMockCordovaJS ) ;
@@ -52,7 +52,7 @@ export function createHttpServer(config: ServeConfig): express.Application {
5252
5353function setupProxies ( app : express . Application ) {
5454 if ( getBooleanPropertyValue ( Constants . ENV_READ_CONFIG_JSON ) ) {
55- getProjectJson ( ) . then ( function ( projectConfig : IonicProject ) {
55+ getProjectJson ( ) . then ( function ( projectConfig : IonicProject ) {
5656 for ( const proxy of projectConfig . proxies || [ ] ) {
5757 let opts : any = url . parse ( proxy . proxyUrl ) ;
5858 if ( proxy . proxyNoAgent ) {
@@ -74,7 +74,7 @@ function setupProxies(app: express.Application) {
7474/**
7575 * http responder for /index.html base entrypoint
7676 */
77- function serveIndex ( req : express . Request , res : express . Response ) {
77+ function serveIndex ( req : express . Request , res : express . Response ) {
7878 const config : ServeConfig = req . app . get ( 'serveConfig' ) ;
7979
8080 // respond with the index.html file
@@ -108,37 +108,64 @@ function serveMockCordovaJS(req: express.Request, res: express.Response) {
108108/**
109109 * Middleware to serve platform resources
110110 */
111- function servePlatformResource ( req : express . Request , res : express . Response , next : express . NextFunction ) {
111+ async function servePlatformResource ( req : express . Request , res : express . Response , next : express . NextFunction ) {
112112 const config : ServeConfig = req . app . get ( 'serveConfig' ) ;
113113 const userAgent = req . header ( 'user-agent' ) ;
114- let resourcePath = config . wwwDir ;
115114
116115 if ( ! config . isCordovaServe ) {
117116 return next ( ) ;
118117 }
119118
119+ let root = await getResourcePath ( req . url , config , userAgent ) ;
120+ if ( root ) {
121+ res . sendFile ( req . url , { root } ) ;
122+ } else {
123+ next ( ) ;
124+ }
125+ }
126+
127+ /**
128+ * Determines the appropriate resource path, and checks if the specified url
129+ *
130+ * @returns string of the resource path or undefined if there is no match
131+ */
132+ async function getResourcePath ( url : string , config : ServeConfig , userAgent : string ) : Promise < string > {
133+ let searchPaths : string [ ] = [ config . wwwDir ] ;
120134 if ( isUserAgentIOS ( userAgent ) ) {
121- resourcePath = path . join ( config . rootDir , IOS_PLATFORM_PATH ) ;
135+ searchPaths = IOS_PLATFORM_PATHS . map ( resourcePath => path . join ( config . rootDir , resourcePath ) ) ;
122136 } else if ( isUserAgentAndroid ( userAgent ) ) {
123- resourcePath = path . join ( config . rootDir , ANDROID_PLATFORM_PATH ) ;
137+ searchPaths = ANDROID_PLATFORM_PATHS . map ( resourcePath => path . join ( config . rootDir , resourcePath ) ) ;
124138 }
125139
126- fs . stat ( path . join ( resourcePath , req . url ) , ( err , stats ) => {
127- if ( err ) {
128- return next ( ) ;
129- }
130- res . sendFile ( req . url , { root : resourcePath } ) ;
131- } ) ;
140+ for ( let i = 0 ; i < searchPaths . length ; i ++ ) {
141+ let checkPath = path . join ( searchPaths [ i ] , url ) ;
142+ try {
143+ let result = await checkFile ( checkPath ) ;
144+ return searchPaths [ i ] ;
145+ } catch ( e ) { }
146+ }
132147}
133148
149+ /**
150+ * Checks if a file exists (responds to stat)
151+ */
152+ function checkFile ( filePath : string ) : Promise < void > {
153+ return new Promise ( ( resolve , reject ) => {
154+ fs . stat ( filePath , ( err : Error , stats : any ) => {
155+ if ( err ) {
156+ return reject ( ) ;
157+ }
158+ resolve ( ) ;
159+ } ) ;
160+ } ) ;
161+ }
134162
135-
136- function isUserAgentIOS ( ua : string ) {
163+ function isUserAgentIOS ( ua : string ) : boolean {
137164 ua = ua . toLowerCase ( ) ;
138165 return ( ua . indexOf ( 'iphone' ) > - 1 || ua . indexOf ( 'ipad' ) > - 1 || ua . indexOf ( 'ipod' ) > - 1 ) ;
139166}
140167
141- function isUserAgentAndroid ( ua : string ) {
168+ function isUserAgentAndroid ( ua : string ) : boolean {
142169 ua = ua . toLowerCase ( ) ;
143170 return ua . indexOf ( 'android' ) > - 1 ;
144171}
0 commit comments