UNPKG

5.59 kBPlain TextView Raw
1#!/usr/bin/env node
2
3'use strict';
4
5const { EOL } = require('os');
6const path = require('path');
7
8const cli = require('commander');
9const { red, green } = require('chalk');
10
11const { version: VERSION } = require('../package.json');
12
13function inLuxProject() {
14 const cwd = process.cwd();
15
16 if (cwd.indexOf(path.join('lux', 'test', 'test-app')) >= 0) {
17 return true;
18 }
19
20 try {
21 const { dependencies } = require(path.join(cwd, 'package.json'));
22 return Boolean(dependencies['lux-framework']);
23 } catch (err) {
24 return false;
25 }
26}
27
28function commandNotFound(cmd) {
29 // eslint-disable-next-line no-console
30 console.log(
31 `${EOL} ${red(cmd)} is not a valid command.${EOL.repeat(2)}`,
32 ` Use ${green('lux --help')} for a full list of commands.${EOL}`
33 );
34}
35
36function setEnvVar(key, val, def) {
37 if (val) {
38 Reflect.set(process.env, key, val);
39 } else if (!Reflect.has(process.env, key)) {
40 Reflect.set(process.env, key, def);
41 }
42}
43
44function exec(cmd, ...args) {
45 const handler = require('../dist')[cmd];
46 const needsProject = new RegExp(
47 '^(?:db:.+|test|build|serve|console|generate|destroy)$'
48 );
49
50 if (needsProject.test(cmd) && !inLuxProject()) {
51 return Promise.reject(new Error(
52 'Directory does not contain a valid Lux application.'
53 ));
54 }
55
56 return handler(...args);
57}
58
59function exit(code) {
60 process.exit(typeof code === 'number' ? code : 0);
61}
62
63function rescue(err) {
64 // eslint-disable-next-line
65 console.error(err.stack);
66 exit(1);
67}
68
69cli.version(VERSION);
70
71cli
72 .command('n <name>')
73 .alias('new')
74 .description('Create a new application')
75 .option(
76 '--database [database]',
77 'Database driver',
78 /^(postgres|sqlite|mysql|mariadb|oracle)$/i,
79 'sqlite'
80 )
81 .action((name, { database }) => {
82 exec('create', name, database)
83 .then(exit)
84 .catch(rescue);
85 });
86
87cli
88 .command('t')
89 .alias('test')
90 .description('Run your application\'s test suite')
91 .action(() => {
92 exec('test')
93 .then(exit)
94 .catch(rescue);
95 });
96
97cli
98 .command('b')
99 .alias('build')
100 .description('Build your application')
101 .option('-w, --use-weak', 'Use weak mode')
102 .action(({ useWeak }) => {
103 exec('build', !useWeak)
104 .then(exit)
105 .catch(rescue);
106 });
107
108cli
109 .command('c')
110 .alias('console')
111 .description('Load your application into a repl')
112 .option('-e, --environment [env]', '(Default: development)')
113 .option('-w, --use-weak', 'Use weak mode')
114 .action(({ environment, useWeak }) => {
115 setEnvVar('NODE_ENV', environment, 'development');
116 process.env.LUX_CONSOLE = true;
117
118 exec('build', !useWeak)
119 .then(() => exec('repl'))
120 .then(exit)
121 .catch(rescue);
122 });
123
124cli
125 .command('s')
126 .alias('serve')
127 .description('Serve your application')
128 .option('-c, --cluster', 'Run in cluster mode')
129 .option('-e, --environment [env]', '(Default: development)')
130 .option(
131 '-p, --port [port]',
132 '(Default: 4000)',
133 port => Number.parseInt(port, 10)
134 )
135 .option('-H, --hot', 'Reload when a file change is detected')
136 .option('-w, --use-weak', 'Use weak mode')
137 .action(({ hot, port, cluster, environment, useWeak }) => {
138 const useStrict = !useWeak;
139
140 setEnvVar('PORT', port, 4000);
141 setEnvVar('NODE_ENV', environment, 'development');
142
143 exec('build', useStrict)
144 .then(() => exec('serve', { hot, cluster, useStrict }))
145 .catch(rescue);
146 });
147
148cli
149 .command('g <type> <name> [attrs...]')
150 .alias('generate')
151 .description('Example: lux generate model user')
152 .action((type, name, attrs) => {
153 exec('generate', { type, name, attrs })
154 .then(exit)
155 .catch(rescue);
156 });
157
158cli
159 .command('d')
160 .alias('destroy <type> <name>')
161 .description('Example: lux destroy model user')
162 .action((type, name) => {
163 exec('destroy', { type, name })
164 .then(exit)
165 .catch(rescue);
166 });
167
168cli
169 .command('db:create')
170 .description('Create your database schema')
171 .option('-w, --use-weak', 'Use weak mode')
172 .action(({ useWeak }) => {
173 exec('build', !useWeak)
174 .then(() => exec('dbcreate'))
175 .then(exit)
176 .catch(rescue);
177 });
178
179cli
180 .command('db:drop')
181 .description('Drop your database schema')
182 .option('-w, --use-weak', 'Use weak mode')
183 .action(({ useWeak }) => {
184 exec('build', !useWeak)
185 .then(() => exec('dbdrop'))
186 .then(exit)
187 .catch(rescue);
188 });
189
190cli
191 .command('db:reset')
192 .description('Drop your database schema and create a new schema')
193 .option('-w, --use-weak', 'Use weak mode')
194 .action(({ useWeak }) => {
195 exec('build', !useWeak)
196 .then(() => exec('dbdrop'))
197 .then(() => exec('dbcreate'))
198 .then(exit)
199 .catch(rescue);
200 });
201
202cli
203 .command('db:migrate')
204 .description('Run database migrations')
205 .option('-w, --use-weak', 'Use weak mode')
206 .action(({ useWeak }) => {
207 exec('build', !useWeak)
208 .then(() => exec('dbmigrate'))
209 .then(exit)
210 .catch(rescue);
211 });
212
213cli
214 .command('db:rollback')
215 .description('Rollback the last database migration')
216 .option('-w, --use-weak', 'Use weak mode')
217 .action(({ useWeak }) => {
218 exec('build', !useWeak)
219 .then(() => exec('dbrollback'))
220 .then(exit)
221 .catch(rescue);
222 });
223
224cli
225 .command('db:seed')
226 .description('Add fixtures to your db from the seed function')
227 .option('-w, --use-weak', 'Use weak mode')
228 .action(({ useWeak }) => {
229 exec('build', !useWeak)
230 .then(() => exec('dbseed'))
231 .then(exit)
232 .catch(rescue);
233 });
234
235cli
236 .on('*', commandNotFound)
237 .parse(process.argv);
238
239if (!cli.args.length) {
240 cli.help();
241}