/** * @license * Copyright (c) 2016 The Polymer Project Authors. All rights reserved. * This code may only be used under the BSD style license found at * http://polymer.github.io/LICENSE.txt * The complete set of authors may be found at * http://polymer.github.io/AUTHORS.txt * The complete set of contributors may be found at * http://polymer.github.io/CONTRIBUTORS.txt * Code distributed by Google as part of the polymer project is also * subject to an additional IP rights grant found at * http://polymer.github.io/PATENTS.txt */ // Be careful with these imports. As many as possible should be dynamic imports // in the run method in order to minimize startup time from loading unused code. import * as logging from 'plylog'; import {ProjectConfig} from 'polymer-project-config'; import {args as polyserveArgs} from 'polyserve/lib/args'; import {ServerOptions} from 'polyserve/lib/start_server'; import {Environment} from '../environment/environment'; import {Command, CommandOptions} from './command'; const logger = logging.getLogger('cli.command.serve'); export class ServeCommand implements Command { name = 'serve'; aliases = []; description = 'Runs the polyserve development server'; args = polyserveArgs; async run(options: CommandOptions, config: ProjectConfig) { // Defer dependency loading until this specific command is run const polyserve = await import('polyserve'); const startServers = polyserve.startServers; const getServerUrls = polyserve.getServerUrls; const url = await import('url'); let openPath: string|undefined; if (config.entrypoint && config.shell) { openPath = config.entrypoint.substring(config.root.length); if (openPath === 'index.html' || openPath === '/index.html') { openPath = '/'; } } // TODO(justinfagnani): Consolidate args handling between polymer-cli and // polyserve's CLI. const proxyArgs = { path: options['proxy-path'], target: options['proxy-target'] }; const serverOptions: ServerOptions = { root: options['root'], allowOrigin: options['allow-origin'], entrypoint: config.entrypoint, compile: options['compile'], port: options['port'], hostname: options['hostname'], open: options['open'], browser: options['browser'], openPath: options['open-path'], npm: config.npm, moduleResolution: config.moduleResolution, componentDir: config.componentDir, packageName: options['package-name'], protocol: options['protocol'], keyPath: options['key'], certPath: options['cert'], pushManifestPath: options['manifest'], proxy: proxyArgs.path && proxyArgs.target && proxyArgs, }; logger.debug('serving with options', serverOptions); const env: Environment = options['env']; if (env && env.serve) { logger.debug('env.serve() found in options'); logger.debug('serving via env.serve()...'); return env.serve(serverOptions); } logger.debug('serving via polyserve.startServers()...'); const serverInfos = await startServers(serverOptions); if (serverInfos.kind === 'mainline') { const mainlineServer = serverInfos; const urls = getServerUrls(options, mainlineServer.server); logger.info( `Files in this directory are available under the following URLs applications: ${url.format(urls.serverUrl)} reusable components: ${url.format(urls.componentUrl)} `); } else { // We started multiple servers, just tell the user about the control // server, it serves out human-readable info on how to access the others. const urls = getServerUrls(options, serverInfos.control.server); logger.info(`Started multiple servers with different variants: View the Polyserve console here: ${url.format(urls.serverUrl)}`); } } }