├── .gitattributes ├── .gitignore ├── .jshintrc ├── .travis.yml ├── LICENSE.md ├── README.md ├── bin └── thingssdk.js ├── lib ├── commands │ ├── devices.js │ └── new.js ├── core │ ├── cli-helpers.js │ ├── colors-theme.js │ ├── file.js │ └── ports.js ├── devices.js └── new.js ├── package-lock.json ├── package.json ├── scripts └── coverage_combine.js ├── templates ├── dot-gitattributes ├── dot-gitignore ├── espruino │ └── scripts │ │ ├── repl.js │ │ └── upload.js └── main.js └── test ├── commands ├── helper.js ├── test-devices.js └── test-new.js └── unit ├── test-file.js └── test-ports.js /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 18 | .grunt 19 | 20 | # node-waf configuration 21 | .lock-wscript 22 | 23 | # Compiled binary addons (http://nodejs.org/api/addons.html) 24 | build/Release 25 | 26 | # Dependency directories 27 | node_modules 28 | jspm_packages 29 | 30 | # Typings for VSC 31 | typings 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | 39 | # IDE/Editors 40 | .idea 41 | .vscode 42 | 43 | # tmp directory 44 | tmp -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "esversion": 6, 3 | "node": true, 4 | "strict": true, 5 | "browser": true, 6 | "mocha": true 7 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "6" 4 | 5 | install: 6 | - npm install --dev 7 | 8 | script: 9 | - npm run test:coverage 10 | 11 | after_success: 12 | - bash <(curl -s https://codecov.io/bash) -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 thingsSDK 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # thingsSDK CLI 2 | 3 | [![Build Status](https://travis-ci.org/thingsSDK/thingssdk-cli.svg?branch=master)](https://travis-ci.org/thingsSDK/thingssdk-cli) 4 | [![codecov](https://codecov.io/gh/thingsSDK/thingssdk-cli/branch/master/graph/badge.svg)](https://codecov.io/gh/thingsSDK/thingssdk-cli) 5 | [![Dependency Status](https://david-dm.org/thingssdk/thingssdk-cli.svg)](https://david-dm.org/thingssdk/thingssdk-cli) 6 | [![devDependency Status](https://david-dm.org/thingssdk/thingssdk-cli/dev-status.svg)](https://david-dm.org/thingssdk/thingssdk-cli#info=devDependencies) 7 | 8 | thingsSDK CLI is a command line utility for generating and managing modern projects for JavaScript microcontroller runtimes. 9 | 10 | Initial support is for Espruino with hopes to support others like Kinoma in the future. 11 | 12 | ## Install CLI 13 | 14 | ```bash 15 | $ npm install thingssdk-cli -g 16 | ``` 17 | 18 | Note that this project uses [serialport](https://github.com/EmergingTechnologyAdvisors/node-serialport), which compiles to binary. You might need to install some prerequesites depending on your operating system. 19 | 20 | ## Prerequisites 21 | Make sure prior to trying to push a project to your device, you flash the device with the Espruino Runtime with [Flasher.js](https://github.com/thingsSDK/flasher.js/releases). 22 | 23 | ## Usage 24 | 25 | Plug your device in first and make sure you have the necessary drivers installed. 26 | 27 | ### New Project 28 | 29 | Next to create a new project use the `new` command like so: 30 | 31 | ```bash 32 | $ thingssdk new path/to/project_name 33 | ``` 34 | 35 | You'll be prompted to enter plug your device in if you haven't already and then select the device's serial port and baud rate. 36 | 37 | If you know your device's port and baud rate already, use the `port` and `baud_rate` options: 38 | 39 | ```bash 40 | $ thingssdk new path/to/project_name --port=COM3 --baud_rate=115200 41 | ``` 42 | 43 | ### Getting Started with Your New Project 44 | 45 | Your new project will now be found at `path/to/project_name`. You'll need to then install the dependencies. 46 | 47 | ```bash 48 | $ npm install 49 | ``` 50 | 51 | `dependencies` in the new project `package.json` should be deployed to the device, `devDependancies` are what are used for your development workflow. 52 | 53 | A `devices.json` file is created in the root of your new project. An entry is placed in your `.gitignore` because serial ports from computer to computer and developer to developer will differ. 54 | 55 | ### Deploying it to Your Device 56 | 57 | To run the "Hello, world" sample project to your device(s) run the npm script `dev`. 58 | 59 | ```bash 60 | $ npm run dev 61 | ``` 62 | 63 | An interactive REPL will launch and you can interact with your code and debug your program. Once you're happy you can use `delpoy` to upload and __save__ your code to the device. 64 | 65 | ```bash 66 | $ npm run deploy 67 | ``` 68 | 69 | The "Hello, world" script can be found in `main.js`. This script gets uploaded to your device and blinks the blue LED on the `ESP8266` board. It uses the `devices.json` file to know which devices to deploy the code to. 70 | 71 | Your JavaScript program must implement a `main` function in order to be ran when the board is initialized. 72 | 73 | ### Creating a `devices.json` file 74 | 75 | To overwrite the current devices.json or create a new devices.json file in your project directory run the following command for an interactive prompt: 76 | 77 | ```bash 78 | $ thingssdk devices 79 | ``` 80 | 81 | Or with the flags `port` and `baud_rate` if you know them already. 82 | 83 | ``` 84 | $ thingssdk devices --port=COM3 --baud_rate=115200 85 | ``` 86 | 87 | This will generate a `devices.json` like this: 88 | 89 | ```javascript 90 | { 91 | "devices": { 92 | "COM3": { 93 | "baud_rate": 115200, 94 | "runtime": "espruino" 95 | } 96 | } 97 | } 98 | ``` 99 | 100 | ### Warning for Unix users: ~/ 101 | Due to cross-platform compatibility issues, `~` does not resolve to your home directory on Unix systems. For example, suppose: 102 | 103 | ```bash 104 | $ pwd 105 | /home//some/subdirectory 106 | ``` 107 | 108 | Running 109 | ```bash 110 | $ thingssdk new ~/path/to/project_name 111 | ``` 112 | 113 | Would produce the following result: 114 | 115 | ```bash 116 | $ ls ~/path/to/project_name 117 | ls: cannot access '/home//path/to/project_name': No such file or directory 118 | 119 | $ ls ~/some/subdirectory/~/path/to/project_name 120 | main.js package.json scripts 121 | ``` 122 | 123 | This is probably not your intended behavior! So `thingssdk` throws an Error for paths beginning with `~`, and a warning for paths containing `~` elsewhere. 124 | -------------------------------------------------------------------------------- /bin/thingssdk.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | const cliPackage = require("../package.json"); 5 | 6 | const argv = require("yargs") 7 | .version(cliPackage.version) 8 | .commandDir('../lib/commands') 9 | .option("runtime", { 10 | alias: "r", 11 | describe: "Runtime for the device", 12 | }) 13 | .option("baud_rate", { 14 | alias: "b", 15 | describe: "Baud rate for the device" 16 | }) 17 | .option("port", { 18 | alias: "p", 19 | describe: "Serial port for the device" 20 | }) 21 | .demand(1) 22 | .strict() 23 | .help() 24 | .argv; 25 | -------------------------------------------------------------------------------- /lib/commands/devices.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const {createDevicesJSON} = require('../devices'); 4 | const colors = require('../core/colors-theme'); 5 | const {onError, onFinish} = require('../core/cli-helpers'); 6 | 7 | /** 8 | * Yargs required exports 9 | */ 10 | 11 | exports.command = "devices"; 12 | 13 | exports.describe = 'create a devices.json in current directory'; 14 | 15 | exports.builder = { 16 | runtime: { 17 | default: "espruino" 18 | } 19 | }; 20 | 21 | exports.handler = function(argv)  { 22 | const {port, baud_rate, runtime, destinationPath} = argv; 23 | const deviceJSONOptions = { port, baud_rate, runtime, destinationPath: process.cwd() }; 24 | createDevicesJSON(deviceJSONOptions).then(onFinish("devices.json successfully created")).catch(onError); 25 | }; -------------------------------------------------------------------------------- /lib/commands/new.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const {createApplication} = require('../new'); 4 | const colors = require('../core/colors-theme'); 5 | const {onError, onFinish} = require('../core/cli-helpers'); 6 | 7 | /** 8 | * Yargs required exports 9 | */ 10 | 11 | exports.command = "new "; 12 | 13 | exports.describe = 'create an applicaiton at a given path'; 14 | 15 | exports.builder = { 16 | runtime: { 17 | default: "espruino" 18 | } 19 | }; 20 | 21 | exports.handler = function (argv) { 22 | createApplication(argv).then(onFinish('Project successfully created')).catch(onError); 23 | }; -------------------------------------------------------------------------------- /lib/core/cli-helpers.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const colors = require('../core/colors-theme'); 3 | 4 | /** 5 | * CLI based functions only 6 | */ 7 | 8 | const readLine = require("readline").createInterface({ 9 | input: process.stdin, 10 | output: process.stdout 11 | }); 12 | 13 | 14 | function askQuestion(question) { 15 | return new Promise((resolve, reject) => { 16 | readLine.question(question, answer => { 17 | readLine.close(); 18 | resolve(answer); 19 | }); 20 | }); 21 | } 22 | 23 | function clearLine() { 24 | const CLEAR_LINE = new Buffer('1b5b304b', 'hex').toString(); 25 | const MOVE_LEFT = new Buffer('1b5b3130303044', 'hex').toString(); 26 | process.stdout.write(MOVE_LEFT + CLEAR_LINE); 27 | process.stdout.write(""); 28 | } 29 | 30 | function printLoading(message, loadingChar, count) { 31 | let i = 0; 32 | let interval = setInterval(() => { 33 | if (i === 0) { 34 | process.stdout.write(message); 35 | } 36 | process.stdout.write(loadingChar); 37 | if (i > count) { 38 | clearLine(); 39 | process.stdout.write(message); 40 | i = 0; 41 | } 42 | i++; 43 | }, 400); 44 | return () => { 45 | clearInterval(interval); 46 | clearLine(); 47 | }; 48 | } 49 | 50 | function cleanAnswer(answer) { 51 | return answer.toLowerCase().trim().charAt(0); 52 | } 53 | 54 | function shouldOverwrite(destinationPath) { 55 | const question = `Files already exist at ${destinationPath}.\nWould you like to overwrite the existing files?\nType y or n: `; 56 | 57 | return askQuestion(question) 58 | .then(cleanAnswer) 59 | .then(answer => { 60 | if (answer === 'y') { 61 | console.log(colors.info("You answered yes. Overwriting existing project files.")); 62 | return true; 63 | } 64 | else if (answer === 'n') { 65 | console.log(colors.warn("No project files were changed. Aborting new project creation.")); 66 | return false; 67 | } 68 | else { 69 | throw "I don't understand your input. No project files were changed. Aborting new project creation."; 70 | } 71 | }); 72 | } 73 | 74 | function onError(err) { 75 | console.error(colors.error(err)); 76 | process.exit(1); 77 | } 78 | 79 | function onFinish(message) { 80 | return () => { 81 | console.log(colors.info(message)); 82 | process.exit(0); 83 | }; 84 | } 85 | 86 | module.exports = { 87 | shouldOverwrite, 88 | printLoading, 89 | onError, 90 | onFinish 91 | }; -------------------------------------------------------------------------------- /lib/core/colors-theme.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const colors = require("colors"); 4 | colors.setTheme({ 5 | info: "green", 6 | help: "cyan", 7 | warn: "yellow", 8 | debug: "blue", 9 | error: "red" 10 | }); 11 | 12 | module.exports = colors; -------------------------------------------------------------------------------- /lib/core/file.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const fs = require("fs"); 3 | 4 | const NO_SUCH_FILE_OR_DIRECTORY_ERROR_CODE = 'ENOENT'; 5 | 6 | function write(path, contents) { 7 | fs.writeFileSync(path, contents); 8 | } 9 | 10 | function copy(from, to) { 11 | write(to, fs.readFileSync(from)); 12 | } 13 | 14 | function isDirectoryEmpty(path) { 15 | return new Promise((resolve, reject) => { 16 | fs.readdir(path, (err, files) => { 17 | /* istanbul ignore if */ 18 | if (err && err.code !== NO_SUCH_FILE_OR_DIRECTORY_ERROR_CODE) { 19 | reject(err); 20 | } else { 21 | const noFilesPresent = !files || !files.length; 22 | resolve(noFilesPresent, path); 23 | } 24 | }); 25 | }); 26 | } 27 | 28 | module.exports = { 29 | write, 30 | copy, 31 | isDirectoryEmpty 32 | }; -------------------------------------------------------------------------------- /lib/core/ports.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const serialport = require("serialport"); 4 | const {printLoading} = require('./cli-helpers'); 5 | 6 | function getPorts() { 7 | let clearDevicePrompt; 8 | return new Promise( 9 | (resolve, reject) => { 10 | function portResolver(err, ports) { 11 | if (err) reject(err); 12 | const portNames = ports.map((port) => port.comName); 13 | if (portNames.length > 0) { 14 | if (clearDevicePrompt) clearDevicePrompt(); 15 | resolve(portNames); 16 | } else { 17 | clearDevicePrompt = clearDevicePrompt || printLoading("Plug your device in", ".", 3); 18 | serialport.list(portResolver); 19 | } 20 | } 21 | serialport.list(portResolver); 22 | }); 23 | } 24 | 25 | module.exports = { 26 | getPorts 27 | }; -------------------------------------------------------------------------------- /lib/devices.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const inquirer = require("inquirer"); 3 | const path = require("path"); 4 | const {write} = require('./core/file'); 5 | const {getPorts} = require('./core/ports'); 6 | 7 | /** 8 | * @name devicesObject 9 | * 10 | * @description 11 | * Helper function ran to ask user for Port 12 | * 13 | * @param {String} port 14 | * @param {String} baud_rate 15 | * @param {String} runtime The proper key for runtime + version 16 | * 17 | * @returns {object} device configuration object 18 | * 19 | * @example 20 | * ```js 21 | * { 22 | * "devices": { 23 | * "/dev/cu.SLAB_USBtoUART": { 24 | * "baud_rate": 115200, 25 | * "runtime": "espruino" 26 | * } 27 | * } 28 | * } 29 | * ``` 30 | */ 31 | function devicesObject(port, baud_rate, runtime) { 32 | baud_rate = parseInt(baud_rate); 33 | const devices = {}; 34 | devices[port] = { baud_rate, runtime }; 35 | return { devices }; 36 | } 37 | 38 | /** 39 | * @name askForPort 40 | * @requires getPorts 41 | * 42 | * @description 43 | * Helper function ran to ask user for Port 44 | * 45 | * @param {object} answers partial device configuration object 46 | * 47 | * @returns {object} partial device configuration object with port property 48 | * defined. 49 | */ 50 | function askForPort(answers) { 51 | return getPorts().then((ports) => { 52 | const portQuestion = [ 53 | { 54 | type: 'list', 55 | name: 'port', 56 | message: 'Select a port:', 57 | choices: ports, 58 | default: ports[0] 59 | } 60 | ]; 61 | return inquirer 62 | .prompt(portQuestion) 63 | .then(promptAnswers => Object.assign({},answers,promptAnswers)) 64 | }); 65 | } 66 | 67 | /** 68 | * @name askForBaudRate 69 | * 70 | * @description 71 | * Helper function ran to ask user for baud rate 72 | * 73 | * @param {object} answers partial device configuration object 74 | * 75 | * @returns {object} partial device configuration object with baud_rate property 76 | * defined. 77 | */ 78 | function askForBaudRate(answers) { 79 | const baudRateQuestion = [ 80 | { 81 | type: 'list', 82 | name: 'baud_rate', 83 | message: 'Select the baud rate:', 84 | choices: ['9600', '115200'], 85 | default: '115200' 86 | } 87 | ]; 88 | return inquirer 89 | .prompt(baudRateQuestion) 90 | .then(promptAnswers => Object.assign({},answers,promptAnswers)) 91 | } 92 | 93 | /** 94 | * @name askUserForPortAndBaudRate 95 | * 96 | * @description 97 | * Helper function ran to ask user for both port and baud rate, then 98 | * return the devices configuration object. 99 | * 100 | * @param {String} runtime The proper key for runtime + version 101 | * 102 | * @returns {object} complete device configuration object 103 | */ 104 | function askUserForPortAndBaudRate(runtime) { 105 | const answers = {}; 106 | return askForPort() 107 | .then(answers => { 108 | return askForBaudRate(answers); 109 | }) 110 | .then(answers => { 111 | return devicesObject(answers.port, answers.baud_rate, runtime); 112 | }); 113 | } 114 | 115 | /** 116 | * @name createDevicesJSON 117 | * @requires askUserForPortAndBaudRate 118 | * @requires askForPort 119 | * @requires askForBaudRate 120 | * @requires devicesObject 121 | * @requires write 122 | * 123 | * @description 124 | * Asks the user for any unspecified configuration details, then 125 | * writes the configuration to the devices.json file in the IoT project 126 | * 127 | * @param {Object} options The four configuration options passed to the yargs 128 | * command line. 129 | * 130 | * ```js options = { 131 | * port, 132 | * baud_rate, 133 | * path, 134 | * runtime 135 | * } 136 | * ``` 137 | */ 138 | function createDevicesJSON(options) { 139 | const {port, baud_rate, runtime, destinationPath} = options; 140 | let devicePromise; 141 | 142 | if (typeof port === 'undefined' && typeof baud_rate === 'undefined') { 143 | devicePromise = askUserForPortAndBaudRate(runtime); 144 | } 145 | else if(typeof port === 'undefined') { 146 | devicePromise = askForPort({}).then(answers => devicesObject(answers.port, baud_rate, runtime)); 147 | } 148 | else if(typeof baud_rate === 'undefined') { 149 | devicePromise = askForBaudRate({}).then(answers => devicesObject(port, answers.baud_rate, runtime)); 150 | } else { 151 | devicePromise = new Promise((resolve) => { 152 | resolve(devicesObject(port, baud_rate, runtime)); 153 | }); 154 | } 155 | 156 | return devicePromise.then(devices => { 157 | write(path.join(destinationPath, "devices.json"), JSON.stringify(devices, null, 2)); 158 | }); 159 | } 160 | 161 | module.exports = { 162 | createDevicesJSON 163 | }; 164 | -------------------------------------------------------------------------------- /lib/new.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const path = require("path"); 3 | const fs = require("fs"); 4 | const mkdirp = require("mkdirp"); 5 | 6 | const {createDevicesJSON} = require('./devices'); 7 | const {write, copy, isDirectoryEmpty} = require('./core/file'); 8 | const colors = require('./core/colors-theme'); 9 | const {shouldOverwrite} = require('./core/cli-helpers'); 10 | 11 | /** 12 | * @name checkForTilde 13 | * 14 | * @description 15 | * Helper function to check the destination path and display any needed warnings 16 | * 17 | * @param {String} destinationPath 18 | * @throws {Error} Bad Path 19 | */ 20 | function checkForTilde(destinationPath) { 21 | /** 22 | If the first part of the path contains a ~, 23 | we'll assume the user intends for their project to install 24 | relative to their home directory on a Unix machine and throw an error. 25 | */ 26 | if (destinationPath.split('/')[0].includes('~')) { 27 | console.log(colors.error(` 28 | Uh-oh, check your desired project path! 29 | It looks like you made a reference to your home directory: ~/ 30 | Due to cross platform compatibility with non-Unix systems, that causes some problems. 31 | Try again using absolute paths like /Users//path/to/project 32 | `)); 33 | throw new Error(`Bad path, we're sorry...`); 34 | } 35 | 36 | /** 37 | If any other part of the path contains a ~, 38 | we'll just give them a helpful warning. 39 | */ 40 | if (destinationPath.includes('~')) { 41 | console.log(colors.warn(` 42 | Be careful, it looks like your project path contains a "~". 43 | If you remove this directory, be very careful about running "rm -rf \\~" 44 | You could accidentally destroy your home directory! 45 | `)); 46 | } 47 | } 48 | 49 | /** 50 | * @name createApplication 51 | * @requires isDirectoryEmpty 52 | * @requires shouldOverwrite 53 | * @requires createFiles 54 | * @requires projectCreated 55 | * 56 | * @description 57 | * Checks if the desired project folder is empty, then creates the project files 58 | * if it is, then displays basic instructions after project has been successfully 59 | * created. 60 | * 61 | * @param {Object} options The four configuration options passed to the yargs 62 | * command line. 63 | * 64 | * ```js options = { 65 | * port, 66 | * baud_rate, 67 | * path, 68 | * runtime 69 | * } 70 | * ``` 71 | */ 72 | function createApplication(options) { 73 | const {path: destinationPath, runtime} = options; 74 | return isDirectoryEmpty(destinationPath) 75 | .then(isEmpty => { 76 | if (isEmpty) { 77 | return true; 78 | } else { 79 | return shouldOverwrite(destinationPath); 80 | } 81 | }) 82 | .then(proceed => { 83 | if (proceed) { 84 | return createFiles(options).then(() => { 85 | projectCreated(destinationPath); 86 | }); 87 | } 88 | }); 89 | } 90 | 91 | /** 92 | * @name projectCreated 93 | * 94 | * @description 95 | * Helper function to display instructions after project is successfully created 96 | * 97 | * @param {String} destinationPath 98 | */ 99 | function projectCreated(destinationPath) { 100 | const successMessage = `To install the project dependencies: 101 | cd ${destinationPath} && npm install 102 | To upload to your device: 103 | Development: 104 | npm run dev 105 | Production: 106 | npm run deploy`; 107 | 108 | console.log(colors.help(successMessage)); 109 | } 110 | 111 | /** 112 | * @name makeDirectory 113 | * 114 | * @description 115 | * Helper function to promisify mkdir 116 | * 117 | * @param {String} directory The name of the desired new directory 118 | */ 119 | function makeDirectory(directory) { 120 | return new Promise((resolve, reject) => { 121 | mkdirp(directory, err => { 122 | if (err) reject(err); 123 | else resolve(); 124 | }); 125 | }); 126 | } 127 | 128 | /** 129 | * @name createFiles 130 | * @requires checkForTilde 131 | * @requires makeDirectory 132 | * @requires createPackageJSON 133 | * @requires createDevicesJSON 134 | * 135 | * @description 136 | * Selects the correct template files for the IoT project, creates the new project 137 | * folder, and copies the template files into the new project folder. Configures 138 | * and writes the package.json and devices.json files. 139 | * 140 | * @param {Object} options The four configuration options passed to the yargs 141 | * command line. 142 | * 143 | * ```js options = { 144 | * port, 145 | * baud_rate, 146 | * path, 147 | * runtime 148 | * } 149 | * ``` 150 | */ 151 | function createFiles(options) { 152 | const {port, baud_rate, path: destinationPath, runtime} = options; 153 | const app_name = path.basename(path.resolve(destinationPath)); 154 | const templatesPath = path.join(__dirname, "..", "templates"); 155 | const scriptPath = path.join(templatesPath, runtime, "scripts"); 156 | 157 | checkForTilde(destinationPath); 158 | 159 | return makeDirectory(path.join(destinationPath, 'scripts')) 160 | .then(() => makeDirectory(path.join(destinationPath, 'build'))) 161 | .then(() => { 162 | /* Copy templates */ 163 | fs.readdir(scriptPath, (err, files) => { 164 | if (err) throw err; 165 | files.forEach(file => copy(path.join(scriptPath, file), path.join(destinationPath, "scripts", file))); 166 | }); 167 | 168 | /* Create package.json for project */ 169 | const pkg = createPackageJSON(app_name, runtime); 170 | write(path.join(destinationPath, "package.json"), JSON.stringify(pkg, null, 2)); 171 | copy(path.join(templatesPath, 'main.js'), path.join(destinationPath, 'main.js')); 172 | copy(path.join(templatesPath, 'dot-gitignore'), path.join(destinationPath, '.gitignore')); 173 | copy(path.join(templatesPath, 'dot-gitattributes'), path.join(destinationPath, '.gitattributes')); 174 | 175 | /* Create devices.json and finish */ 176 | const deviceJSONOptions = { port, baud_rate, runtime, destinationPath }; 177 | return createDevicesJSON(deviceJSONOptions); 178 | }); 179 | } 180 | 181 | /** 182 | * @name createPackageJSON 183 | * 184 | * @description 185 | * Returns the package.json object for the IoT project 186 | * 187 | * @param {String} app_name The name for the IoT project 188 | * @param {String} runtime Key string asociated with the required runtime env 189 | * desired from the RUNTIMES object. 190 | * 191 | * @returns {Object} The package.json object for the new project 192 | */ 193 | function createPackageJSON(app_name, runtime) { 194 | const strategy = `thingssdk-${runtime}-strategy`; 195 | const strategyVersions = { 196 | espruino: "~1.0.3" 197 | }; 198 | const pkg = { 199 | name: app_name, 200 | version: '0.0.0', 201 | private: true, 202 | main: 'main.js', 203 | scripts: { 204 | dev: "node ./scripts/upload development && npm run repl", 205 | deploy: "node ./scripts/upload production", 206 | repl: "node ./scripts/repl", 207 | postinstall: "rimraf node_modules/bluetooth-hci-socket" 208 | }, 209 | devDependencies: { 210 | "thingssdk-deployer": "~1.0.1", 211 | [strategy]: strategyVersions[runtime] 212 | } 213 | }; 214 | 215 | return pkg; 216 | } 217 | 218 | module.exports = { 219 | createApplication 220 | }; 221 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "thingssdk-cli", 3 | "version": "1.3.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "abbrev": { 8 | "version": "1.0.9", 9 | "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", 10 | "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", 11 | "dev": true 12 | }, 13 | "align-text": { 14 | "version": "0.1.4", 15 | "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", 16 | "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", 17 | "dev": true, 18 | "requires": { 19 | "kind-of": "3.2.2", 20 | "longest": "1.0.1", 21 | "repeat-string": "1.6.1" 22 | } 23 | }, 24 | "amdefine": { 25 | "version": "1.0.1", 26 | "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", 27 | "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", 28 | "dev": true 29 | }, 30 | "ansi-bgblack": { 31 | "version": "0.1.1", 32 | "resolved": "https://registry.npmjs.org/ansi-bgblack/-/ansi-bgblack-0.1.1.tgz", 33 | "integrity": "sha1-poulAHiHcBtqr74/oNrf36juPKI=", 34 | "requires": { 35 | "ansi-wrap": "0.1.0" 36 | } 37 | }, 38 | "ansi-bgblue": { 39 | "version": "0.1.1", 40 | "resolved": "https://registry.npmjs.org/ansi-bgblue/-/ansi-bgblue-0.1.1.tgz", 41 | "integrity": "sha1-Z73ATtybm1J4lp2hlt6j11yMNhM=", 42 | "requires": { 43 | "ansi-wrap": "0.1.0" 44 | } 45 | }, 46 | "ansi-bgcyan": { 47 | "version": "0.1.1", 48 | "resolved": "https://registry.npmjs.org/ansi-bgcyan/-/ansi-bgcyan-0.1.1.tgz", 49 | "integrity": "sha1-WEiUJWAL3p9VBwaN2Wnr/bUP52g=", 50 | "requires": { 51 | "ansi-wrap": "0.1.0" 52 | } 53 | }, 54 | "ansi-bggreen": { 55 | "version": "0.1.1", 56 | "resolved": "https://registry.npmjs.org/ansi-bggreen/-/ansi-bggreen-0.1.1.tgz", 57 | "integrity": "sha1-TjGRJIUplD9DIelr8THRwTgWr0k=", 58 | "requires": { 59 | "ansi-wrap": "0.1.0" 60 | } 61 | }, 62 | "ansi-bgmagenta": { 63 | "version": "0.1.1", 64 | "resolved": "https://registry.npmjs.org/ansi-bgmagenta/-/ansi-bgmagenta-0.1.1.tgz", 65 | "integrity": "sha1-myhDLAduqpmUGGcqPvvhk5HCx6E=", 66 | "requires": { 67 | "ansi-wrap": "0.1.0" 68 | } 69 | }, 70 | "ansi-bgred": { 71 | "version": "0.1.1", 72 | "resolved": "https://registry.npmjs.org/ansi-bgred/-/ansi-bgred-0.1.1.tgz", 73 | "integrity": "sha1-p2+Sg4OCukMpCmwXeEJPmE1vEEE=", 74 | "requires": { 75 | "ansi-wrap": "0.1.0" 76 | } 77 | }, 78 | "ansi-bgwhite": { 79 | "version": "0.1.1", 80 | "resolved": "https://registry.npmjs.org/ansi-bgwhite/-/ansi-bgwhite-0.1.1.tgz", 81 | "integrity": "sha1-ZQRlE3elim7OzQMxmU5IAljhG6g=", 82 | "requires": { 83 | "ansi-wrap": "0.1.0" 84 | } 85 | }, 86 | "ansi-bgyellow": { 87 | "version": "0.1.1", 88 | "resolved": "https://registry.npmjs.org/ansi-bgyellow/-/ansi-bgyellow-0.1.1.tgz", 89 | "integrity": "sha1-w/4usIzUdmSAKeaHTRWgs49h1E8=", 90 | "requires": { 91 | "ansi-wrap": "0.1.0" 92 | } 93 | }, 94 | "ansi-black": { 95 | "version": "0.1.1", 96 | "resolved": "https://registry.npmjs.org/ansi-black/-/ansi-black-0.1.1.tgz", 97 | "integrity": "sha1-9hheiJNgslRaHsUMC/Bj/EMDJFM=", 98 | "requires": { 99 | "ansi-wrap": "0.1.0" 100 | } 101 | }, 102 | "ansi-blue": { 103 | "version": "0.1.1", 104 | "resolved": "https://registry.npmjs.org/ansi-blue/-/ansi-blue-0.1.1.tgz", 105 | "integrity": "sha1-FbgEmQ6S/JyoxUds6PaZd3wh7b8=", 106 | "requires": { 107 | "ansi-wrap": "0.1.0" 108 | } 109 | }, 110 | "ansi-bold": { 111 | "version": "0.1.1", 112 | "resolved": "https://registry.npmjs.org/ansi-bold/-/ansi-bold-0.1.1.tgz", 113 | "integrity": "sha1-PmOVCvWswq4uZw5vZ96xFdGl9QU=", 114 | "requires": { 115 | "ansi-wrap": "0.1.0" 116 | } 117 | }, 118 | "ansi-colors": { 119 | "version": "0.2.0", 120 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-0.2.0.tgz", 121 | "integrity": "sha1-csMd4qDZoszQysMMyYI+6y9kNLU=", 122 | "requires": { 123 | "ansi-bgblack": "0.1.1", 124 | "ansi-bgblue": "0.1.1", 125 | "ansi-bgcyan": "0.1.1", 126 | "ansi-bggreen": "0.1.1", 127 | "ansi-bgmagenta": "0.1.1", 128 | "ansi-bgred": "0.1.1", 129 | "ansi-bgwhite": "0.1.1", 130 | "ansi-bgyellow": "0.1.1", 131 | "ansi-black": "0.1.1", 132 | "ansi-blue": "0.1.1", 133 | "ansi-bold": "0.1.1", 134 | "ansi-cyan": "0.1.1", 135 | "ansi-dim": "0.1.1", 136 | "ansi-gray": "0.1.1", 137 | "ansi-green": "0.1.1", 138 | "ansi-grey": "0.1.1", 139 | "ansi-hidden": "0.1.1", 140 | "ansi-inverse": "0.1.1", 141 | "ansi-italic": "0.1.1", 142 | "ansi-magenta": "0.1.1", 143 | "ansi-red": "0.1.1", 144 | "ansi-reset": "0.1.1", 145 | "ansi-strikethrough": "0.1.1", 146 | "ansi-underline": "0.1.1", 147 | "ansi-white": "0.1.1", 148 | "ansi-yellow": "0.1.1", 149 | "lazy-cache": "2.0.2" 150 | }, 151 | "dependencies": { 152 | "lazy-cache": { 153 | "version": "2.0.2", 154 | "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", 155 | "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=", 156 | "requires": { 157 | "set-getter": "0.1.0" 158 | } 159 | } 160 | } 161 | }, 162 | "ansi-cyan": { 163 | "version": "0.1.1", 164 | "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", 165 | "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", 166 | "requires": { 167 | "ansi-wrap": "0.1.0" 168 | } 169 | }, 170 | "ansi-dim": { 171 | "version": "0.1.1", 172 | "resolved": "https://registry.npmjs.org/ansi-dim/-/ansi-dim-0.1.1.tgz", 173 | "integrity": "sha1-QN5MYDqoCG2Oeoa4/5mNXDbu/Ww=", 174 | "requires": { 175 | "ansi-wrap": "0.1.0" 176 | } 177 | }, 178 | "ansi-gray": { 179 | "version": "0.1.1", 180 | "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", 181 | "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", 182 | "requires": { 183 | "ansi-wrap": "0.1.0" 184 | } 185 | }, 186 | "ansi-green": { 187 | "version": "0.1.1", 188 | "resolved": "https://registry.npmjs.org/ansi-green/-/ansi-green-0.1.1.tgz", 189 | "integrity": "sha1-il2al55FjVfEDjNYCzc5C44Q0Pc=", 190 | "requires": { 191 | "ansi-wrap": "0.1.0" 192 | } 193 | }, 194 | "ansi-grey": { 195 | "version": "0.1.1", 196 | "resolved": "https://registry.npmjs.org/ansi-grey/-/ansi-grey-0.1.1.tgz", 197 | "integrity": "sha1-WdmLasK6GfilF5jphT+6eDOaM8E=", 198 | "requires": { 199 | "ansi-wrap": "0.1.0" 200 | } 201 | }, 202 | "ansi-hidden": { 203 | "version": "0.1.1", 204 | "resolved": "https://registry.npmjs.org/ansi-hidden/-/ansi-hidden-0.1.1.tgz", 205 | "integrity": "sha1-7WpMSY0rt8uyidvyqNHcyFZ/rg8=", 206 | "requires": { 207 | "ansi-wrap": "0.1.0" 208 | } 209 | }, 210 | "ansi-inverse": { 211 | "version": "0.1.1", 212 | "resolved": "https://registry.npmjs.org/ansi-inverse/-/ansi-inverse-0.1.1.tgz", 213 | "integrity": "sha1-tq9Fgm/oJr+1KKbHmIV5Q1XM0mk=", 214 | "requires": { 215 | "ansi-wrap": "0.1.0" 216 | } 217 | }, 218 | "ansi-italic": { 219 | "version": "0.1.1", 220 | "resolved": "https://registry.npmjs.org/ansi-italic/-/ansi-italic-0.1.1.tgz", 221 | "integrity": "sha1-EEdDRj9iXBQqA2c5z4XtpoiYbyM=", 222 | "requires": { 223 | "ansi-wrap": "0.1.0" 224 | } 225 | }, 226 | "ansi-magenta": { 227 | "version": "0.1.1", 228 | "resolved": "https://registry.npmjs.org/ansi-magenta/-/ansi-magenta-0.1.1.tgz", 229 | "integrity": "sha1-BjtboW+z8j4c/aKwfAqJ3hHkMK4=", 230 | "requires": { 231 | "ansi-wrap": "0.1.0" 232 | } 233 | }, 234 | "ansi-red": { 235 | "version": "0.1.1", 236 | "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", 237 | "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", 238 | "requires": { 239 | "ansi-wrap": "0.1.0" 240 | } 241 | }, 242 | "ansi-regex": { 243 | "version": "2.1.1", 244 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 245 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" 246 | }, 247 | "ansi-reset": { 248 | "version": "0.1.1", 249 | "resolved": "https://registry.npmjs.org/ansi-reset/-/ansi-reset-0.1.1.tgz", 250 | "integrity": "sha1-5+cSksPH3c1NYu9KbHwFmAkRw7c=", 251 | "requires": { 252 | "ansi-wrap": "0.1.0" 253 | } 254 | }, 255 | "ansi-strikethrough": { 256 | "version": "0.1.1", 257 | "resolved": "https://registry.npmjs.org/ansi-strikethrough/-/ansi-strikethrough-0.1.1.tgz", 258 | "integrity": "sha1-2Eh3FAss/wfRyT685pkE9oiF5Wg=", 259 | "requires": { 260 | "ansi-wrap": "0.1.0" 261 | } 262 | }, 263 | "ansi-underline": { 264 | "version": "0.1.1", 265 | "resolved": "https://registry.npmjs.org/ansi-underline/-/ansi-underline-0.1.1.tgz", 266 | "integrity": "sha1-38kg9Ml7WXfqFi34/7mIMIqqcaQ=", 267 | "requires": { 268 | "ansi-wrap": "0.1.0" 269 | } 270 | }, 271 | "ansi-white": { 272 | "version": "0.1.1", 273 | "resolved": "https://registry.npmjs.org/ansi-white/-/ansi-white-0.1.1.tgz", 274 | "integrity": "sha1-nHe3wZPF7pkuYBHTbsTJIbRXiUQ=", 275 | "requires": { 276 | "ansi-wrap": "0.1.0" 277 | } 278 | }, 279 | "ansi-wrap": { 280 | "version": "0.1.0", 281 | "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", 282 | "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=" 283 | }, 284 | "ansi-yellow": { 285 | "version": "0.1.1", 286 | "resolved": "https://registry.npmjs.org/ansi-yellow/-/ansi-yellow-0.1.1.tgz", 287 | "integrity": "sha1-y5NW8vRscy8OMZnmEClVp32oPB0=", 288 | "requires": { 289 | "ansi-wrap": "0.1.0" 290 | } 291 | }, 292 | "aproba": { 293 | "version": "1.2.0", 294 | "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", 295 | "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" 296 | }, 297 | "are-we-there-yet": { 298 | "version": "1.1.4", 299 | "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", 300 | "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", 301 | "requires": { 302 | "delegates": "1.0.0", 303 | "readable-stream": "2.3.6" 304 | } 305 | }, 306 | "argparse": { 307 | "version": "1.0.9", 308 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", 309 | "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", 310 | "dev": true, 311 | "requires": { 312 | "sprintf-js": "1.0.3" 313 | } 314 | }, 315 | "arr-flatten": { 316 | "version": "1.1.0", 317 | "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", 318 | "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==" 319 | }, 320 | "arr-swap": { 321 | "version": "1.0.1", 322 | "resolved": "https://registry.npmjs.org/arr-swap/-/arr-swap-1.0.1.tgz", 323 | "integrity": "sha1-FHWQ7WX8gVvAf+8Jl8Llgj1kNTQ=", 324 | "requires": { 325 | "is-number": "3.0.0" 326 | } 327 | }, 328 | "assertion-error": { 329 | "version": "1.0.2", 330 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", 331 | "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", 332 | "dev": true 333 | }, 334 | "assign-symbols": { 335 | "version": "1.0.0", 336 | "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", 337 | "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" 338 | }, 339 | "async": { 340 | "version": "1.5.2", 341 | "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", 342 | "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", 343 | "dev": true 344 | }, 345 | "balanced-match": { 346 | "version": "0.4.2", 347 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", 348 | "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", 349 | "dev": true 350 | }, 351 | "bl": { 352 | "version": "1.2.2", 353 | "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", 354 | "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", 355 | "requires": { 356 | "readable-stream": "2.3.6", 357 | "safe-buffer": "5.1.1" 358 | } 359 | }, 360 | "brace-expansion": { 361 | "version": "1.1.7", 362 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", 363 | "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", 364 | "dev": true, 365 | "requires": { 366 | "balanced-match": "0.4.2", 367 | "concat-map": "0.0.1" 368 | } 369 | }, 370 | "camelcase": { 371 | "version": "4.1.0", 372 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", 373 | "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=" 374 | }, 375 | "center-align": { 376 | "version": "0.1.3", 377 | "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", 378 | "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", 379 | "dev": true, 380 | "optional": true, 381 | "requires": { 382 | "align-text": "0.1.4", 383 | "lazy-cache": "1.0.4" 384 | } 385 | }, 386 | "chai": { 387 | "version": "4.1.2", 388 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", 389 | "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", 390 | "dev": true, 391 | "requires": { 392 | "assertion-error": "1.0.2", 393 | "check-error": "1.0.2", 394 | "deep-eql": "3.0.1", 395 | "get-func-name": "2.0.0", 396 | "pathval": "1.1.0", 397 | "type-detect": "4.0.3" 398 | }, 399 | "dependencies": { 400 | "deep-eql": { 401 | "version": "3.0.1", 402 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", 403 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", 404 | "dev": true, 405 | "requires": { 406 | "type-detect": "4.0.3" 407 | } 408 | } 409 | } 410 | }, 411 | "chardet": { 412 | "version": "0.4.2", 413 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", 414 | "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=" 415 | }, 416 | "check-error": { 417 | "version": "1.0.2", 418 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", 419 | "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", 420 | "dev": true 421 | }, 422 | "choices-separator": { 423 | "version": "2.0.0", 424 | "resolved": "https://registry.npmjs.org/choices-separator/-/choices-separator-2.0.0.tgz", 425 | "integrity": "sha1-kv0XYxgteQM/XFxR0Lo1LlVnxpY=", 426 | "requires": { 427 | "ansi-dim": "0.1.1", 428 | "debug": "2.6.8", 429 | "strip-color": "0.1.0" 430 | } 431 | }, 432 | "chownr": { 433 | "version": "1.0.1", 434 | "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", 435 | "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=" 436 | }, 437 | "cli-cursor": { 438 | "version": "2.1.0", 439 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", 440 | "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", 441 | "requires": { 442 | "restore-cursor": "2.0.0" 443 | } 444 | }, 445 | "cli-width": { 446 | "version": "2.1.0", 447 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", 448 | "integrity": "sha1-sjTKIJsp72b8UY2bmNWEewDt8Ao=" 449 | }, 450 | "clone-deep": { 451 | "version": "1.0.0", 452 | "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-1.0.0.tgz", 453 | "integrity": "sha512-hmJRX8x1QOJVV+GUjOBzi6iauhPqc9hIF6xitWRBbiPZOBb6vGo/mDRIK9P74RTKSQK7AE8B0DDWY/vpRrPmQw==", 454 | "requires": { 455 | "for-own": "1.0.0", 456 | "is-plain-object": "2.0.4", 457 | "kind-of": "5.1.0", 458 | "shallow-clone": "1.0.0" 459 | }, 460 | "dependencies": { 461 | "kind-of": { 462 | "version": "5.1.0", 463 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", 464 | "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" 465 | } 466 | } 467 | }, 468 | "code-point-at": { 469 | "version": "1.1.0", 470 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 471 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" 472 | }, 473 | "collection-visit": { 474 | "version": "1.0.0", 475 | "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", 476 | "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", 477 | "requires": { 478 | "map-visit": "1.0.0", 479 | "object-visit": "1.0.1" 480 | } 481 | }, 482 | "color-convert": { 483 | "version": "1.9.1", 484 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", 485 | "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", 486 | "requires": { 487 | "color-name": "1.1.3" 488 | } 489 | }, 490 | "color-name": { 491 | "version": "1.1.3", 492 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 493 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 494 | }, 495 | "colors": { 496 | "version": "1.2.1", 497 | "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.1.tgz", 498 | "integrity": "sha512-s8+wktIuDSLffCywiwSxQOMqtPxML11a/dtHE17tMn4B1MSWw/C22EKf7M2KGUBcDaVFEGT+S8N02geDXeuNKg==" 499 | }, 500 | "component-emitter": { 501 | "version": "1.2.1", 502 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", 503 | "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" 504 | }, 505 | "concat-map": { 506 | "version": "0.0.1", 507 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 508 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 509 | "dev": true 510 | }, 511 | "console-control-strings": { 512 | "version": "1.1.0", 513 | "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", 514 | "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" 515 | }, 516 | "copy-descriptor": { 517 | "version": "0.1.1", 518 | "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", 519 | "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" 520 | }, 521 | "core-util-is": { 522 | "version": "1.0.2", 523 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 524 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 525 | }, 526 | "cross-spawn": { 527 | "version": "4.0.2", 528 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", 529 | "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", 530 | "requires": { 531 | "lru-cache": "4.0.2", 532 | "which": "1.2.14" 533 | } 534 | }, 535 | "debug": { 536 | "version": "2.6.8", 537 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", 538 | "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", 539 | "requires": { 540 | "ms": "2.0.0" 541 | } 542 | }, 543 | "decamelize": { 544 | "version": "1.2.0", 545 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 546 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" 547 | }, 548 | "decompress-response": { 549 | "version": "3.3.0", 550 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", 551 | "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", 552 | "requires": { 553 | "mimic-response": "1.0.0" 554 | } 555 | }, 556 | "deep-extend": { 557 | "version": "0.4.2", 558 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", 559 | "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=" 560 | }, 561 | "deep-is": { 562 | "version": "0.1.3", 563 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 564 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 565 | "dev": true 566 | }, 567 | "define-property": { 568 | "version": "1.0.0", 569 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", 570 | "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", 571 | "requires": { 572 | "is-descriptor": "1.0.2" 573 | } 574 | }, 575 | "delegates": { 576 | "version": "1.0.0", 577 | "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", 578 | "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" 579 | }, 580 | "detect-libc": { 581 | "version": "1.0.3", 582 | "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", 583 | "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" 584 | }, 585 | "end-of-stream": { 586 | "version": "1.4.1", 587 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", 588 | "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", 589 | "requires": { 590 | "once": "1.4.0" 591 | } 592 | }, 593 | "error-symbol": { 594 | "version": "0.1.0", 595 | "resolved": "https://registry.npmjs.org/error-symbol/-/error-symbol-0.1.0.tgz", 596 | "integrity": "sha1-Ck2uN9YA0VopukU9jvkg8YRDM/Y=" 597 | }, 598 | "escape-string-regexp": { 599 | "version": "1.0.5", 600 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 601 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 602 | }, 603 | "escodegen": { 604 | "version": "1.8.1", 605 | "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", 606 | "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", 607 | "dev": true, 608 | "requires": { 609 | "esprima": "2.7.3", 610 | "estraverse": "1.9.3", 611 | "esutils": "2.0.2", 612 | "optionator": "0.8.2", 613 | "source-map": "0.2.0" 614 | } 615 | }, 616 | "esprima": { 617 | "version": "2.7.3", 618 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", 619 | "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", 620 | "dev": true 621 | }, 622 | "estraverse": { 623 | "version": "1.9.3", 624 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", 625 | "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", 626 | "dev": true 627 | }, 628 | "esutils": { 629 | "version": "2.0.2", 630 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 631 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", 632 | "dev": true 633 | }, 634 | "execa": { 635 | "version": "0.5.1", 636 | "resolved": "https://registry.npmjs.org/execa/-/execa-0.5.1.tgz", 637 | "integrity": "sha1-3j+4XLjW6RyFvLzrFkWBeFy1ezY=", 638 | "requires": { 639 | "cross-spawn": "4.0.2", 640 | "get-stream": "2.3.1", 641 | "is-stream": "1.1.0", 642 | "npm-run-path": "2.0.2", 643 | "p-finally": "1.0.0", 644 | "signal-exit": "3.0.2", 645 | "strip-eof": "1.0.0" 646 | } 647 | }, 648 | "expand-template": { 649 | "version": "1.1.0", 650 | "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-1.1.0.tgz", 651 | "integrity": "sha512-kkjwkMqj0h4w/sb32ERCDxCQkREMCAgS39DscDnSwDsbxnwwM1BTZySdC3Bn1lhY7vL08n9GoO/fVTynjDgRyQ==" 652 | }, 653 | "extend-shallow": { 654 | "version": "2.0.1", 655 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", 656 | "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", 657 | "requires": { 658 | "is-extendable": "0.1.1" 659 | } 660 | }, 661 | "fast-levenshtein": { 662 | "version": "2.0.6", 663 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 664 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 665 | "dev": true 666 | }, 667 | "figures": { 668 | "version": "2.0.0", 669 | "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", 670 | "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", 671 | "requires": { 672 | "escape-string-regexp": "1.0.5" 673 | } 674 | }, 675 | "fill-keys": { 676 | "version": "1.0.2", 677 | "resolved": "https://registry.npmjs.org/fill-keys/-/fill-keys-1.0.2.tgz", 678 | "integrity": "sha1-mo+jb06K1jTjv2tPPIiCVRRS6yA=", 679 | "dev": true, 680 | "requires": { 681 | "is-object": "1.0.1", 682 | "merge-descriptors": "1.0.1" 683 | } 684 | }, 685 | "find-up": { 686 | "version": "2.1.0", 687 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", 688 | "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", 689 | "requires": { 690 | "locate-path": "2.0.0" 691 | } 692 | }, 693 | "for-in": { 694 | "version": "1.0.2", 695 | "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", 696 | "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=" 697 | }, 698 | "for-own": { 699 | "version": "1.0.0", 700 | "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", 701 | "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", 702 | "requires": { 703 | "for-in": "1.0.2" 704 | } 705 | }, 706 | "force-array": { 707 | "version": "3.1.0", 708 | "resolved": "https://registry.npmjs.org/force-array/-/force-array-3.1.0.tgz", 709 | "integrity": "sha1-oGD21BiNx9qm/lYt85rqq8pAR4Q=", 710 | "dev": true, 711 | "requires": { 712 | "is-array": "1.0.1" 713 | } 714 | }, 715 | "fs.realpath": { 716 | "version": "1.0.0", 717 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 718 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 719 | "dev": true 720 | }, 721 | "gauge": { 722 | "version": "2.7.4", 723 | "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", 724 | "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", 725 | "requires": { 726 | "aproba": "1.2.0", 727 | "console-control-strings": "1.1.0", 728 | "has-unicode": "2.0.1", 729 | "object-assign": "4.1.1", 730 | "signal-exit": "3.0.2", 731 | "string-width": "1.0.2", 732 | "strip-ansi": "3.0.1", 733 | "wide-align": "1.1.2" 734 | }, 735 | "dependencies": { 736 | "is-fullwidth-code-point": { 737 | "version": "1.0.0", 738 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 739 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 740 | "requires": { 741 | "number-is-nan": "1.0.1" 742 | } 743 | }, 744 | "string-width": { 745 | "version": "1.0.2", 746 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 747 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 748 | "requires": { 749 | "code-point-at": "1.1.0", 750 | "is-fullwidth-code-point": "1.0.0", 751 | "strip-ansi": "3.0.1" 752 | } 753 | } 754 | } 755 | }, 756 | "get-caller-file": { 757 | "version": "1.0.2", 758 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", 759 | "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=" 760 | }, 761 | "get-func-name": { 762 | "version": "2.0.0", 763 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", 764 | "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", 765 | "dev": true 766 | }, 767 | "get-stream": { 768 | "version": "2.3.1", 769 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", 770 | "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", 771 | "requires": { 772 | "object-assign": "4.1.1", 773 | "pinkie-promise": "2.0.1" 774 | } 775 | }, 776 | "github-from-package": { 777 | "version": "0.0.0", 778 | "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", 779 | "integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=" 780 | }, 781 | "glob": { 782 | "version": "5.0.15", 783 | "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", 784 | "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", 785 | "dev": true, 786 | "requires": { 787 | "inflight": "1.0.6", 788 | "inherits": "2.0.3", 789 | "minimatch": "3.0.4", 790 | "once": "1.4.0", 791 | "path-is-absolute": "1.0.1" 792 | } 793 | }, 794 | "handlebars": { 795 | "version": "4.0.10", 796 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz", 797 | "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=", 798 | "dev": true, 799 | "requires": { 800 | "async": "1.5.2", 801 | "optimist": "0.6.1", 802 | "source-map": "0.4.4", 803 | "uglify-js": "2.8.27" 804 | }, 805 | "dependencies": { 806 | "source-map": { 807 | "version": "0.4.4", 808 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", 809 | "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", 810 | "dev": true, 811 | "requires": { 812 | "amdefine": "1.0.1" 813 | } 814 | } 815 | } 816 | }, 817 | "has-flag": { 818 | "version": "1.0.0", 819 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", 820 | "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", 821 | "dev": true 822 | }, 823 | "has-unicode": { 824 | "version": "2.0.1", 825 | "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", 826 | "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" 827 | }, 828 | "he": { 829 | "version": "1.1.1", 830 | "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", 831 | "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", 832 | "dev": true 833 | }, 834 | "iconv-lite": { 835 | "version": "0.4.17", 836 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.17.tgz", 837 | "integrity": "sha1-T9qjs4rLwsAxsEXQ7c3+HsqxjI0=" 838 | }, 839 | "inflight": { 840 | "version": "1.0.6", 841 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 842 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 843 | "dev": true, 844 | "requires": { 845 | "once": "1.4.0", 846 | "wrappy": "1.0.2" 847 | } 848 | }, 849 | "info-symbol": { 850 | "version": "0.1.0", 851 | "resolved": "https://registry.npmjs.org/info-symbol/-/info-symbol-0.1.0.tgz", 852 | "integrity": "sha1-J4QdcoZ920JCzWEtecEGM4gcang=" 853 | }, 854 | "inherits": { 855 | "version": "2.0.3", 856 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 857 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 858 | }, 859 | "ini": { 860 | "version": "1.3.5", 861 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", 862 | "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" 863 | }, 864 | "inquirer": { 865 | "version": "5.2.0", 866 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-5.2.0.tgz", 867 | "integrity": "sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ==", 868 | "requires": { 869 | "ansi-escapes": "3.1.0", 870 | "chalk": "2.3.2", 871 | "cli-cursor": "2.1.0", 872 | "cli-width": "2.1.0", 873 | "external-editor": "2.2.0", 874 | "figures": "2.0.0", 875 | "lodash": "4.17.4", 876 | "mute-stream": "0.0.7", 877 | "run-async": "2.3.0", 878 | "rxjs": "5.5.8", 879 | "string-width": "2.1.1", 880 | "strip-ansi": "4.0.0", 881 | "through": "2.3.8" 882 | }, 883 | "dependencies": { 884 | "ansi-escapes": { 885 | "version": "3.1.0", 886 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", 887 | "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==" 888 | }, 889 | "ansi-regex": { 890 | "version": "3.0.0", 891 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 892 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" 893 | }, 894 | "ansi-styles": { 895 | "version": "3.2.1", 896 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 897 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 898 | "requires": { 899 | "color-convert": "1.9.1" 900 | } 901 | }, 902 | "chalk": { 903 | "version": "2.3.2", 904 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", 905 | "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", 906 | "requires": { 907 | "ansi-styles": "3.2.1", 908 | "escape-string-regexp": "1.0.5", 909 | "supports-color": "5.3.0" 910 | } 911 | }, 912 | "external-editor": { 913 | "version": "2.2.0", 914 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", 915 | "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", 916 | "requires": { 917 | "chardet": "0.4.2", 918 | "iconv-lite": "0.4.17", 919 | "tmp": "0.0.33" 920 | } 921 | }, 922 | "has-flag": { 923 | "version": "3.0.0", 924 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 925 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" 926 | }, 927 | "string-width": { 928 | "version": "2.1.1", 929 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 930 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 931 | "requires": { 932 | "is-fullwidth-code-point": "2.0.0", 933 | "strip-ansi": "4.0.0" 934 | } 935 | }, 936 | "strip-ansi": { 937 | "version": "4.0.0", 938 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 939 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 940 | "requires": { 941 | "ansi-regex": "3.0.0" 942 | } 943 | }, 944 | "supports-color": { 945 | "version": "5.3.0", 946 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", 947 | "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", 948 | "requires": { 949 | "has-flag": "3.0.0" 950 | } 951 | }, 952 | "tmp": { 953 | "version": "0.0.33", 954 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 955 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 956 | "requires": { 957 | "os-tmpdir": "1.0.2" 958 | } 959 | } 960 | } 961 | }, 962 | "invert-kv": { 963 | "version": "1.0.0", 964 | "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", 965 | "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" 966 | }, 967 | "is-accessor-descriptor": { 968 | "version": "1.0.0", 969 | "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", 970 | "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", 971 | "requires": { 972 | "kind-of": "6.0.2" 973 | }, 974 | "dependencies": { 975 | "kind-of": { 976 | "version": "6.0.2", 977 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", 978 | "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" 979 | } 980 | } 981 | }, 982 | "is-array": { 983 | "version": "1.0.1", 984 | "resolved": "https://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz", 985 | "integrity": "sha1-6YUMwsyGDDvAl36EzPDdRkWEJ5o=", 986 | "dev": true 987 | }, 988 | "is-buffer": { 989 | "version": "1.1.5", 990 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", 991 | "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=" 992 | }, 993 | "is-data-descriptor": { 994 | "version": "1.0.0", 995 | "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", 996 | "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", 997 | "requires": { 998 | "kind-of": "6.0.2" 999 | }, 1000 | "dependencies": { 1001 | "kind-of": { 1002 | "version": "6.0.2", 1003 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", 1004 | "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" 1005 | } 1006 | } 1007 | }, 1008 | "is-descriptor": { 1009 | "version": "1.0.2", 1010 | "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", 1011 | "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", 1012 | "requires": { 1013 | "is-accessor-descriptor": "1.0.0", 1014 | "is-data-descriptor": "1.0.0", 1015 | "kind-of": "6.0.2" 1016 | }, 1017 | "dependencies": { 1018 | "kind-of": { 1019 | "version": "6.0.2", 1020 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", 1021 | "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" 1022 | } 1023 | } 1024 | }, 1025 | "is-extendable": { 1026 | "version": "0.1.1", 1027 | "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", 1028 | "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=" 1029 | }, 1030 | "is-fullwidth-code-point": { 1031 | "version": "2.0.0", 1032 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1033 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" 1034 | }, 1035 | "is-number": { 1036 | "version": "3.0.0", 1037 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", 1038 | "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", 1039 | "requires": { 1040 | "kind-of": "3.2.2" 1041 | } 1042 | }, 1043 | "is-object": { 1044 | "version": "1.0.1", 1045 | "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", 1046 | "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", 1047 | "dev": true 1048 | }, 1049 | "is-plain-object": { 1050 | "version": "2.0.4", 1051 | "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", 1052 | "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", 1053 | "requires": { 1054 | "isobject": "3.0.1" 1055 | } 1056 | }, 1057 | "is-promise": { 1058 | "version": "2.1.0", 1059 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", 1060 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" 1061 | }, 1062 | "is-stream": { 1063 | "version": "1.1.0", 1064 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 1065 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" 1066 | }, 1067 | "is-windows": { 1068 | "version": "1.0.2", 1069 | "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", 1070 | "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==" 1071 | }, 1072 | "isarray": { 1073 | "version": "1.0.0", 1074 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 1075 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 1076 | }, 1077 | "isexe": { 1078 | "version": "2.0.0", 1079 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1080 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" 1081 | }, 1082 | "isobject": { 1083 | "version": "3.0.1", 1084 | "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", 1085 | "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" 1086 | }, 1087 | "istanbul": { 1088 | "version": "0.4.5", 1089 | "resolved": "https://registry.npmjs.org/istanbul/-/istanbul-0.4.5.tgz", 1090 | "integrity": "sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs=", 1091 | "dev": true, 1092 | "requires": { 1093 | "abbrev": "1.0.9", 1094 | "async": "1.5.2", 1095 | "escodegen": "1.8.1", 1096 | "esprima": "2.7.3", 1097 | "glob": "5.0.15", 1098 | "handlebars": "4.0.10", 1099 | "js-yaml": "3.8.4", 1100 | "mkdirp": "0.5.1", 1101 | "nopt": "3.0.6", 1102 | "once": "1.4.0", 1103 | "resolve": "1.1.7", 1104 | "supports-color": "3.2.3", 1105 | "which": "1.2.14", 1106 | "wordwrap": "1.0.0" 1107 | }, 1108 | "dependencies": { 1109 | "supports-color": { 1110 | "version": "3.2.3", 1111 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", 1112 | "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", 1113 | "dev": true, 1114 | "requires": { 1115 | "has-flag": "1.0.0" 1116 | } 1117 | } 1118 | } 1119 | }, 1120 | "js-yaml": { 1121 | "version": "3.8.4", 1122 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.8.4.tgz", 1123 | "integrity": "sha1-UgtFZPhlc7qWZir4Woyvp7S1pvY=", 1124 | "dev": true, 1125 | "requires": { 1126 | "argparse": "1.0.9", 1127 | "esprima": "3.1.3" 1128 | }, 1129 | "dependencies": { 1130 | "esprima": { 1131 | "version": "3.1.3", 1132 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", 1133 | "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", 1134 | "dev": true 1135 | } 1136 | } 1137 | }, 1138 | "kind-of": { 1139 | "version": "3.2.2", 1140 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 1141 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 1142 | "requires": { 1143 | "is-buffer": "1.1.5" 1144 | } 1145 | }, 1146 | "koalas": { 1147 | "version": "1.0.2", 1148 | "resolved": "https://registry.npmjs.org/koalas/-/koalas-1.0.2.tgz", 1149 | "integrity": "sha1-MYQz8HQjXbePrlZhoCqMpT7ilc0=" 1150 | }, 1151 | "lazy-cache": { 1152 | "version": "1.0.4", 1153 | "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", 1154 | "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", 1155 | "dev": true, 1156 | "optional": true 1157 | }, 1158 | "lcid": { 1159 | "version": "1.0.0", 1160 | "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", 1161 | "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", 1162 | "requires": { 1163 | "invert-kv": "1.0.0" 1164 | } 1165 | }, 1166 | "levn": { 1167 | "version": "0.3.0", 1168 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 1169 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 1170 | "dev": true, 1171 | "requires": { 1172 | "prelude-ls": "1.1.2", 1173 | "type-check": "0.3.2" 1174 | } 1175 | }, 1176 | "locate-path": { 1177 | "version": "2.0.0", 1178 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", 1179 | "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", 1180 | "requires": { 1181 | "p-locate": "2.0.0", 1182 | "path-exists": "3.0.0" 1183 | } 1184 | }, 1185 | "lodash": { 1186 | "version": "4.17.4", 1187 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", 1188 | "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" 1189 | }, 1190 | "log-ok": { 1191 | "version": "0.1.1", 1192 | "resolved": "https://registry.npmjs.org/log-ok/-/log-ok-0.1.1.tgz", 1193 | "integrity": "sha1-vqPdNqzQuKckDXhza1uXxlREozQ=", 1194 | "requires": { 1195 | "ansi-green": "0.1.1", 1196 | "success-symbol": "0.1.0" 1197 | } 1198 | }, 1199 | "log-utils": { 1200 | "version": "0.2.1", 1201 | "resolved": "https://registry.npmjs.org/log-utils/-/log-utils-0.2.1.tgz", 1202 | "integrity": "sha1-pMIXoN2aUFFdm5ICBgkas9TgMc8=", 1203 | "requires": { 1204 | "ansi-colors": "0.2.0", 1205 | "error-symbol": "0.1.0", 1206 | "info-symbol": "0.1.0", 1207 | "log-ok": "0.1.1", 1208 | "success-symbol": "0.1.0", 1209 | "time-stamp": "1.1.0", 1210 | "warning-symbol": "0.1.0" 1211 | } 1212 | }, 1213 | "longest": { 1214 | "version": "1.0.1", 1215 | "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", 1216 | "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", 1217 | "dev": true 1218 | }, 1219 | "lru-cache": { 1220 | "version": "4.0.2", 1221 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz", 1222 | "integrity": "sha1-HRdnnAac2l0ECZGgnbwsDbN35V4=", 1223 | "requires": { 1224 | "pseudomap": "1.0.2", 1225 | "yallist": "2.1.2" 1226 | } 1227 | }, 1228 | "map-visit": { 1229 | "version": "1.0.0", 1230 | "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", 1231 | "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", 1232 | "requires": { 1233 | "object-visit": "1.0.1" 1234 | } 1235 | }, 1236 | "mem": { 1237 | "version": "1.1.0", 1238 | "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", 1239 | "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", 1240 | "requires": { 1241 | "mimic-fn": "1.1.0" 1242 | } 1243 | }, 1244 | "merge-descriptors": { 1245 | "version": "1.0.1", 1246 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", 1247 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", 1248 | "dev": true 1249 | }, 1250 | "mimic-fn": { 1251 | "version": "1.1.0", 1252 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", 1253 | "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=" 1254 | }, 1255 | "mimic-response": { 1256 | "version": "1.0.0", 1257 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz", 1258 | "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=" 1259 | }, 1260 | "minimatch": { 1261 | "version": "3.0.4", 1262 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 1263 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 1264 | "dev": true, 1265 | "requires": { 1266 | "brace-expansion": "1.1.7" 1267 | } 1268 | }, 1269 | "minimist": { 1270 | "version": "0.0.8", 1271 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 1272 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" 1273 | }, 1274 | "mixin-object": { 1275 | "version": "2.0.1", 1276 | "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", 1277 | "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=", 1278 | "requires": { 1279 | "for-in": "0.1.8", 1280 | "is-extendable": "0.1.1" 1281 | }, 1282 | "dependencies": { 1283 | "for-in": { 1284 | "version": "0.1.8", 1285 | "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz", 1286 | "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=" 1287 | } 1288 | } 1289 | }, 1290 | "mkdirp": { 1291 | "version": "0.5.1", 1292 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 1293 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 1294 | "requires": { 1295 | "minimist": "0.0.8" 1296 | } 1297 | }, 1298 | "mocha": { 1299 | "version": "5.0.5", 1300 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.5.tgz", 1301 | "integrity": "sha512-3MM3UjZ5p8EJrYpG7s+29HAI9G7sTzKEe4+w37Dg0QP7qL4XGsV+Q2xet2cE37AqdgN1OtYQB6Vl98YiPV3PgA==", 1302 | "dev": true, 1303 | "requires": { 1304 | "browser-stdout": "1.3.1", 1305 | "commander": "2.11.0", 1306 | "debug": "3.1.0", 1307 | "diff": "3.5.0", 1308 | "escape-string-regexp": "1.0.5", 1309 | "glob": "7.1.2", 1310 | "growl": "1.10.3", 1311 | "he": "1.1.1", 1312 | "mkdirp": "0.5.1", 1313 | "supports-color": "4.4.0" 1314 | }, 1315 | "dependencies": { 1316 | "browser-stdout": { 1317 | "version": "1.3.1", 1318 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 1319 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 1320 | "dev": true 1321 | }, 1322 | "commander": { 1323 | "version": "2.11.0", 1324 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", 1325 | "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", 1326 | "dev": true 1327 | }, 1328 | "debug": { 1329 | "version": "3.1.0", 1330 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 1331 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 1332 | "dev": true, 1333 | "requires": { 1334 | "ms": "2.0.0" 1335 | } 1336 | }, 1337 | "diff": { 1338 | "version": "3.5.0", 1339 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", 1340 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", 1341 | "dev": true 1342 | }, 1343 | "glob": { 1344 | "version": "7.1.2", 1345 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 1346 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 1347 | "dev": true, 1348 | "requires": { 1349 | "fs.realpath": "1.0.0", 1350 | "inflight": "1.0.6", 1351 | "inherits": "2.0.3", 1352 | "minimatch": "3.0.4", 1353 | "once": "1.4.0", 1354 | "path-is-absolute": "1.0.1" 1355 | } 1356 | }, 1357 | "growl": { 1358 | "version": "1.10.3", 1359 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", 1360 | "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", 1361 | "dev": true 1362 | }, 1363 | "has-flag": { 1364 | "version": "2.0.0", 1365 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", 1366 | "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", 1367 | "dev": true 1368 | }, 1369 | "supports-color": { 1370 | "version": "4.4.0", 1371 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", 1372 | "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", 1373 | "dev": true, 1374 | "requires": { 1375 | "has-flag": "2.0.0" 1376 | } 1377 | } 1378 | } 1379 | }, 1380 | "module-not-found-error": { 1381 | "version": "1.0.1", 1382 | "resolved": "https://registry.npmjs.org/module-not-found-error/-/module-not-found-error-1.0.1.tgz", 1383 | "integrity": "sha1-z4tP9PKWQGdNbN0CsOO8UjwrvcA=", 1384 | "dev": true 1385 | }, 1386 | "ms": { 1387 | "version": "2.0.0", 1388 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1389 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 1390 | }, 1391 | "mute-stream": { 1392 | "version": "0.0.7", 1393 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", 1394 | "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" 1395 | }, 1396 | "nan": { 1397 | "version": "2.6.2", 1398 | "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz", 1399 | "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=" 1400 | }, 1401 | "node-abi": { 1402 | "version": "2.3.0", 1403 | "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.3.0.tgz", 1404 | "integrity": "sha512-zwm6vU3SsVgw3e9fu48JBaRBCJGIvAgysDsqtf5+vEexFE71bEOtaMWb5zr/zODZNzTPtQlqUUpC79k68Hspow==", 1405 | "requires": { 1406 | "semver": "5.5.0" 1407 | }, 1408 | "dependencies": { 1409 | "semver": { 1410 | "version": "5.5.0", 1411 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", 1412 | "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==" 1413 | } 1414 | } 1415 | }, 1416 | "noop-logger": { 1417 | "version": "0.1.1", 1418 | "resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz", 1419 | "integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=" 1420 | }, 1421 | "nopt": { 1422 | "version": "3.0.6", 1423 | "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", 1424 | "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", 1425 | "dev": true, 1426 | "requires": { 1427 | "abbrev": "1.0.9" 1428 | } 1429 | }, 1430 | "npm-run-path": { 1431 | "version": "2.0.2", 1432 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", 1433 | "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", 1434 | "requires": { 1435 | "path-key": "2.0.1" 1436 | } 1437 | }, 1438 | "npmlog": { 1439 | "version": "4.1.2", 1440 | "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", 1441 | "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", 1442 | "requires": { 1443 | "are-we-there-yet": "1.1.4", 1444 | "console-control-strings": "1.1.0", 1445 | "gauge": "2.7.4", 1446 | "set-blocking": "2.0.0" 1447 | } 1448 | }, 1449 | "number-is-nan": { 1450 | "version": "1.0.1", 1451 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 1452 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" 1453 | }, 1454 | "object-assign": { 1455 | "version": "4.1.1", 1456 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1457 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" 1458 | }, 1459 | "object-copy": { 1460 | "version": "0.1.0", 1461 | "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", 1462 | "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", 1463 | "requires": { 1464 | "copy-descriptor": "0.1.1", 1465 | "define-property": "0.2.5", 1466 | "kind-of": "3.2.2" 1467 | }, 1468 | "dependencies": { 1469 | "define-property": { 1470 | "version": "0.2.5", 1471 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", 1472 | "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", 1473 | "requires": { 1474 | "is-descriptor": "0.1.6" 1475 | } 1476 | }, 1477 | "is-accessor-descriptor": { 1478 | "version": "0.1.6", 1479 | "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", 1480 | "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", 1481 | "requires": { 1482 | "kind-of": "3.2.2" 1483 | } 1484 | }, 1485 | "is-data-descriptor": { 1486 | "version": "0.1.4", 1487 | "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", 1488 | "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", 1489 | "requires": { 1490 | "kind-of": "3.2.2" 1491 | } 1492 | }, 1493 | "is-descriptor": { 1494 | "version": "0.1.6", 1495 | "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", 1496 | "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", 1497 | "requires": { 1498 | "is-accessor-descriptor": "0.1.6", 1499 | "is-data-descriptor": "0.1.4", 1500 | "kind-of": "5.1.0" 1501 | }, 1502 | "dependencies": { 1503 | "kind-of": { 1504 | "version": "5.1.0", 1505 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", 1506 | "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" 1507 | } 1508 | } 1509 | } 1510 | } 1511 | }, 1512 | "object-visit": { 1513 | "version": "1.0.1", 1514 | "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", 1515 | "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", 1516 | "requires": { 1517 | "isobject": "3.0.1" 1518 | } 1519 | }, 1520 | "once": { 1521 | "version": "1.4.0", 1522 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1523 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1524 | "requires": { 1525 | "wrappy": "1.0.2" 1526 | } 1527 | }, 1528 | "onetime": { 1529 | "version": "2.0.1", 1530 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", 1531 | "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", 1532 | "requires": { 1533 | "mimic-fn": "1.1.0" 1534 | } 1535 | }, 1536 | "optimist": { 1537 | "version": "0.6.1", 1538 | "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", 1539 | "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", 1540 | "dev": true, 1541 | "requires": { 1542 | "minimist": "0.0.8", 1543 | "wordwrap": "0.0.3" 1544 | }, 1545 | "dependencies": { 1546 | "wordwrap": { 1547 | "version": "0.0.3", 1548 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", 1549 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", 1550 | "dev": true 1551 | } 1552 | } 1553 | }, 1554 | "optionator": { 1555 | "version": "0.8.2", 1556 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", 1557 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", 1558 | "dev": true, 1559 | "requires": { 1560 | "deep-is": "0.1.3", 1561 | "fast-levenshtein": "2.0.6", 1562 | "levn": "0.3.0", 1563 | "prelude-ls": "1.1.2", 1564 | "type-check": "0.3.2", 1565 | "wordwrap": "1.0.0" 1566 | } 1567 | }, 1568 | "os-homedir": { 1569 | "version": "1.0.2", 1570 | "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", 1571 | "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" 1572 | }, 1573 | "os-locale": { 1574 | "version": "2.0.0", 1575 | "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.0.0.tgz", 1576 | "integrity": "sha1-FZGN7VEFIrge565aMJ1U9jn8OaQ=", 1577 | "requires": { 1578 | "execa": "0.5.1", 1579 | "lcid": "1.0.0", 1580 | "mem": "1.1.0" 1581 | } 1582 | }, 1583 | "os-tmpdir": { 1584 | "version": "1.0.2", 1585 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 1586 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" 1587 | }, 1588 | "p-finally": { 1589 | "version": "1.0.0", 1590 | "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", 1591 | "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" 1592 | }, 1593 | "p-limit": { 1594 | "version": "1.1.0", 1595 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", 1596 | "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=" 1597 | }, 1598 | "p-locate": { 1599 | "version": "2.0.0", 1600 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", 1601 | "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", 1602 | "requires": { 1603 | "p-limit": "1.1.0" 1604 | } 1605 | }, 1606 | "path-exists": { 1607 | "version": "3.0.0", 1608 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 1609 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" 1610 | }, 1611 | "path-is-absolute": { 1612 | "version": "1.0.1", 1613 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1614 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 1615 | "dev": true 1616 | }, 1617 | "path-key": { 1618 | "version": "2.0.1", 1619 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 1620 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" 1621 | }, 1622 | "path-parse": { 1623 | "version": "1.0.5", 1624 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", 1625 | "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", 1626 | "dev": true 1627 | }, 1628 | "pathval": { 1629 | "version": "1.1.0", 1630 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", 1631 | "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", 1632 | "dev": true 1633 | }, 1634 | "pinkie": { 1635 | "version": "2.0.4", 1636 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 1637 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" 1638 | }, 1639 | "pinkie-promise": { 1640 | "version": "2.0.1", 1641 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 1642 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", 1643 | "requires": { 1644 | "pinkie": "2.0.4" 1645 | } 1646 | }, 1647 | "pointer-symbol": { 1648 | "version": "1.0.0", 1649 | "resolved": "https://registry.npmjs.org/pointer-symbol/-/pointer-symbol-1.0.0.tgz", 1650 | "integrity": "sha1-YPkRAgTqepKbYmRKITFVQ8uz1Ec=" 1651 | }, 1652 | "prebuild-install": { 1653 | "version": "2.5.1", 1654 | "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.5.1.tgz", 1655 | "integrity": "sha512-3DX9L6pzwc1m1ksMkW3Ky2WLgPQUBiySOfXVl3WZyAeJSyJb4wtoH9OmeRGcubAWsMlLiL8BTHbwfm/jPQE9Ag==", 1656 | "requires": { 1657 | "detect-libc": "1.0.3", 1658 | "expand-template": "1.1.0", 1659 | "github-from-package": "0.0.0", 1660 | "minimist": "1.2.0", 1661 | "mkdirp": "0.5.1", 1662 | "node-abi": "2.3.0", 1663 | "noop-logger": "0.1.1", 1664 | "npmlog": "4.1.2", 1665 | "os-homedir": "1.0.2", 1666 | "pump": "2.0.1", 1667 | "rc": "1.2.6", 1668 | "simple-get": "2.7.0", 1669 | "tar-fs": "1.16.0", 1670 | "tunnel-agent": "0.6.0", 1671 | "which-pm-runs": "1.0.0" 1672 | }, 1673 | "dependencies": { 1674 | "minimist": { 1675 | "version": "1.2.0", 1676 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 1677 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" 1678 | } 1679 | } 1680 | }, 1681 | "prelude-ls": { 1682 | "version": "1.1.2", 1683 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 1684 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 1685 | "dev": true 1686 | }, 1687 | "process-nextick-args": { 1688 | "version": "2.0.0", 1689 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", 1690 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" 1691 | }, 1692 | "promirepl": { 1693 | "version": "1.0.1", 1694 | "resolved": "https://registry.npmjs.org/promirepl/-/promirepl-1.0.1.tgz", 1695 | "integrity": "sha1-KVGq66K/P+InT/Y6FtlMBMpghy4=" 1696 | }, 1697 | "prompt-actions": { 1698 | "version": "3.0.2", 1699 | "resolved": "https://registry.npmjs.org/prompt-actions/-/prompt-actions-3.0.2.tgz", 1700 | "integrity": "sha512-dhz2Fl7vK+LPpmnQ/S/eSut4BnH4NZDLyddHKi5uTU/2PDn3grEMGkgsll16V5RpVUh/yxdiam0xsM0RD4xvtg==", 1701 | "requires": { 1702 | "debug": "2.6.8" 1703 | } 1704 | }, 1705 | "prompt-base": { 1706 | "version": "4.1.0", 1707 | "resolved": "https://registry.npmjs.org/prompt-base/-/prompt-base-4.1.0.tgz", 1708 | "integrity": "sha512-svGzgLUKZoqomz9SGMkf1hBG8Wl3K7JGuRCXc/Pv7xw8239hhaTBXrmjt7EXA9P/QZzdyT8uNWt9F/iJTXq75g==", 1709 | "requires": { 1710 | "component-emitter": "1.2.1", 1711 | "debug": "3.1.0", 1712 | "koalas": "1.0.2", 1713 | "log-utils": "0.2.1", 1714 | "prompt-actions": "3.0.2", 1715 | "prompt-question": "5.0.2", 1716 | "readline-ui": "2.2.3", 1717 | "readline-utils": "2.2.3", 1718 | "static-extend": "0.1.2" 1719 | }, 1720 | "dependencies": { 1721 | "debug": { 1722 | "version": "3.1.0", 1723 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 1724 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 1725 | "requires": { 1726 | "ms": "2.0.0" 1727 | } 1728 | } 1729 | } 1730 | }, 1731 | "prompt-checkbox": { 1732 | "version": "2.2.0", 1733 | "resolved": "https://registry.npmjs.org/prompt-checkbox/-/prompt-checkbox-2.2.0.tgz", 1734 | "integrity": "sha512-T/QWgkdUmKjRSr0FQlV8O+LfgmBk8PwDbWhzllm7mwWNAjs3qOVuru5Y1gV4/14L73zCncqcuwGwvnDyVcVgvA==", 1735 | "requires": { 1736 | "ansi-cyan": "0.1.1", 1737 | "debug": "2.6.8", 1738 | "prompt-base": "4.1.0" 1739 | } 1740 | }, 1741 | "prompt-choices": { 1742 | "version": "4.0.6", 1743 | "resolved": "https://registry.npmjs.org/prompt-choices/-/prompt-choices-4.0.6.tgz", 1744 | "integrity": "sha512-JfXujJo79TKG6KUHE+1S4tYLUEMRLM/mW9Bz49qrGKxVpnBGsQSv9lPiLKZgHtGEzXH7nG2kfMvWBEaKQs+JkQ==", 1745 | "requires": { 1746 | "arr-flatten": "1.1.0", 1747 | "arr-swap": "1.0.1", 1748 | "choices-separator": "2.0.0", 1749 | "clone-deep": "1.0.0", 1750 | "collection-visit": "1.0.0", 1751 | "debug": "3.1.0", 1752 | "define-property": "1.0.0", 1753 | "extend-shallow": "2.0.1", 1754 | "is-number": "3.0.0", 1755 | "kind-of": "5.1.0", 1756 | "koalas": "1.0.2", 1757 | "lazy-cache": "2.0.2", 1758 | "log-utils": "0.2.1", 1759 | "pointer-symbol": "1.0.0", 1760 | "radio-symbol": "2.0.0", 1761 | "set-value": "2.0.0", 1762 | "strip-color": "0.1.0", 1763 | "terminal-paginator": "2.0.2", 1764 | "toggle-array": "1.0.1" 1765 | }, 1766 | "dependencies": { 1767 | "debug": { 1768 | "version": "3.1.0", 1769 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 1770 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 1771 | "requires": { 1772 | "ms": "2.0.0" 1773 | } 1774 | }, 1775 | "kind-of": { 1776 | "version": "5.1.0", 1777 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", 1778 | "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" 1779 | }, 1780 | "lazy-cache": { 1781 | "version": "2.0.2", 1782 | "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-2.0.2.tgz", 1783 | "integrity": "sha1-uRkKT5EzVGlIQIWfio9whNiCImQ=", 1784 | "requires": { 1785 | "set-getter": "0.1.0" 1786 | } 1787 | } 1788 | } 1789 | }, 1790 | "prompt-list": { 1791 | "version": "3.1.2", 1792 | "resolved": "https://registry.npmjs.org/prompt-list/-/prompt-list-3.1.2.tgz", 1793 | "integrity": "sha512-5ezD3usudKMQVpMFLV5R0RTpUF0T+VRvQvmQyDz8Rpz274lKwabZO4ozTR8tq2X4HuovqZb3kGqFZmJeXjAyDw==", 1794 | "requires": { 1795 | "ansi-cyan": "0.1.1", 1796 | "ansi-dim": "0.1.1", 1797 | "debug": "3.1.0", 1798 | "prompt-radio": "1.2.1" 1799 | }, 1800 | "dependencies": { 1801 | "debug": { 1802 | "version": "3.1.0", 1803 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 1804 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 1805 | "requires": { 1806 | "ms": "2.0.0" 1807 | } 1808 | } 1809 | } 1810 | }, 1811 | "prompt-question": { 1812 | "version": "5.0.2", 1813 | "resolved": "https://registry.npmjs.org/prompt-question/-/prompt-question-5.0.2.tgz", 1814 | "integrity": "sha512-wreaLbbu8f5+7zXds199uiT11Ojp59Z4iBi6hONlSLtsKGTvL2UY8VglcxQ3t/X4qWIxsNCg6aT4O8keO65v6Q==", 1815 | "requires": { 1816 | "clone-deep": "1.0.0", 1817 | "debug": "3.1.0", 1818 | "define-property": "1.0.0", 1819 | "isobject": "3.0.1", 1820 | "kind-of": "5.1.0", 1821 | "koalas": "1.0.2", 1822 | "prompt-choices": "4.0.6" 1823 | }, 1824 | "dependencies": { 1825 | "debug": { 1826 | "version": "3.1.0", 1827 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 1828 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 1829 | "requires": { 1830 | "ms": "2.0.0" 1831 | } 1832 | }, 1833 | "kind-of": { 1834 | "version": "5.1.0", 1835 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", 1836 | "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" 1837 | } 1838 | } 1839 | }, 1840 | "prompt-radio": { 1841 | "version": "1.2.1", 1842 | "resolved": "https://registry.npmjs.org/prompt-radio/-/prompt-radio-1.2.1.tgz", 1843 | "integrity": "sha512-vH1iAkgbWyvZBC1BTajydiHmwJP4F1b684gq0fm2wOjPVW1zaDo01OXWr/Dske0XdoHhtZFNMOXNj/ZUSRBywg==", 1844 | "requires": { 1845 | "debug": "2.6.8", 1846 | "prompt-checkbox": "2.2.0" 1847 | } 1848 | }, 1849 | "proxyquire": { 1850 | "version": "2.0.1", 1851 | "resolved": "https://registry.npmjs.org/proxyquire/-/proxyquire-2.0.1.tgz", 1852 | "integrity": "sha512-fQr3VQrbdzHrdaDn3XuisVoJlJNDJizHAvUXw9IuXRR8BpV2x0N7LsCxrpJkeKfPbNjiNU/V5vc008cI0TmzzQ==", 1853 | "dev": true, 1854 | "requires": { 1855 | "fill-keys": "1.0.2", 1856 | "module-not-found-error": "1.0.1", 1857 | "resolve": "1.5.0" 1858 | }, 1859 | "dependencies": { 1860 | "resolve": { 1861 | "version": "1.5.0", 1862 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", 1863 | "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", 1864 | "dev": true, 1865 | "requires": { 1866 | "path-parse": "1.0.5" 1867 | } 1868 | } 1869 | } 1870 | }, 1871 | "pseudomap": { 1872 | "version": "1.0.2", 1873 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 1874 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" 1875 | }, 1876 | "pump": { 1877 | "version": "2.0.1", 1878 | "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", 1879 | "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", 1880 | "requires": { 1881 | "end-of-stream": "1.4.1", 1882 | "once": "1.4.0" 1883 | } 1884 | }, 1885 | "radio-symbol": { 1886 | "version": "2.0.0", 1887 | "resolved": "https://registry.npmjs.org/radio-symbol/-/radio-symbol-2.0.0.tgz", 1888 | "integrity": "sha1-eqm/xQSFY21S3XbWqOYxspB5muE=", 1889 | "requires": { 1890 | "ansi-gray": "0.1.1", 1891 | "ansi-green": "0.1.1", 1892 | "is-windows": "1.0.2" 1893 | } 1894 | }, 1895 | "rc": { 1896 | "version": "1.2.6", 1897 | "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.6.tgz", 1898 | "integrity": "sha1-6xiYnG1PTxYsOZ953dKfODVWgJI=", 1899 | "requires": { 1900 | "deep-extend": "0.4.2", 1901 | "ini": "1.3.5", 1902 | "minimist": "1.2.0", 1903 | "strip-json-comments": "2.0.1" 1904 | }, 1905 | "dependencies": { 1906 | "minimist": { 1907 | "version": "1.2.0", 1908 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 1909 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" 1910 | } 1911 | } 1912 | }, 1913 | "readable-stream": { 1914 | "version": "2.3.6", 1915 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 1916 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 1917 | "requires": { 1918 | "core-util-is": "1.0.2", 1919 | "inherits": "2.0.3", 1920 | "isarray": "1.0.0", 1921 | "process-nextick-args": "2.0.0", 1922 | "safe-buffer": "5.1.1", 1923 | "string_decoder": "1.1.1", 1924 | "util-deprecate": "1.0.2" 1925 | } 1926 | }, 1927 | "readline-ui": { 1928 | "version": "2.2.3", 1929 | "resolved": "https://registry.npmjs.org/readline-ui/-/readline-ui-2.2.3.tgz", 1930 | "integrity": "sha512-ix7jz0PxqQqcIuq3yQTHv1TOhlD2IHO74aNO+lSuXsRYm1d+pdyup1yF3zKyLK1wWZrVNGjkzw5tUegO2IDy+A==", 1931 | "requires": { 1932 | "component-emitter": "1.2.1", 1933 | "debug": "2.6.8", 1934 | "readline-utils": "2.2.3", 1935 | "string-width": "2.0.0" 1936 | } 1937 | }, 1938 | "readline-utils": { 1939 | "version": "2.2.3", 1940 | "resolved": "https://registry.npmjs.org/readline-utils/-/readline-utils-2.2.3.tgz", 1941 | "integrity": "sha1-b4R9a48ZFcORtYHDZ81HhzhiNRo=", 1942 | "requires": { 1943 | "arr-flatten": "1.1.0", 1944 | "extend-shallow": "2.0.1", 1945 | "is-buffer": "1.1.5", 1946 | "is-number": "3.0.0", 1947 | "is-windows": "1.0.2", 1948 | "koalas": "1.0.2", 1949 | "mute-stream": "0.0.7", 1950 | "strip-color": "0.1.0", 1951 | "window-size": "1.1.0" 1952 | }, 1953 | "dependencies": { 1954 | "window-size": { 1955 | "version": "1.1.0", 1956 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-1.1.0.tgz", 1957 | "integrity": "sha1-O0AtMkTzVWHbLJdhrZ0eUoawei0=", 1958 | "requires": { 1959 | "define-property": "1.0.0", 1960 | "is-number": "3.0.0" 1961 | } 1962 | } 1963 | } 1964 | }, 1965 | "repeat-string": { 1966 | "version": "1.6.1", 1967 | "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", 1968 | "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", 1969 | "dev": true 1970 | }, 1971 | "require-directory": { 1972 | "version": "2.1.1", 1973 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1974 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" 1975 | }, 1976 | "require-main-filename": { 1977 | "version": "1.0.1", 1978 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", 1979 | "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" 1980 | }, 1981 | "resolve": { 1982 | "version": "1.1.7", 1983 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", 1984 | "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", 1985 | "dev": true 1986 | }, 1987 | "restore-cursor": { 1988 | "version": "2.0.0", 1989 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", 1990 | "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", 1991 | "requires": { 1992 | "onetime": "2.0.1", 1993 | "signal-exit": "3.0.2" 1994 | } 1995 | }, 1996 | "right-align": { 1997 | "version": "0.1.3", 1998 | "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", 1999 | "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", 2000 | "dev": true, 2001 | "optional": true, 2002 | "requires": { 2003 | "align-text": "0.1.4" 2004 | } 2005 | }, 2006 | "rimraf": { 2007 | "version": "2.6.2", 2008 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", 2009 | "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", 2010 | "dev": true, 2011 | "requires": { 2012 | "glob": "7.1.2" 2013 | }, 2014 | "dependencies": { 2015 | "glob": { 2016 | "version": "7.1.2", 2017 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 2018 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 2019 | "dev": true, 2020 | "requires": { 2021 | "fs.realpath": "1.0.0", 2022 | "inflight": "1.0.6", 2023 | "inherits": "2.0.3", 2024 | "minimatch": "3.0.4", 2025 | "once": "1.4.0", 2026 | "path-is-absolute": "1.0.1" 2027 | } 2028 | } 2029 | } 2030 | }, 2031 | "run-async": { 2032 | "version": "2.3.0", 2033 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", 2034 | "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", 2035 | "requires": { 2036 | "is-promise": "2.1.0" 2037 | } 2038 | }, 2039 | "rxjs": { 2040 | "version": "5.5.8", 2041 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.8.tgz", 2042 | "integrity": "sha512-Bz7qou7VAIoGiglJZbzbXa4vpX5BmTTN2Dj/se6+SwADtw4SihqBIiEa7VmTXJ8pynvq0iFr5Gx9VLyye1rIxQ==", 2043 | "requires": { 2044 | "symbol-observable": "1.0.1" 2045 | } 2046 | }, 2047 | "safe-buffer": { 2048 | "version": "5.1.1", 2049 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 2050 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" 2051 | }, 2052 | "serialport": { 2053 | "version": "6.1.1", 2054 | "resolved": "https://registry.npmjs.org/serialport/-/serialport-6.1.1.tgz", 2055 | "integrity": "sha512-l7S8QgjVEb1n+saBSlZpcVKzkhCS4n0HmLdjbgCc+mA3IeHtVvMH/aPcx7auqGOHljMRgwfJdl0x5Kn9ImD1rA==", 2056 | "requires": { 2057 | "bindings": "1.3.0", 2058 | "commander": "2.15.1", 2059 | "debug": "3.1.0", 2060 | "nan": "2.6.2", 2061 | "prebuild-install": "2.5.1", 2062 | "promirepl": "1.0.1", 2063 | "prompt-list": "3.1.2", 2064 | "safe-buffer": "5.1.1" 2065 | }, 2066 | "dependencies": { 2067 | "bindings": { 2068 | "version": "1.3.0", 2069 | "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", 2070 | "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" 2071 | }, 2072 | "commander": { 2073 | "version": "2.15.1", 2074 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", 2075 | "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" 2076 | }, 2077 | "debug": { 2078 | "version": "3.1.0", 2079 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 2080 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 2081 | "requires": { 2082 | "ms": "2.0.0" 2083 | } 2084 | } 2085 | } 2086 | }, 2087 | "set-blocking": { 2088 | "version": "2.0.0", 2089 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 2090 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" 2091 | }, 2092 | "set-getter": { 2093 | "version": "0.1.0", 2094 | "resolved": "https://registry.npmjs.org/set-getter/-/set-getter-0.1.0.tgz", 2095 | "integrity": "sha1-12nBgsnVpR9AkUXy+6guXoboA3Y=", 2096 | "requires": { 2097 | "to-object-path": "0.3.0" 2098 | } 2099 | }, 2100 | "set-value": { 2101 | "version": "2.0.0", 2102 | "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", 2103 | "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", 2104 | "requires": { 2105 | "extend-shallow": "2.0.1", 2106 | "is-extendable": "0.1.1", 2107 | "is-plain-object": "2.0.4", 2108 | "split-string": "3.1.0" 2109 | } 2110 | }, 2111 | "shallow-clone": { 2112 | "version": "1.0.0", 2113 | "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz", 2114 | "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==", 2115 | "requires": { 2116 | "is-extendable": "0.1.1", 2117 | "kind-of": "5.1.0", 2118 | "mixin-object": "2.0.1" 2119 | }, 2120 | "dependencies": { 2121 | "kind-of": { 2122 | "version": "5.1.0", 2123 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", 2124 | "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" 2125 | } 2126 | } 2127 | }, 2128 | "shebang-command": { 2129 | "version": "1.2.0", 2130 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 2131 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 2132 | "dev": true, 2133 | "requires": { 2134 | "shebang-regex": "1.0.0" 2135 | } 2136 | }, 2137 | "shebang-regex": { 2138 | "version": "1.0.0", 2139 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 2140 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", 2141 | "dev": true 2142 | }, 2143 | "signal-exit": { 2144 | "version": "3.0.2", 2145 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 2146 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" 2147 | }, 2148 | "simple-concat": { 2149 | "version": "1.0.0", 2150 | "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", 2151 | "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=" 2152 | }, 2153 | "simple-get": { 2154 | "version": "2.7.0", 2155 | "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.7.0.tgz", 2156 | "integrity": "sha512-RkE9rGPHcxYZ/baYmgJtOSM63vH0Vyq+ma5TijBcLla41SWlh8t6XYIGMR/oeZcmr+/G8k+zrClkkVrtnQ0esg==", 2157 | "requires": { 2158 | "decompress-response": "3.3.0", 2159 | "once": "1.4.0", 2160 | "simple-concat": "1.0.0" 2161 | } 2162 | }, 2163 | "source-map": { 2164 | "version": "0.2.0", 2165 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", 2166 | "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", 2167 | "dev": true, 2168 | "optional": true, 2169 | "requires": { 2170 | "amdefine": "1.0.1" 2171 | } 2172 | }, 2173 | "split-string": { 2174 | "version": "3.1.0", 2175 | "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", 2176 | "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", 2177 | "requires": { 2178 | "extend-shallow": "3.0.2" 2179 | }, 2180 | "dependencies": { 2181 | "extend-shallow": { 2182 | "version": "3.0.2", 2183 | "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", 2184 | "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", 2185 | "requires": { 2186 | "assign-symbols": "1.0.0", 2187 | "is-extendable": "1.0.1" 2188 | } 2189 | }, 2190 | "is-extendable": { 2191 | "version": "1.0.1", 2192 | "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", 2193 | "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", 2194 | "requires": { 2195 | "is-plain-object": "2.0.4" 2196 | } 2197 | } 2198 | } 2199 | }, 2200 | "sprintf-js": { 2201 | "version": "1.0.3", 2202 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 2203 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 2204 | "dev": true 2205 | }, 2206 | "static-extend": { 2207 | "version": "0.1.2", 2208 | "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", 2209 | "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", 2210 | "requires": { 2211 | "define-property": "0.2.5", 2212 | "object-copy": "0.1.0" 2213 | }, 2214 | "dependencies": { 2215 | "define-property": { 2216 | "version": "0.2.5", 2217 | "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", 2218 | "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", 2219 | "requires": { 2220 | "is-descriptor": "0.1.6" 2221 | } 2222 | }, 2223 | "is-accessor-descriptor": { 2224 | "version": "0.1.6", 2225 | "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", 2226 | "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", 2227 | "requires": { 2228 | "kind-of": "3.2.2" 2229 | }, 2230 | "dependencies": { 2231 | "kind-of": { 2232 | "version": "3.2.2", 2233 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 2234 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 2235 | "requires": { 2236 | "is-buffer": "1.1.5" 2237 | } 2238 | } 2239 | } 2240 | }, 2241 | "is-data-descriptor": { 2242 | "version": "0.1.4", 2243 | "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", 2244 | "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", 2245 | "requires": { 2246 | "kind-of": "3.2.2" 2247 | }, 2248 | "dependencies": { 2249 | "kind-of": { 2250 | "version": "3.2.2", 2251 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", 2252 | "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", 2253 | "requires": { 2254 | "is-buffer": "1.1.5" 2255 | } 2256 | } 2257 | } 2258 | }, 2259 | "is-descriptor": { 2260 | "version": "0.1.6", 2261 | "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", 2262 | "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", 2263 | "requires": { 2264 | "is-accessor-descriptor": "0.1.6", 2265 | "is-data-descriptor": "0.1.4", 2266 | "kind-of": "5.1.0" 2267 | } 2268 | }, 2269 | "kind-of": { 2270 | "version": "5.1.0", 2271 | "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", 2272 | "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==" 2273 | } 2274 | } 2275 | }, 2276 | "string": { 2277 | "version": "3.3.3", 2278 | "resolved": "https://registry.npmjs.org/string/-/string-3.3.3.tgz", 2279 | "integrity": "sha1-XqIRzZLSKOGEKUmQpsyXs2anfLA=", 2280 | "dev": true 2281 | }, 2282 | "string-width": { 2283 | "version": "2.0.0", 2284 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz", 2285 | "integrity": "sha1-Y1xUNsxypuDDh87KJ41OLuxSaH4=", 2286 | "requires": { 2287 | "is-fullwidth-code-point": "2.0.0", 2288 | "strip-ansi": "3.0.1" 2289 | } 2290 | }, 2291 | "string_decoder": { 2292 | "version": "1.1.1", 2293 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 2294 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 2295 | "requires": { 2296 | "safe-buffer": "5.1.1" 2297 | } 2298 | }, 2299 | "strip-ansi": { 2300 | "version": "3.0.1", 2301 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 2302 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 2303 | "requires": { 2304 | "ansi-regex": "2.1.1" 2305 | } 2306 | }, 2307 | "strip-color": { 2308 | "version": "0.1.0", 2309 | "resolved": "https://registry.npmjs.org/strip-color/-/strip-color-0.1.0.tgz", 2310 | "integrity": "sha1-EG9l09PmotlAHKwOsM6LinArT3s=" 2311 | }, 2312 | "strip-eof": { 2313 | "version": "1.0.0", 2314 | "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", 2315 | "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" 2316 | }, 2317 | "strip-json-comments": { 2318 | "version": "2.0.1", 2319 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 2320 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" 2321 | }, 2322 | "success-symbol": { 2323 | "version": "0.1.0", 2324 | "resolved": "https://registry.npmjs.org/success-symbol/-/success-symbol-0.1.0.tgz", 2325 | "integrity": "sha1-JAIuSG878c3KCUKDt2nEctO3KJc=" 2326 | }, 2327 | "suppose": { 2328 | "version": "0.6.2", 2329 | "resolved": "https://registry.npmjs.org/suppose/-/suppose-0.6.2.tgz", 2330 | "integrity": "sha1-+J6e70IxppxZlWf0jVCgBqg7SB4=", 2331 | "dev": true, 2332 | "requires": { 2333 | "cross-spawn": "5.1.0", 2334 | "force-array": "3.1.0", 2335 | "string": "3.3.3", 2336 | "strip-ansi": "3.0.1" 2337 | }, 2338 | "dependencies": { 2339 | "cross-spawn": { 2340 | "version": "5.1.0", 2341 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", 2342 | "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", 2343 | "dev": true, 2344 | "requires": { 2345 | "lru-cache": "4.0.2", 2346 | "shebang-command": "1.2.0", 2347 | "which": "1.2.14" 2348 | } 2349 | } 2350 | } 2351 | }, 2352 | "symbol-observable": { 2353 | "version": "1.0.1", 2354 | "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", 2355 | "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=" 2356 | }, 2357 | "tar-fs": { 2358 | "version": "1.16.0", 2359 | "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.0.tgz", 2360 | "integrity": "sha512-I9rb6v7mjWLtOfCau9eH5L7sLJyU2BnxtEZRQ5Mt+eRKmf1F0ohXmT/Jc3fr52kDvjJ/HV5MH3soQfPL5bQ0Yg==", 2361 | "requires": { 2362 | "chownr": "1.0.1", 2363 | "mkdirp": "0.5.1", 2364 | "pump": "1.0.3", 2365 | "tar-stream": "1.5.5" 2366 | }, 2367 | "dependencies": { 2368 | "pump": { 2369 | "version": "1.0.3", 2370 | "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz", 2371 | "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==", 2372 | "requires": { 2373 | "end-of-stream": "1.4.1", 2374 | "once": "1.4.0" 2375 | } 2376 | } 2377 | } 2378 | }, 2379 | "tar-stream": { 2380 | "version": "1.5.5", 2381 | "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz", 2382 | "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==", 2383 | "requires": { 2384 | "bl": "1.2.2", 2385 | "end-of-stream": "1.4.1", 2386 | "readable-stream": "2.3.6", 2387 | "xtend": "4.0.1" 2388 | } 2389 | }, 2390 | "terminal-paginator": { 2391 | "version": "2.0.2", 2392 | "resolved": "https://registry.npmjs.org/terminal-paginator/-/terminal-paginator-2.0.2.tgz", 2393 | "integrity": "sha512-IZMT5ECF9p4s+sNCV8uvZSW9E1+9zy9Ji9xz2oee8Jfo7hUFpauyjxkhfRcIH6Lu3Wdepv5D1kVRc8Hx74/LfQ==", 2394 | "requires": { 2395 | "debug": "2.6.8", 2396 | "extend-shallow": "2.0.1", 2397 | "log-utils": "0.2.1" 2398 | } 2399 | }, 2400 | "through": { 2401 | "version": "2.3.8", 2402 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 2403 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" 2404 | }, 2405 | "time-stamp": { 2406 | "version": "1.1.0", 2407 | "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", 2408 | "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=" 2409 | }, 2410 | "to-object-path": { 2411 | "version": "0.3.0", 2412 | "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", 2413 | "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", 2414 | "requires": { 2415 | "kind-of": "3.2.2" 2416 | } 2417 | }, 2418 | "toggle-array": { 2419 | "version": "1.0.1", 2420 | "resolved": "https://registry.npmjs.org/toggle-array/-/toggle-array-1.0.1.tgz", 2421 | "integrity": "sha1-y/WEB5K9UJfzMReugkyTKv/ofVg=", 2422 | "requires": { 2423 | "isobject": "3.0.1" 2424 | } 2425 | }, 2426 | "tunnel-agent": { 2427 | "version": "0.6.0", 2428 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 2429 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 2430 | "requires": { 2431 | "safe-buffer": "5.1.1" 2432 | } 2433 | }, 2434 | "type-check": { 2435 | "version": "0.3.2", 2436 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 2437 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 2438 | "dev": true, 2439 | "requires": { 2440 | "prelude-ls": "1.1.2" 2441 | } 2442 | }, 2443 | "type-detect": { 2444 | "version": "4.0.3", 2445 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.3.tgz", 2446 | "integrity": "sha1-Dj8mcLRAmbC0bChNE2p+9Jx0wuo=", 2447 | "dev": true 2448 | }, 2449 | "uglify-js": { 2450 | "version": "2.8.27", 2451 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.27.tgz", 2452 | "integrity": "sha1-R3h/kSsPJC5bmENDvo416V9pTJw=", 2453 | "dev": true, 2454 | "optional": true, 2455 | "requires": { 2456 | "source-map": "0.5.6", 2457 | "uglify-to-browserify": "1.0.2", 2458 | "yargs": "3.10.0" 2459 | }, 2460 | "dependencies": { 2461 | "camelcase": { 2462 | "version": "1.2.1", 2463 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", 2464 | "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", 2465 | "dev": true, 2466 | "optional": true 2467 | }, 2468 | "cliui": { 2469 | "version": "2.1.0", 2470 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", 2471 | "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", 2472 | "dev": true, 2473 | "optional": true, 2474 | "requires": { 2475 | "center-align": "0.1.3", 2476 | "right-align": "0.1.3", 2477 | "wordwrap": "0.0.2" 2478 | } 2479 | }, 2480 | "source-map": { 2481 | "version": "0.5.6", 2482 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", 2483 | "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", 2484 | "dev": true, 2485 | "optional": true 2486 | }, 2487 | "wordwrap": { 2488 | "version": "0.0.2", 2489 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", 2490 | "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", 2491 | "dev": true, 2492 | "optional": true 2493 | }, 2494 | "yargs": { 2495 | "version": "3.10.0", 2496 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", 2497 | "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", 2498 | "dev": true, 2499 | "optional": true, 2500 | "requires": { 2501 | "camelcase": "1.2.1", 2502 | "cliui": "2.1.0", 2503 | "decamelize": "1.2.0", 2504 | "window-size": "0.1.0" 2505 | } 2506 | } 2507 | } 2508 | }, 2509 | "uglify-to-browserify": { 2510 | "version": "1.0.2", 2511 | "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", 2512 | "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", 2513 | "dev": true, 2514 | "optional": true 2515 | }, 2516 | "util-deprecate": { 2517 | "version": "1.0.2", 2518 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 2519 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 2520 | }, 2521 | "warning-symbol": { 2522 | "version": "0.1.0", 2523 | "resolved": "https://registry.npmjs.org/warning-symbol/-/warning-symbol-0.1.0.tgz", 2524 | "integrity": "sha1-uzHdEbeg+dZ6su2V9Fe2WCW7rSE=" 2525 | }, 2526 | "which": { 2527 | "version": "1.2.14", 2528 | "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", 2529 | "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", 2530 | "requires": { 2531 | "isexe": "2.0.0" 2532 | } 2533 | }, 2534 | "which-module": { 2535 | "version": "2.0.0", 2536 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", 2537 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" 2538 | }, 2539 | "which-pm-runs": { 2540 | "version": "1.0.0", 2541 | "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", 2542 | "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=" 2543 | }, 2544 | "wide-align": { 2545 | "version": "1.1.2", 2546 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", 2547 | "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", 2548 | "requires": { 2549 | "string-width": "1.0.2" 2550 | }, 2551 | "dependencies": { 2552 | "is-fullwidth-code-point": { 2553 | "version": "1.0.0", 2554 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 2555 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 2556 | "requires": { 2557 | "number-is-nan": "1.0.1" 2558 | } 2559 | }, 2560 | "string-width": { 2561 | "version": "1.0.2", 2562 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 2563 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 2564 | "requires": { 2565 | "code-point-at": "1.1.0", 2566 | "is-fullwidth-code-point": "1.0.0", 2567 | "strip-ansi": "3.0.1" 2568 | } 2569 | } 2570 | } 2571 | }, 2572 | "window-size": { 2573 | "version": "0.1.0", 2574 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", 2575 | "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", 2576 | "dev": true, 2577 | "optional": true 2578 | }, 2579 | "wordwrap": { 2580 | "version": "1.0.0", 2581 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 2582 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", 2583 | "dev": true 2584 | }, 2585 | "wrap-ansi": { 2586 | "version": "2.1.0", 2587 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", 2588 | "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", 2589 | "requires": { 2590 | "string-width": "1.0.2", 2591 | "strip-ansi": "3.0.1" 2592 | }, 2593 | "dependencies": { 2594 | "is-fullwidth-code-point": { 2595 | "version": "1.0.0", 2596 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 2597 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 2598 | "requires": { 2599 | "number-is-nan": "1.0.1" 2600 | } 2601 | }, 2602 | "string-width": { 2603 | "version": "1.0.2", 2604 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 2605 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 2606 | "requires": { 2607 | "code-point-at": "1.1.0", 2608 | "is-fullwidth-code-point": "1.0.0", 2609 | "strip-ansi": "3.0.1" 2610 | } 2611 | } 2612 | } 2613 | }, 2614 | "wrappy": { 2615 | "version": "1.0.2", 2616 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2617 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 2618 | }, 2619 | "xtend": { 2620 | "version": "4.0.1", 2621 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", 2622 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" 2623 | }, 2624 | "y18n": { 2625 | "version": "3.2.1", 2626 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", 2627 | "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" 2628 | }, 2629 | "yallist": { 2630 | "version": "2.1.2", 2631 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 2632 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" 2633 | }, 2634 | "yargs": { 2635 | "version": "11.0.0", 2636 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz", 2637 | "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", 2638 | "requires": { 2639 | "cliui": "4.0.0", 2640 | "decamelize": "1.2.0", 2641 | "find-up": "2.1.0", 2642 | "get-caller-file": "1.0.2", 2643 | "os-locale": "2.0.0", 2644 | "require-directory": "2.1.1", 2645 | "require-main-filename": "1.0.1", 2646 | "set-blocking": "2.0.0", 2647 | "string-width": "2.0.0", 2648 | "which-module": "2.0.0", 2649 | "y18n": "3.2.1", 2650 | "yargs-parser": "9.0.2" 2651 | }, 2652 | "dependencies": { 2653 | "ansi-regex": { 2654 | "version": "3.0.0", 2655 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 2656 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" 2657 | }, 2658 | "cliui": { 2659 | "version": "4.0.0", 2660 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz", 2661 | "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==", 2662 | "requires": { 2663 | "string-width": "2.1.1", 2664 | "strip-ansi": "4.0.0", 2665 | "wrap-ansi": "2.1.0" 2666 | }, 2667 | "dependencies": { 2668 | "string-width": { 2669 | "version": "2.1.1", 2670 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 2671 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 2672 | "requires": { 2673 | "is-fullwidth-code-point": "2.0.0", 2674 | "strip-ansi": "4.0.0" 2675 | } 2676 | } 2677 | } 2678 | }, 2679 | "strip-ansi": { 2680 | "version": "4.0.0", 2681 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 2682 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 2683 | "requires": { 2684 | "ansi-regex": "3.0.0" 2685 | } 2686 | }, 2687 | "yargs-parser": { 2688 | "version": "9.0.2", 2689 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz", 2690 | "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=", 2691 | "requires": { 2692 | "camelcase": "4.1.0" 2693 | } 2694 | } 2695 | } 2696 | } 2697 | } 2698 | } 2699 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "thingssdk-cli", 3 | "version": "1.3.0", 4 | "description": "Generator for JavaScript microcontroller projects", 5 | "main": "bin/thingssdk.js", 6 | "bin": { 7 | "thingssdk": "./bin/thingssdk.js" 8 | }, 9 | "scripts": { 10 | "test": "mocha --recursive --timeout 5000 --exit", 11 | "combine-coverage": "node ./scripts/coverage_combine", 12 | "test:coverage": "rimraf coverage && istanbul cover --report=none --print=none --include-pid node_modules/mocha/bin/_mocha -- --recursive --timeout 5000 --exit && npm run combine-coverage" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/thingsSDK/thingssdk-cli.git" 17 | }, 18 | "keywords": [ 19 | "JavaScript", 20 | "IoT", 21 | "ESP8266", 22 | "Espruino" 23 | ], 24 | "author": "Andrew Chalkley ", 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/thingsSDK/thingssdk-cli/issues" 28 | }, 29 | "homepage": "https://github.com/thingsSDK/thingssdk-cli#readme", 30 | "dependencies": { 31 | "colors": "^1.2.1", 32 | "inquirer": "^5.2.0", 33 | "mkdirp": "^0.5.1", 34 | "serialport": "^6.1.1", 35 | "yargs": "11.0.0" 36 | }, 37 | "devDependencies": { 38 | "chai": "^4.1.2", 39 | "istanbul": "^0.4.5", 40 | "mocha": "^5.0.5", 41 | "proxyquire": "^2.0.1", 42 | "rimraf": "^2.6.2", 43 | "suppose": "^0.6.2" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /scripts/coverage_combine.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const path = require('path'); 5 | 6 | const istanbul = require('istanbul'), 7 | collector = new istanbul.Collector(), 8 | reporter = new istanbul.Reporter(), 9 | sync = false; 10 | 11 | const coveragePath = "./coverage"; 12 | 13 | fs.readdir(coveragePath, (err, files) => { 14 | files 15 | .filter(file => path.extname(file) === ".json") 16 | .map(file => path.join(coveragePath, file)) 17 | .map(filePath => fs.readFileSync(filePath, "utf-8")) 18 | .map(fileContents => JSON.parse(fileContents)) 19 | .forEach(json => collector.add(json)); 20 | reporter.addAll(['lcov']); 21 | reporter.write(collector, sync, function () { 22 | console.log('All reports generated'); 23 | }); 24 | }); -------------------------------------------------------------------------------- /templates/dot-gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto -------------------------------------------------------------------------------- /templates/dot-gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/node 2 | 3 | ### Node ### 4 | # Logs 5 | logs 6 | *.log 7 | npm-debug.log* 8 | 9 | # Runtime data 10 | pids 11 | *.pid 12 | *.seed 13 | *.pid.lock 14 | 15 | # Directory for instrumented libs generated by jscoverage/JSCover 16 | lib-cov 17 | 18 | # Coverage directory used by tools like istanbul 19 | coverage 20 | 21 | # nyc test coverage 22 | .nyc_output 23 | 24 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 25 | .grunt 26 | 27 | # node-waf configuration 28 | .lock-wscript 29 | 30 | # Compiled binary addons (http://nodejs.org/api/addons.html) 31 | build/Release 32 | 33 | # Dependency directories 34 | node_modules 35 | jspm_packages 36 | 37 | # Optional npm cache directory 38 | .npm 39 | 40 | # Optional REPL history 41 | .node_repl_history 42 | 43 | # ThingsSDK 44 | devices.json 45 | build/* -------------------------------------------------------------------------------- /templates/espruino/scripts/repl.js: -------------------------------------------------------------------------------- 1 | const espruinoStrategy = require('thingssdk-espruino-strategy'); 2 | 3 | const devices = require('../devices.json').devices; 4 | 5 | espruinoStrategy.utils.filterDevices(devices) 6 | .forEach(espruinoStrategy.repl); 7 | -------------------------------------------------------------------------------- /templates/espruino/scripts/upload.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const env = process.argv[2]; 3 | 4 | if(!env) throw Error('Environment not present. Please use development or production.'); 5 | 6 | const path = require('path'); 7 | const deployer = require('thingssdk-deployer')(); 8 | 9 | const espruinoStrategy = require('thingssdk-espruino-strategy'); 10 | 11 | const iotPackageJson = require('../package.json'); 12 | const devices = require('../devices.json').devices; 13 | const scriptsDir = path.dirname(require.main.filename); 14 | const payload = { 15 | entry: path.join(__dirname, '..', iotPackageJson.main), 16 | buildDir: path.join(scriptsDir, '..', 'build'), 17 | env 18 | }; 19 | 20 | deployer.prepare(devices, payload); 21 | 22 | deployer.use('espruino', espruinoStrategy.build); 23 | deployer.use('espruino', espruinoStrategy.upload); 24 | 25 | deployer.deploy(); -------------------------------------------------------------------------------- /templates/main.js: -------------------------------------------------------------------------------- 1 | let isOn = false; 2 | const interval = 500; // 500 milliseconds = 0.5 seconds 3 | 4 | /** 5 | * The `main` function gets executed when the board is initialized. 6 | * Development: npm run dev 7 | * Production: npm run deploy 8 | */ 9 | function main() { 10 | setInterval(() => { 11 | isOn = !isOn; // Flips the state on or off 12 | digitalWrite(D2, isOn); // D2 is the blue LED on the ESP8266 boards 13 | }, interval); 14 | } 15 | -------------------------------------------------------------------------------- /test/commands/helper.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const rmdir = require('rimraf'); 5 | 6 | function prepCommand(command, cliArgs, path_to = "") { 7 | cliArgs[0] = path_to + cliArgs[0]; 8 | if (process.env.running_under_istanbul) { 9 | let cmd = "istanbul"; 10 | if (process.platform === 'win32') cmd = `${cmd}.cmd`; 11 | cliArgs.unshift(cliArgs[0]); 12 | cliArgs[1] = "--"; 13 | cliArgs = ['cover', '--report=none', '--print=none', '--include-pid'].concat(cliArgs); 14 | command = path.join(path_to, "node_modules", ".bin", cmd); 15 | } 16 | return { command, cliArgs }; 17 | } 18 | 19 | function cleanTmp(done) { 20 | rmdir('tmp', function (error) { 21 | done(); 22 | }); 23 | } 24 | 25 | module.exports = { 26 | prepCommand, 27 | cleanTmp 28 | }; -------------------------------------------------------------------------------- /test/commands/test-devices.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('chai').assert; 4 | const mkdirp = require('mkdirp'); 5 | const proxyquire = require('proxyquire'); 6 | const suppose = require("suppose"); 7 | 8 | const fs = require('fs'); 9 | const path = require('path'); 10 | 11 | const {prepCommand, cleanTmp} = require('./helper'); 12 | const {createDevicesJSON: devicesCommand} = require('../../lib/devices'); 13 | 14 | 15 | describe("thingssdk devices", () => { 16 | describe("with valid arguments", () => { 17 | const checkDevicesPath = "tmp/devices-json-check"; 18 | const jsonPath = path.join(checkDevicesPath, "devices.json"); 19 | 20 | const validArguments = { 21 | port: "COM7", 22 | baud_rate: "115200", 23 | runtime: "espruino", 24 | destinationPath: checkDevicesPath 25 | }; 26 | 27 | const otherValidArguments = { 28 | port: "COM3", 29 | runtime: "espruino", 30 | baud_rate: 9600, 31 | destinationPath: checkDevicesPath 32 | }; 33 | 34 | const validArgumentsWithoutPortAndBaudRate = { 35 | runtime: "espruino", 36 | destinationPath: checkDevicesPath 37 | }; 38 | 39 | before(done => { 40 | cleanTmp(() => { 41 | mkdirp(checkDevicesPath, (err) => { 42 | done(); 43 | }); 44 | }); 45 | }); 46 | 47 | it("should create a `devices.json` in the correct folder", done => { 48 | mkdirp(checkDevicesPath, (err) => { 49 | devicesCommand(validArguments).then(() => { 50 | const devices = JSON.parse(fs.readFileSync(jsonPath)); 51 | const expectedJson = { 52 | devices: { 53 | COM7: { 54 | runtime: "espruino", 55 | baud_rate: 115200 56 | } 57 | } 58 | }; 59 | assert.deepEqual(devices, expectedJson, "devices.json didn't match expectedJson"); 60 | done(); 61 | }); 62 | }); 63 | }); 64 | 65 | 66 | it("should create a `devices.json` in the correct folder with different params", done => { 67 | mkdirp(checkDevicesPath, (err) => { 68 | devicesCommand(otherValidArguments).then(() => { 69 | const devices = JSON.parse(fs.readFileSync(jsonPath)); 70 | const expectedJson = { 71 | devices: { 72 | COM3: { 73 | runtime: "espruino", 74 | baud_rate: 9600 75 | } 76 | } 77 | }; 78 | assert.deepEqual(devices, expectedJson, "devices.json didn't match expectedJson"); 79 | done(); 80 | }); 81 | }); 82 | }); 83 | 84 | it("should exit correctly when correct aguments are passed", () => { 85 | process.chdir('tmp'); 86 | let commandOutput; 87 | 88 | const {handler : cliDevicesCommand} = proxyquire('../../lib/commands/devices', 89 | { 90 | '../core/cli-helpers': { 91 | onFinish: (message) => { 92 | commandOutput = message; 93 | } 94 | } 95 | }); 96 | 97 | cliDevicesCommand(validArguments); 98 | assert.equal(commandOutput, 'devices.json successfully created'); 99 | process.chdir('../'); 100 | }); 101 | 102 | it("should ask for port and baud rate if missing from arguments", done => { 103 | const {createDevicesJSON: devicesCommand} = proxyquire('../../lib/devices', { 104 | "./core/ports": { 105 | getPorts: () => { 106 | return new Promise((resolve, reject) => { 107 | resolve(["COM7", "COM18"]); 108 | }); 109 | } 110 | }, 111 | "inquirer": { 112 | prompt: questions => { 113 | return new Promise((resolve, reject) => { 114 | const answers = { 115 | port: "COM7", 116 | baud_rate: 115200 117 | }; 118 | resolve(answers); 119 | }); 120 | } 121 | } 122 | }); 123 | 124 | devicesCommand(validArgumentsWithoutPortAndBaudRate).then(() => { 125 | const devices = JSON.parse(fs.readFileSync(jsonPath)); 126 | const expectedJson = { 127 | devices: { 128 | COM7: { 129 | runtime: "espruino", 130 | baud_rate: 115200 131 | } 132 | } 133 | }; 134 | assert.deepEqual(devices, expectedJson, "devices.json didn't match expectedJson"); 135 | done(); 136 | }); 137 | 138 | }); 139 | 140 | after(cleanTmp); 141 | }); 142 | }); 143 | -------------------------------------------------------------------------------- /test/commands/test-new.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('chai').assert; 4 | const mkdirp = require('mkdirp'); 5 | const {createApplication: newCommand} = require("../../lib/new"); 6 | const fs = require('fs'); 7 | const path = require('path'); 8 | const suppose = require("suppose"); 9 | const {prepCommand, cleanTmp} = require('./helper'); 10 | 11 | describe("thingssdk new", () => { 12 | const projectPath = "tmp/folder/to/project_name"; 13 | 14 | const validArguments = { 15 | port: "COM7", 16 | baud_rate: "115200", 17 | runtime: "espruino", 18 | path: projectPath 19 | }; 20 | 21 | describe("with valid arguments", () => { 22 | before(cleanTmp); 23 | 24 | it("should create a devices.json", done => { 25 | newCommand(validArguments).then(() => { 26 | const devices = JSON.parse(fs.readFileSync(path.join(projectPath, "devices.json"))); 27 | const expectedJson = { 28 | devices: { 29 | COM7: { 30 | runtime: "espruino", 31 | baud_rate: 115200 32 | } 33 | } 34 | }; 35 | assert.deepEqual(devices, expectedJson, "devices.json didn't match expectedJson"); 36 | done(); 37 | }); 38 | }); 39 | 40 | it("should create a properly structured package.json", done => { 41 | const pkgJSON = JSON.parse(fs.readFileSync(path.join(projectPath, "package.json"))); 42 | const expectedJson = { 43 | name: "project_name", 44 | version: '0.0.0', 45 | private: true, 46 | main: 'main.js', 47 | scripts: { 48 | dev: "node ./scripts/upload development && npm run repl", 49 | deploy: "node ./scripts/upload production", 50 | repl: "node ./scripts/repl", 51 | postinstall: "rimraf node_modules/bluetooth-hci-socket" 52 | }, 53 | devDependencies: { 54 | "thingssdk-deployer": "~1.0.1", 55 | "thingssdk-espruino-strategy": "~1.0.3" 56 | } 57 | }; 58 | assert.deepEqual(pkgJSON, expectedJson, "package.json didn't match expectedJson"); 59 | done(); 60 | }); 61 | 62 | it("should copy the correct files", done => { 63 | const templatesPath = path.join(__dirname, "..", "..", "templates"); 64 | const files = [ 65 | { 66 | source: path.join(templatesPath, "dot-gitignore"), 67 | dest: path.join(projectPath, ".gitignore") 68 | }, 69 | { 70 | source: path.join(templatesPath, "dot-gitattributes"), 71 | dest: path.join(projectPath, ".gitattributes") 72 | }, 73 | { 74 | source: path.join(templatesPath, "main.js"), 75 | dest: path.join(projectPath, "main.js") 76 | }, 77 | { 78 | source: path.join(templatesPath, validArguments.runtime, "scripts", "upload.js"), 79 | dest: path.join(projectPath, "scripts", "upload.js") 80 | }, 81 | 82 | ]; 83 | files.forEach(file => { 84 | const fileSourceContents = fs.readFileSync(file.source, "utf-8"); 85 | const fileDestinationContents = fs.readFileSync(file.dest, "utf-8"); 86 | assert.equal(fileSourceContents, fileDestinationContents, `file contetnts for ${file.dest} didn't match ${file.source}`); 87 | }); 88 | done(); 89 | }); 90 | 91 | }); 92 | 93 | describe("when folder already exists", () => { 94 | const mainPath = path.join(projectPath, 'main.js'); 95 | const newFileContents = "console.log('hello world')"; 96 | let command = "node"; 97 | let cliArgs = [`bin/thingssdk.js`, `new`, projectPath, `--port=${validArguments.port}`, `--baud_rate=${validArguments.baud_rate}`]; 98 | 99 | before(done => { 100 | const preparedCommand = prepCommand(command, cliArgs); 101 | command = preparedCommand.command; 102 | cliArgs = preparedCommand.cliArgs; 103 | done(); 104 | }); 105 | 106 | beforeEach(done => { 107 | cleanTmp(() => { 108 | newCommand(validArguments).then(() => { 109 | fs.writeFileSync(mainPath, newFileContents); 110 | done(); 111 | }); 112 | }); 113 | }); 114 | 115 | it("should replace files if y", done => { 116 | assert.equal(fs.readFileSync(mainPath, "utf-8"), newFileContents); 117 | suppose(command, cliArgs) 118 | .when('Type y or n: ').respond('y\n') 119 | .on('error', function (err) { 120 | console.log(err.message); 121 | }) 122 | .end(function (code) { 123 | assert.equal(code, 0, "process exit code"); 124 | assert.notEqual(fs.readFileSync(mainPath, "utf-8"), newFileContents); 125 | done(); 126 | }); 127 | }); 128 | 129 | it("should abort if n", done => { 130 | assert.equal(fs.readFileSync(mainPath, "utf-8"), newFileContents); 131 | suppose(command, cliArgs) 132 | .when('Type y or n: ').respond('n\n') 133 | .on('error', function (err) { 134 | console.log(err.message); 135 | }) 136 | .end(function (code) { 137 | assert.equal(code, 0, "process exit code"); 138 | assert.equal(fs.readFileSync(mainPath, "utf-8"), newFileContents); 139 | done(); 140 | }); 141 | }); 142 | 143 | it("should abort and error if y or n not pressent", done => { 144 | assert.equal(fs.readFileSync(mainPath, "utf-8"), newFileContents); 145 | suppose(command, cliArgs) 146 | .when('Type y or n: ').respond('please don\'t\n') 147 | .on('error', function (err) { 148 | console.log(err.message); 149 | }) 150 | .end(function (code) { 151 | assert.equal(code, 1, "process exit code"); 152 | assert.equal(fs.readFileSync(mainPath, "utf-8"), newFileContents); 153 | done(); 154 | }); 155 | }); 156 | }); 157 | 158 | describe("if arguments with tildes in the path are passed", () => { 159 | it("should error if tilde is used at the start of path and no project created", done => { 160 | const examplePath = "~/example"; 161 | newCommand({ 162 | path: examplePath, 163 | port: "COM7", 164 | baud_rate: "115200", 165 | runtime: "espruino" 166 | }).catch((err) => { 167 | assert.isNotNull(err); 168 | // package.json shouldn't be there, i.e. project not created 169 | assert.throws(() => fs.readFileSync(path.join(examplePath, "package.json"))); 170 | done(); 171 | }); 172 | }); 173 | 174 | it("should create project if it's in the middle of the path", done => { 175 | const examplePath = "tmp/~/example"; 176 | newCommand({ 177 | path: examplePath, 178 | port: "COM7", 179 | baud_rate: "115200", 180 | runtime: "espruino" 181 | }).then(() => { 182 | // Check that the package.json is created i.e. project created 183 | const packageJSON = JSON.parse(fs.readFileSync(path.join(examplePath, "package.json"))); 184 | assert.equal(packageJSON.name, "example"); 185 | done(); 186 | }); 187 | }); 188 | }); 189 | 190 | after(cleanTmp); 191 | }); 192 | -------------------------------------------------------------------------------- /test/unit/test-file.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const expect = require("chai").expect; 4 | const path = require("path"); 5 | const mkdirp = require("mkdirp"); 6 | const fs = require("fs"); 7 | 8 | const {isDirectoryEmpty} = require("../../lib/core/file"); 9 | 10 | describe("function isDirectoryEmpty()", () => { 11 | it("should throw an error if given no path", (done) => { 12 | isDirectoryEmpty().catch(err => { 13 | expect(err).to.be.a('Error'); 14 | done(); 15 | }); 16 | 17 | }); 18 | 19 | it("should return false if any files are present in the given directory", (done) => { 20 | /** 21 | An arbitrary directory that we know isn't empty 22 | */ 23 | const thisDirectory = path.resolve(__dirname); 24 | 25 | /** 26 | Initialize actual here so that we can update it with 27 | the async results of isDirectoryEmpty 28 | */ 29 | let actual; 30 | const expected = false; 31 | 32 | /** 33 | asyncResult is passed to the callback via 34 | isDirectoryEmpty internal logic 35 | */ 36 | const callback = (asyncResult) => { 37 | actual = asyncResult; 38 | expect(actual).to.equal(expected); 39 | done(); 40 | }; 41 | 42 | isDirectoryEmpty(thisDirectory).then(callback); 43 | }); 44 | 45 | it("should return true if the given directory is empty", (done) => { 46 | const emptyDirectory = path.resolve(__dirname, "empty"); 47 | mkdirp(emptyDirectory); 48 | 49 | /** 50 | Initialize actual here so that we can update it with 51 | the async results of isDirectoryEmpty 52 | */ 53 | let actual; 54 | const expected = true; 55 | 56 | /** 57 | isDirectoryEmpty internal logic 58 | asyncResult is passed to the callback via 59 | */ 60 | const callback = (asyncResult) => { 61 | actual = asyncResult; 62 | expect(actual).to.equal(expected); 63 | 64 | /** 65 | Destroy the empty directory we made for this test 66 | before we finish 67 | */ 68 | fs.rmdir(emptyDirectory, done); 69 | }; 70 | 71 | isDirectoryEmpty(emptyDirectory).then(callback); 72 | }); 73 | }); 74 | -------------------------------------------------------------------------------- /test/unit/test-ports.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const assert = require('chai').assert; 4 | const proxyquire = require('proxyquire'); 5 | 6 | 7 | describe("function getPorts()", () => { 8 | let getPorts; 9 | let error; 10 | let ports; 11 | before(() => { 12 | getPorts = proxyquire('../../lib/core/ports', { 13 | 'serialport': { 14 | list: (callback) => { 15 | callback(error, ports); 16 | } 17 | } 18 | }).getPorts; 19 | }); 20 | 21 | it("should return a list of serveral ports", done => { 22 | error = null; 23 | ports = [{ comName: "COM3" }, { comName: "COM7" }] 24 | getPorts().then(ports => { 25 | assert.deepEqual(ports, ["COM3", "COM7"]); 26 | done(); 27 | }).catch(err => { 28 | assert.isNull(err); 29 | done(); 30 | }); 31 | }); 32 | 33 | it("should return a list of port if there's only one port", done => { 34 | error = null; 35 | ports = [{ comName: "COM7" }]; 36 | getPorts().then(ports => { 37 | assert.deepEqual(ports, ["COM7"]); 38 | done(); 39 | }).catch(err => { 40 | assert.isNull(err); 41 | done(); 42 | }); 43 | }); 44 | 45 | it("should return an error", done => { 46 | const errorMessage = "Opps some serial port error"; 47 | error = new Error(errorMessage); 48 | ports = null; 49 | getPorts().then(ports => { 50 | assert.isNull(ports); 51 | done(); 52 | }).catch(err => { 53 | assert.equal(err.message, errorMessage); 54 | done(); 55 | }); 56 | }); 57 | 58 | it("should eventually return ports once they're plugged in", done => { 59 | //Initially there's no ports [], then COM7 get's plugged in 60 | const calls = [[], [{ comName: "COM7" }]]; 61 | let callBackTime = 0; 62 | const getPorts = proxyquire('../../lib/core/ports', { 63 | 'serialport': { 64 | list: (callback) => { 65 | const ports = calls.shift(); 66 | setTimeout(() => callback(null, ports), callBackTime+=1200); 67 | } 68 | } 69 | }).getPorts; 70 | 71 | getPorts().then(ports => { 72 | assert.deepEqual(ports, ["COM7"], 'Ports were not what was expected'); 73 | done(); 74 | }).catch(err => { 75 | assert.isNull(err); 76 | done(); 77 | }); 78 | }); 79 | }); --------------------------------------------------------------------------------