UNPKG

4.22 kBJavaScriptView Raw
1var https = require('https');
2var _ = require('lodash');
3var fs = require('fs');
4var path = require('path');
5var async = require('async');
6var formatUrl = require('url').format;
7var api = require('../lib/api');
8var openBrowser = require('open');
9var basedir = require('../lib/basedir');
10var log = require('../lib/log');
11var debug = require('debug')('4front:cli:dev-sandbox');
12var sandboxServer = require('../lib/sandbox-server');
13var spawn = require('../lib/spawn');
14
15module.exports = function(program, done) {
16 _.defaults(program, {
17 port: 3000,
18 autoReload: program.virtualAppManifest.autoReload === true,
19 cwd: process.cwd(),
20 buildType: 'debug'
21 });
22
23 debug('running dev-sandbox command');
24
25 if (program.release === true) {
26 program.buildType = 'release';
27 }
28
29 // Verify that the build type is valid.
30 if (_.contains(['debug', 'release'], program.buildType) === false) {
31 return done('Invalid build-type option value. Valid values are \'debug\' and \'release\'.');
32 }
33
34 var asyncTasks = [];
35
36 // If serving in release mode, run the build step first.
37 asyncTasks.push(function(cb) {
38 if (program.buildType === 'release' && program.virtualAppManifest.scripts.build) {
39 spawn('npm', ['run-script', program.virtualAppManifest.scripts.build], cb);
40 } else {
41 cb();
42 }
43 });
44
45 // Determine which directory should be the base from which relative
46 // file paths are resolved from. A common convention is to have a directory
47 // like 'app' for raw source files and 'release' for build assets.
48 // Do this after the previous step in case the release directory is
49 // created for the first time by the build script.
50 asyncTasks.push(function(cb) {
51 basedir(program, function(err, baseDir) {
52 if (err) return cb(err);
53
54 debug('setting baseDir to %s', baseDir);
55 program.baseDir = baseDir;
56 cb();
57 });
58 });
59
60 asyncTasks.push(function(cb) {
61 if (program.virtualAppManifest.scripts.build) {
62 debug('Found npm build script');
63 spawn('npm', ['run-script', program.virtualAppManifest.scripts.build], cb);
64 } else {
65 cb();
66 }
67 });
68
69 asyncTasks.push(function(cb) {
70 if (program.virtualAppManifest.scripts.watch) {
71 debug('Found npm watch script');
72 spawn('npm', ['run-script', program.virtualAppManifest.scripts.watch],
73 {waitForExit: false}, cb);
74 } else {
75 cb();
76 }
77 });
78
79 asyncTasks.push(function(cb) {
80 debug('uploading the app manifest');
81
82 // Upload the app manifest
83 var requestOptions = {
84 method: 'post',
85 path: '/dev/' + program.virtualApp.appId + '/manifest',
86 body: _.omit(program.virtualAppManifest, 'scripts', 'appId')
87 };
88
89 api(program, requestOptions, cb);
90 });
91
92 var localhost;
93 var sandboxUrl = buildSandboxUrl();
94
95 asyncTasks.push(function(cb) {
96 localhost = sandboxServer(program);
97
98 if (program.virtualApp.requireSsl) {
99 // Using the same SSL cert from the grunt server task
100 var httpsOptions = {
101 key: fs.readFileSync(path.join(__dirname, '../certs', 'private.key')).toString(),
102 cert: fs.readFileSync(path.join(__dirname, '../certs', 'localhost.crt')).toString(),
103 rejectUnauthorized: false
104 };
105
106 https.createServer(httpsOptions, localhost).listen(program.port, cb);
107 } else {
108 localhost.listen(program.port, cb);
109 }
110 });
111
112 async.series(asyncTasks, function(err) {
113 if (err) return done(err);
114
115 // Display a message that the app is ready for development at the sandboxUrl.
116 log.messageBox('The dev sandbox was launched in your browser with url:');
117 log.writeln(sandboxUrl);
118
119 openBrowser(sandboxUrl);
120
121 done(null, function() {
122 if (localhost) localhost.stop();
123 });
124 });
125
126 function buildSandboxUrl() {
127 var devOptions = {
128 buildType: program.buildType,
129 token: program.profile.jwt.token,
130 port: program.port
131 };
132
133 if (program.autoReload === true) {
134 devOptions.autoReload = 1;
135 }
136
137 return formatUrl({
138 protocol: program.virtualApp.requireSsl === true ? 'https' : 'http',
139 host: program.virtualApp.name + '--dev.' + program.virtualHost,
140 pathname: '/__login',
141 query: devOptions
142 });
143 }
144};