aboutsummaryrefslogtreecommitdiffstats
path: root/cli.js
diff options
context:
space:
mode:
authorJan Tuomi <jan.tuomi@eficode.com>2018-07-12 12:22:15 +0300
committerJan Tuomi <jan.tuomi@eficode.com>2018-07-12 12:23:14 +0300
commit33fc72e5ce47a0669072d173e6f95e6e3661f516 (patch)
treea24c7ecf95a7ba54e6fa4d48e4727e74b358ea60 /cli.js
parent2d9e63a11b1a0e6052d794d87b614df854ca4536 (diff)
Initial commit
Diffstat (limited to 'cli.js')
-rwxr-xr-xcli.js232
1 files changed, 232 insertions, 0 deletions
diff --git a/cli.js b/cli.js
new file mode 100755
index 0000000..6319e4c
--- /dev/null
+++ b/cli.js
@@ -0,0 +1,232 @@
+#!/usr/bin/env node
+const path = require('path');
+const fs = require('fs');
+const monk = require('monk');
+const express = require('express');
+let serverInstance;
+const requireFromString = require('require-from-string');
+
+const userConfigPath = path.join(process.env.HOME, '.faas.config');
+require('dotenv').config({
+ path: userConfigPath,
+});
+let mongoURL = process.env.MONGO_URL;
+
+const chalk = require('chalk');
+
+const vorpal = require('vorpal')();
+vorpal.delimiter(chalk.blue('faas $'));
+
+const showMongoNotSetError = v => {
+ v.log(chalk.red('MongoDB URL is not set or is invalid. The URL is needed to authorize the CLI.'));
+ v.log(chalk.red('Please use the command "authorize <url>" to set the URL.'));
+}
+
+const checkConnection = async (url, v) => {
+ return new Promise((resolve, reject) => {
+ let db;
+ try {
+ db = monk(url);
+ } catch (err) {
+ v.log(chalk.red('Failed to authorize the CLI! Please review the Mongo URL.'));
+ v.log(chalk.red(String(err)));
+ reject(err);
+ }
+
+ db.then(async () => {
+ models = require('./models')(db);
+ await models.endpoints.stats();
+ resolve();
+ }).catch(err => {
+ v.log(chalk.red('Failed to authorize the CLI! Please review the Mongo URL.'));
+ v.log(chalk.red(String(err)));
+ reject(err);
+ });
+ });
+}
+
+let db, models;
+
+(async function() {
+ try {
+ await checkConnection(mongoURL, vorpal);
+ db = monk(mongoURL);
+ models = require('./models')(db);
+ } catch (err) {
+ showMongoNotSetError(vorpal);
+ }
+})();
+
+vorpal
+ .command('authorize <url>', 'Set the MongoDB URL to authorize the CLI.')
+ .action(async function(args, callback) {
+ if (!args.url) {
+ this.log('Please give the Mongo URL.');
+ return callback();
+ }
+
+ const row = `MONGO_URL=${args.url}`;
+ fs.writeFileSync(userConfigPath, row);
+
+ try {
+ await checkConnection(args.url, this);
+ this.log(chalk.green('CLI successfully authorized!'));
+ mongoURL = args.url;
+ } catch (err) {
+ mongoURL = null;
+ }
+ });
+
+vorpal
+ .command('create <name>', 'Create new endpoint called "name".')
+ .action(async function(args, callback) {
+ try {
+ await checkConnection(mongoURL, this);
+ } catch (err) {
+ showMongoNotSetError(vorpal);
+ return callback();
+ }
+
+ if (!args.name) {
+ this.log('Please give a name for the endpoint.');
+ return callback();
+ }
+ try {
+ await models.endpoints.insert({
+ name: args.name,
+ code: `module.exports = function (req, res) { res.send('Hello ${args.name}!') }`,
+ });
+ this.log(`Created endpoint ${args.name}.`);
+ } catch (err) {
+ this.log(chalk.red('Failed to create endpoint.'));
+ if (String(err).includes('E11000')) {
+ this.log('Endpoint names must be unique.');
+ } else {
+ this.log(String(err));
+ }
+ }
+ callback();
+ });
+
+vorpal
+ .command('remove <name>', 'Remove endpoint called "name".')
+ .action(async function(args, callback) {
+ try {
+ await checkConnection(mongoURL, this);
+ } catch (err) {
+ showMongoNotSetError(vorpal);
+ return callback();
+ }
+
+ if (!args.name) {
+ this.log('Please give a name for the endpoint.');
+ return callback();
+ }
+ try {
+ await models.endpoints.remove({
+ name: args.name,
+ });
+ } catch (err) {
+ this.log(chalk.red(`Failed to remove endpoint ${args.name}!`));
+ this.log(chalk.red(String(err)));
+ }
+ this.log(`Removed endpoint ${args.name}.`);
+ callback();
+ });
+
+vorpal
+ .command('list', 'List all endpoints.')
+ .action(async function(args, callback) {
+ try {
+ await checkConnection(mongoURL, this);
+ } catch (err) {
+ showMongoNotSetError(vorpal);
+ return callback();
+ }
+
+ const endpoints = await models.endpoints.find({});
+ endpoints.forEach(endpoint => {
+ this.log(`${chalk(endpoint.name)}`);
+ })
+ callback();
+ });
+
+vorpal
+ .command('upload <file> <endpoint>', 'Upload "file" to endpoint "endpoint".')
+ .action(async function(args, callback) {
+ try {
+ await checkConnection(mongoURL, this);
+ } catch (err) {
+ showMongoNotSetError(vorpal);
+ return callback();
+ }
+
+ if (!args.file || !args.endpoint) {
+ this.log('Please provide both "file" and "endpoint" as arguments.');
+ return callback();
+ }
+
+ const existing = await models.endpoints.findOne({ name: args.endpoint });
+ if (!existing) {
+ this.log(chalk.red(`Endpoint ${args.endpoint} doesn't exist!`));
+ return callback();
+ }
+
+ try {
+ this.log(chalk.yellow(`Uploading function from file "${args.file}"...`));
+ const data = fs.readFileSync(path.join(process.cwd(), args.file), 'utf-8');
+ await models.endpoints.update(
+ { name: args.endpoint },
+ { code: data, name: args.endpoint },
+ { upsert: true });
+ this.log(chalk.green(`Uploaded function successfully to endpoint ${args.endpoint}!`));
+ } catch (err) {
+ this.log(chalk.red(`Failed to upload to endpoint ${args.endpoint}!`));
+ this.log(chalk.red(String(err)));
+ }
+ callback();
+ });
+
+vorpal
+ .command('start dev <file>', 'Run a function locally for development purposes.')
+ .action(async function(args, callback) {
+ if (!args.file ) {
+ this.log('Please provide the "file" to run.');
+ return callback();
+ }
+ const code = fs.readFileSync(path.join(process.cwd(), args.file), 'utf-8');
+ if (serverInstance) {
+ serverInstance.close();
+ }
+ const app = express();
+ const func = requireFromString(code);
+ app.all('*', async (req, res) => {
+ func(req, res);
+ });
+ const port = 1337;
+ serverInstance = app.listen(port, () =>
+ console.log(`${chalk.blue('debug server')} listening on port ${port}! URL: ${chalk.yellow(`http://localhost:${port}`)}`)
+ );
+ callback();
+ });
+
+vorpal
+ .command('stop dev', 'Stop the development server.')
+ .action(async function(args, callback) {
+ if (serverInstance) {
+ serverInstance.close();
+ this.log(chalk.green('Server stopped.'));
+ } else {
+ this.log(chalk.red('Server is not running.'));
+ }
+ callback();
+ });
+
+vorpal
+ .command('info', 'Show information about the session')
+ .action(async function(args, callback) {
+ this.log('Mongo URL: ' + chalk.yellow(mongoURL));
+ callback();
+ });
+
+vorpal.show();