diff --git a/bin/polyserve b/bin/polyserve index 87c1aab36..ac5606557 100755 --- a/bin/polyserve +++ b/bin/polyserve @@ -9,8 +9,10 @@ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt */ -var resolve = require('resolve'); -var argv = require('minimist')(process.argv); +'use strict'; + +const resolve = require('resolve'); +const argv = require('minimist')(process.argv); process.title = 'polyserve'; @@ -26,11 +28,13 @@ if (argv.h || argv.help) { } resolve('polyserve', {basedir: process.cwd()}, function(error, path) { - var polyserve = path ? require(path) : require('..'); + let polyserve = path ? require(path) : require('..'); polyserve.startServer({ port: argv.p, page: argv.o, host: argv.H, browser: argv.b + }).catch((e) => { + process.exit(69); }); }); diff --git a/src/bower_config.js b/src/bower_config.js index 4c732ac6d..70d83e946 100644 --- a/src/bower_config.js +++ b/src/bower_config.js @@ -8,16 +8,17 @@ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt */ -var path = require('path'); -var fs = require('fs'); +'use strict'; + +const path = require('path'); +const fs = require('fs'); function bowerConfigPath(root) { - root = path.join(process.cwd(), root || '.'); return path.resolve(root, 'bower.json'); } function bowerConfigContents(root) { - var contents; + let contents; try { contents = fs.readFileSync(bowerConfigPath(root)); diff --git a/src/make_app.js b/src/make_app.js index 30d7b205d..6542a7647 100644 --- a/src/make_app.js +++ b/src/make_app.js @@ -8,34 +8,40 @@ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt */ -var express = require('express'); -var fs = require('fs'); -var path = require('path'); -var parseUrl = require('url').parse; -var send = require('send'); -var bowerConfig = require('./bower_config'); +'use strict'; + +const express = require('express'); +const fs = require('fs'); +const path = require('path'); +const parseUrl = require('url').parse; +const send = require('send'); +const bowerConfig = require('./bower_config'); /** * Make a polyserve express app. - * @param {string} componentDir The directory to serve components from. - * @param {string} packageName A name for this polyserve package. - * @param {Object} headers An object keyed by header name containing - * header values. - * @param {string} root The root directory to serve a package from - * @return {Object} An express app which can be served with - * `app.get` + * @param {Object} options + * @param {string} options.componentDir The directory to serve components from. + * @param {string} options.packageName A name for this polyserve package. + * @param {Object} options.headers An object keyed by header name containing + * header values. + * @param {string} options.root The root directory to serve a package from + * @return {Object} An express app which can be served with `app.get` */ -function makeApp(componentDir, packageName, headers, root) { - componentDir = componentDir || 'bower_components'; - packageName = packageName || bowerConfig(root).name; - root = root || '.'; +function makeApp(options) { + + let root = options.root; + let componentDir = options.componentDir || 'bower_components'; + let packageName = options.packageName || bowerConfig(root).name + || path.basename(process.cwd()); + let headers = options.headers || {}; - var app = express(); + let app = express(); app.get('*', function (req, res) { // Serve local files from . and other components from bower_components - var url = parseUrl(req.url, true); - var splitPath = url.pathname.split('/').slice(1); + let url = parseUrl(req.url, true); + let splitPath = url.pathname.split('/').slice(1); + if (splitPath[0] === packageName) { if (root) { splitPath = [root].concat(splitPath.slice(1)); @@ -45,9 +51,11 @@ function makeApp(componentDir, packageName, headers, root) { } else { splitPath = [componentDir].concat(splitPath); } - var filePath = splitPath.join('/'); + let filePath = splitPath.join('/'); + console.log('filePath', filePath); + if (headers) { - for (header in headers) { + for (let header in headers) { res.append(header, headers[header]); } } diff --git a/src/start_server.js b/src/start_server.js index e921a61d4..fe3bf5a80 100644 --- a/src/start_server.js +++ b/src/start_server.js @@ -8,31 +8,42 @@ * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt */ -var express = require('express'); -var http = require('http'); -var makeApp = require('./make_app'); -var opn = require('opn'); -var util = require('util'); -var findPort = require('find-port'); +'use strict'; +const express = require('express'); +const findPort = require('find-port'); +const http = require('http'); +const makeApp = require('./make_app'); +const opn = require('opn'); + +/** + * @return {Promise} A Promise that completes when the server has started. + */ function startServer(options) { - if (!options.port) { - findPort(8080, 8180, function(ports) { - options.port = ports[0]; - startWithPort(options); - }); - } - else { - startWithPort(options); - } + return new Promise((resolve, reject) => { + if (options.port) { + resolve(options); + } else { + findPort(8080, 8180, function(ports) { + options.port = ports[0]; + resolve(options); + }); + } + }).then((opts) => startWithPort(opts)); } +let portInUseMessage = (port) => ` +ERROR: Port in use: ${port} +Please choose another port, or let an unused port be chosen automatically. +`; + /** * @param {Object} options * @param {Number} options.port -- port number * @param {String} options.host -- hostname string * @param {String=} options.page -- page path, ex: "/", "/index.html" * @param {(String|String[])} options.browser -- names of browser apps to launch + * @return {Promise} */ function startWithPort(options) { @@ -41,36 +52,48 @@ function startWithPort(options) { console.log('Starting Polyserve on port ' + options.port); - var app = express(); - var polyserve = makeApp(options.componentDir, options.packageName); + let app = express(); + let polyserve = makeApp({ + componentDir: options.componentDir, + packageName: options.packageName, + root: process.cwd(), + }); app.use('/components/', polyserve); - var server = http.createServer(app); + let server = http.createServer(app); + let serverStartedResolve; + let serverStartedReject; + let serverStartedPromise = new Promise((resolve, reject) => { + serverStartedResolve = resolve; + serverStartedReject = reject; + }); - server = app.listen(options.port, options.host); + server = app.listen(options.port, options.host, + () => serverStartedResolve(server)); server.on('error', function(err) { - if (err.code === 'EADDRINUSE') - console.error("ERROR: Port in use", options.port, - "\nPlease choose another port, or let an unused port be chosen automatically."); - process.exit(69); + if (err.code === 'EADDRINUSE') { + console.error(portInUseMessage(options.port)); + } + serverStartedReject(err); }); - var baseUrl = util.format('http://'+ options.host +':%d/components/%s/', options.port, - polyserve.packageName); - console.log('Files in this directory are available under ' + baseUrl); + let baseUrl = `http://${options.host}:${options.port}/components/${polyserve.packageName}/`; + console.log(`Files in this directory are available under ${baseUrl}`); if (options.page) { - var url = baseUrl + (options.page === true ? 'index.html' : options.page); + let url = baseUrl + (options.page === true ? 'index.html' : options.page); if (Array.isArray(options.browser)) { - for (var i = 0; i < options.browser.length; i++) + for (let i = 0; i < options.browser.length; i++) opn(url, options.browser[i]); } else { opn(url, options.browser); } } + + return serverStartedPromise; } module.exports = startServer;