UNPKG

5.13 kBJavaScriptView Raw
1var inquirer = require("inquirer");
2var _ = require('lodash');
3var isValidJSName = require('../util/isValidJSName');
4var slug = require('slug');
5var chalk = require('chalk');
6var shell = require('shelljs');
7var async = require('async');
8var fs = require('fs-extra');
9var path = require('path');
10var log = require('../util/log');
11var multichoice = require('../util/multichoice');
12
13module.exports = function(program){
14 program
15 .command('init')
16 .description('initialize a new Custom App design')
17 .action(function(){
18
19 inquirer.prompt([
20 {
21 type: 'input',
22 message: 'design name',
23 name: 'name'
24 },
25 multichoice({
26 type: 'list',
27 message: 'select a starter',
28 name: 'starter',
29 choices: ['hello world', 'manifest only']
30 })
31
32 ], function(answers){
33 // answers.list = multichoice.answer(answers.list);
34 answers.datasources = [];
35 askDatasource(answers, function(allAnswers){
36 var files;
37 var dirs;
38 var step = 0;
39 var nextStepsMessage = 'Next steps: \n';
40
41 if(allAnswers.starter === 'manifest only'){
42 files = ['manifest.json'];
43 dirs = [null];
44 }
45 else if (allAnswers.starter === 'hello world'){
46 files = ['manifest.json', 'index.html', 'app.js', 'app.css', 'domo.js'];
47 dirs = [null, null, null, null, null];
48
49 var dirname = slug(answers.name);
50 nextStepsMessage += `${stepNumber()} ${chalk.cyan('cd')} into the ${chalk.green(dirname)} directory\n`;
51
52 shell.mkdir('-p', dirname);
53 process.chdir(path.resolve(dirname));
54 }
55
56 // populate and write out the template files
57 writeFilesIfNonexistent(files, dirs, allAnswers, function(err, res) {
58 if(err) {
59 log.fail('Cannot initialize new design. Doing so would overwrite existing files:' + err);
60 }
61 else {
62 nextStepsMessage += `${stepNumber()} Edit the files that were just generated. \n${stepNumber()} Run ${chalk.cyan('domo login')} if you haven't already. \n${stepNumber()} Run ${chalk.cyan('domo publish')} whenever you make changes. \n${stepNumber()} Add a Custom App card to any page in Domo. `;
63 log.ok(`New design initialized in the ${chalk.green(dirname || 'current')} directory`, nextStepsMessage);
64 }
65
66 if (allAnswers.starter === 'hello world'){
67 fs.remove('node_modules');
68 }
69
70 process.exit();
71
72 });
73
74 /**
75 * Add an incrementing step to the instructions message
76 */
77 function stepNumber(){
78 step++;
79 return `${step}.`;
80 }
81
82
83 });
84 });
85
86
87
88
89
90 });
91
92}
93
94
95// recursively ask user to enter all their datasources
96function askDatasource(currentAnswers, callback){
97 inquirer.prompt([
98 {
99 type: 'confirm',
100 message: currentAnswers.datasources.length > 0 ? 'add another dataset?' : 'would you like to connect to any datasets?',
101 name: 'askDatasource'
102 }
103 ], function(answers){
104 if (answers.askDatasource){
105 addDatasource(_.merge(currentAnswers, answers), function(combinedAnswers){
106 // ask for more datasources
107 askDatasource(combinedAnswers, callback);
108 });
109 }
110 else {
111 // all done with datasources, continue on.
112 callback(_.merge(currentAnswers, answers));
113 }
114 });
115}
116
117
118function addDatasource(currentAnswers, callback){
119 inquirer.prompt([
120 {
121 type: 'input',
122 message: 'dataset id',
123 name: 'id'
124 },
125 {
126 type: 'input',
127 message: 'dataset alias',
128 name: 'alias',
129 validate: function(name){
130 if (!isValidJSName(name)) return 'Alias must be a valid JavaScript property';
131 return true;
132 }
133 }
134 ], function(datasource){
135 currentAnswers.datasources.push(datasource);
136 callback(currentAnswers);
137 });
138}
139
140function writeFilesIfNonexistent(files, dirs, allAnswers, callback) {
141 async.reduce(files, [], function(filesThatExist, file, reduceCallback) {
142 fs.open(file,'r',function(err, fd) {
143 var fileExists = !err;
144 if(fileExists) {
145 fs.closeSync(fd);
146 filesThatExist.push(file);
147 }
148 reduceCallback(null, filesThatExist);
149 });
150 }, function(err, filesThatExist) {
151 if(filesThatExist.length > 0) {
152 callback(filesThatExist, null);
153 }
154 else {
155 _.zip(files,dirs).forEach(writeTemplateFile);
156 callback(null, files);
157 }
158 });
159
160 function writeTemplateFile(filedir){
161 var file = filedir[0];
162 var dir = filedir[1];
163 dir = dir || (__dirname + '/../templates/');
164 var contents = _.template(fs.readFileSync(path.resolve(dir + file )))(allAnswers);
165
166 fs.writeFileSync(process.cwd() + '/' + file, contents);
167 }
168}