|
| 1 | +import * as assign from 'lodash/assign'; |
| 2 | +import * as Command from 'ember-cli/lib/models/command'; |
| 3 | +import * as Serve from '../tasks/serve'; |
| 4 | +import * as Promise from 'ember-cli/lib/ext/promise'); |
| 5 | +import * as SilentError from 'silent-error'; |
| 6 | +import * as PortFinder from 'portfinder'; |
| 7 | +import * as win from 'ember-cli/lib/utilities/windows-admin'; |
| 8 | +import * as EOL from 'os'.EOL; |
| 9 | + |
| 10 | +PortFinder.basePort = 49152; |
| 11 | + |
| 12 | +let getPort = Promise.denodeify(PortFinder.getPort); |
| 13 | +let defaultPort = process.env.PORT || 4200; |
| 14 | + |
| 15 | +const ServeCommand = Command.extend({ |
| 16 | + name: 'serve', |
| 17 | + description: 'Builds and serves your Angular2 app, rebuilding on file changes.', |
| 18 | + aliases: ['server', 's'], |
| 19 | + |
| 20 | + availableOptions: [ |
| 21 | + { name: 'port', type: Number, default: defaultPort, aliases: ['p'] }, |
| 22 | + { name: 'host', type: String, aliases: ['H'], description: 'Listens on all interfaces by default' }, |
| 23 | + { name: 'proxy', type: String, aliases: ['pr', 'pxy'] }, |
| 24 | + { name: 'insecure-proxy', type: Boolean, default: false, aliases: ['inspr'], description: 'Set false to proxy self-signed SSL certificates' }, |
| 25 | + { name: 'watcher', type: String, default: 'events', aliases: ['w'] }, |
| 26 | + { name: 'live-reload', type: Boolean, default: true, aliases: ['lr'] }, |
| 27 | + { name: 'live-reload-host', type: String, aliases: ['lrh'], description: 'Defaults to host' }, |
| 28 | + { name: 'live-reload-base-url', type: String, aliases: ['lrbu'], description: 'Defaults to baseURL' }, |
| 29 | + { name: 'live-reload-port', type: Number, aliases: ['lrp'], description: '(Defaults to port number within [49152...65535])' }, |
| 30 | + { name: 'environment', type: String, default: 'development', aliases: ['e', { 'dev': 'development' }, { 'prod': 'production' }] }, |
| 31 | + { name: 'output-path', type: 'Path', default: 'dist/', aliases: ['op', 'out'] }, |
| 32 | + { name: 'ssl', type: Boolean, default: false }, |
| 33 | + { name: 'ssl-key', type: String, default: 'ssl/server.key' }, |
| 34 | + { name: 'ssl-cert', type: String, default: 'ssl/server.crt' } |
| 35 | + ], |
| 36 | + |
| 37 | + run: function(commandOptions) { |
| 38 | + commandOptions.liveReloadHost = commandOptions.liveReloadHost || commandOptions.host; |
| 39 | + |
| 40 | + return this._checkExpressPort(commandOptions) |
| 41 | + .then(this._autoFindLiveReloadPort.bind(this)) |
| 42 | + .then(function(commandOptions) { |
| 43 | + commandOptions = assign({}, commandOptions, { |
| 44 | + baseURL: this.project.config(commandOptions.environment).baseURL || '/' |
| 45 | + }); |
| 46 | + |
| 47 | + if (commandOptions.proxy) { |
| 48 | + if (!commandOptions.proxy.match(/^(http:|https:)/)) { |
| 49 | + var message = 'You need to include a protocol with the proxy URL.' + EOL + 'Try --proxy http://' + commandOptions.proxy; |
| 50 | + |
| 51 | + return Promise.reject(new SilentError(message)); |
| 52 | + } |
| 53 | + } |
| 54 | + |
| 55 | + var ServeTask = Serve; |
| 56 | + var serve = new ServeTask({ |
| 57 | + ui: this.ui, |
| 58 | + analytics: this.analytics, |
| 59 | + project: this.project |
| 60 | + }); |
| 61 | + |
| 62 | + return win.checkWindowsElevation(this.ui).then(function() { |
| 63 | + return serve.run(commandOptions); |
| 64 | + }); |
| 65 | + }.bind(this)); |
| 66 | + }, |
| 67 | + |
| 68 | + _checkExpressPort: function(commandOptions) { |
| 69 | + return getPort({ port: commandOptions.port, host: commandOptions.host }) |
| 70 | + .then(function(foundPort) { |
| 71 | + |
| 72 | + if (commandOptions.port !== foundPort && commandOptions.port !== 0) { |
| 73 | + var message = 'Port ' + commandOptions.port + ' is already in use.'; |
| 74 | + return Promise.reject(new SilentError(message)); |
| 75 | + } |
| 76 | + |
| 77 | + commandOptions.port = foundPort; |
| 78 | + return commandOptions; |
| 79 | + |
| 80 | + }.bind(this)); |
| 81 | + }, |
| 82 | + |
| 83 | + _autoFindLiveReloadPort: function(commandOptions) { |
| 84 | + return getPort({ port: commandOptions.liveReloadPort, host: commandOptions.liveReloadHost }) |
| 85 | + .then(function(foundPort) { |
| 86 | + |
| 87 | + if (foundPort === commandOptions.port) { |
| 88 | + commandOptions.liveReloadPort = foundPort + 1; |
| 89 | + return this._autoFindLiveReloadPort(commandOptions); |
| 90 | + } |
| 91 | + |
| 92 | + if (foundPort === commandOptions.liveReloadPort) { |
| 93 | + return commandOptions; |
| 94 | + } |
| 95 | + |
| 96 | + commandOptions.liveReloadPort = foundPort; |
| 97 | + return commandOptions; |
| 98 | + |
| 99 | + }.bind(this)); |
| 100 | + } |
| 101 | + |
| 102 | +}); |
| 103 | + |
| 104 | +module.exports = ServeCommand; |
| 105 | +module.exports.overrideCore = true; |
0 commit comments