├── .dockerignore ├── .eslintrc ├── .gitignore ├── .travis.yml ├── Dockerfile ├── README.md ├── package.json ├── src ├── index.js └── run.js └── yarn.lock /.dockerignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .git 3 | .DS_Store 4 | bin 5 | coverage 6 | auth.js 7 | node_modules 8 | npm-debug.log 9 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "eslint:recommended", 3 | "ecmaFeatures": { 4 | "modules": true 5 | }, 6 | "env": { 7 | "node": true, 8 | "es6": true 9 | }, 10 | "rules": { 11 | "array-bracket-spacing": [ 2, "always" ], 12 | "comma-dangle": [ 2, "never" ], 13 | "eol-last": 2, 14 | "indent": [2, 2], 15 | "no-multiple-empty-lines": 2, 16 | "no-unused-vars": 2, 17 | "no-console": 0, 18 | "no-var": 0, 19 | "object-curly-spacing": [ 2, "always" ], 20 | "quotes": [ 2, "single", "avoid-escape" ], 21 | "semi": [ 2, "never" ], 22 | "strict": 0, 23 | "space-before-blocks": [ 2, "always" ], 24 | "space-before-function-paren": [ 2, { "anonymous": "always", "named": "never" } ], 25 | "valid-jsdoc": 2 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .DS_Store 3 | node_modules 4 | npm-debug.log 5 | bin 6 | auth.js 7 | /coverage 8 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "5" 4 | script: 5 | - npm run lint 6 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:6.11.2-alpine 2 | 3 | MAINTAINER Mike Stead 4 | 5 | WORKDIR /opt/app 6 | 7 | COPY package.json yarn.lock /opt/app/ 8 | RUN yarn install --production 9 | COPY . /opt/app 10 | 11 | ENTRYPOINT ["node", "/opt/app/src/run.js"] 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ECS Task Deploy 2 | 3 | [![Build Status](https://travis-ci.org/mikestead/ecs-task-deploy.svg?branch=greenkeeper%2Fcommander-2.10.0)](https://travis-ci.org/mikestead/ecs-task-deploy) 4 | 5 | A script to increment an active task definition on [ECS](https://aws.amazon.com/ecs) with an updated Docker image, followed by a service update to use it. 6 | 7 | Sequence of steps performed by the script: 8 | 9 | 1. Download the active task definition of an ECS service. 10 | 1. Clone it. 11 | 1. Given the Docker image name provided, find *any* containers in the task definition with references to it and replace them with the new one. Docker tags are ignored when searching for a match. 12 | 1. Register this new task definition with ECS. 13 | 1. Update the service to use this new task definition, triggering a blue/green deployment. 14 | 15 | #### Environment Varaiables 16 | 17 | For all the container definitions found when looking up your defined `image`, you have the option to add or update environment variables for these. 18 | 19 | This can be done using the `--env` option. 20 | 21 | --env "SERVICE_URL=http://api.somedomain.com" 22 | 23 | You can supply as many of these as required. 24 | 25 | #### Spare Capacity 26 | 27 | In order to roll a blue/green deployment there must be spare capacity available to spin up a task based on your updated task definition. 28 | If there's not capacity to do this your deployment will fail. 29 | 30 | This can be done via ECS service `minimum healthy percent` but as a brute force option this tool supports `--kill-task`. 31 | This will attempt to stop an existing task, making way for the blue/green rollout. 32 | 33 | If you're only running a single task you'll experience some down time. **Use at your own risk.** 34 | 35 | #### Usage 36 | 37 | ecs-task-deploy [options] 38 | 39 | Options: 40 | 41 | -h, --help output usage information 42 | -V, --version output the version number 43 | -k, --aws-access-key aws access key, or via AWS_ACCESS_KEY_ID env variable 44 | -s, --aws-secret-key aws secret key, or via AWS_SECRET_ACCESS_KEY env variable 45 | -r, --region aws region, or via AWS_DEFAULT_REGION env variable. 46 | -c, --cluster ecs cluster, or via AWS_ECS_CLUSTER env variable 47 | -n, --service ecs service, or via AWS_ECS_SERVICE_NAME env variable 48 | -i, --image docker image for task definition, or via AWS_ECS_TASK_IMAGE env variable 49 | -t, --timeout max timeout (sec) for ECS service to launch new task, defaults to 90s 50 | -v, --verbose enable verbose mode 51 | -e, --env environment variable in "=" format 52 | --kill-task stop a running task to allow space for a rolling blue/green deployment 53 | 54 | ##### Node 55 | 56 | To run via cli. 57 | 58 | npm install -g ecs-task-deploy 59 | 60 | ```javascript 61 | ecs-task-deploy \ 62 | -k 'ABCD' \ 63 | -s 'SECRET' \ 64 | -r 'us-west-1' \ 65 | -c 'qa' \ 66 | -n 'website-service' \ 67 | -i '44444444.ddd.ecr.us-east-1.amazonaws.com/website:1.0.2' \ 68 | -e 'SERVICE_URL=http://api.somedomain.com' \ 69 | -e 'API_KEY=clientapikey' \ 70 | -v 71 | ``` 72 | 73 | To run in code. 74 | 75 | npm install ecs-task-deploy --save 76 | 77 | ```javascript 78 | const ecsTaskDeploy = require('ecs-task-deploy') 79 | 80 | ecsTaskDeploy({ 81 | awsAccessKey: 'ABCD', 82 | awsSecretKey: 'SECRET', 83 | region: 'us-east-1', 84 | cluster: 'cache-cluster', 85 | service: 'cache-service', 86 | image: 'redis:2.8', 87 | env: { 88 | SERVICE_URL: 'http://api.somedomain.com', 89 | API_KEY: 'clientapikey' 90 | } 91 | }) 92 | .then( 93 | newTask => console.info(`Task '${newTask.taskDefinitionArn}' created and deployed`), 94 | e => console.error(e) 95 | ) 96 | ``` 97 | 98 | ##### Docker 99 | 100 | Run with arguments. 101 | 102 | docker run --rm stead/ecs-task-deploy \ 103 | -k \ 104 | -s \ 105 | -r \ 106 | -c \ 107 | -n \ 108 | -i 109 | 110 | Run with standard AWS environment variables. 111 | 112 | docker run --rm \ 113 | -e AWS_DEFAULT_REGION= \ 114 | -e AWS_ACCESS_KEY_ID= \ 115 | -e AWS_SECRET_ACCESS_KEY= \ 116 | stead/ecs-task-deploy \ 117 | -c \ 118 | -n \ 119 | -i 120 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ecs-task-deploy", 3 | "version": "1.3.1", 4 | "description": "Update an ECS task definition with Docker image and trigger blue/green deployment", 5 | "keywords": [ 6 | "aws", 7 | "ecs", 8 | "deploy", 9 | "docker" 10 | ], 11 | "author": { 12 | "name": "Mike Stead", 13 | "url": "https://github.com/mikestead" 14 | }, 15 | "license": "MIT", 16 | "homepage": "https://github.com/mikestead/ecs-task-deploy", 17 | "repository": { 18 | "type": "git", 19 | "url": "https://github.com/mikestead/ecs-task-deploy.git" 20 | }, 21 | "bugs": { 22 | "url": "https://github.com/mikestead/ecs-task-deploy/issues" 23 | }, 24 | "engines": { 25 | "node": ">=4.0.0", 26 | "npm": ">=2.14.2" 27 | }, 28 | "main": "src/index.js", 29 | "bin": { 30 | "ecs-task-deploy": "src/run.js" 31 | }, 32 | "scripts": { 33 | "lint": "eslint src" 34 | }, 35 | "dependencies": { 36 | "aws-sdk": "^2.28.0", 37 | "aws-sdk-promise": "0.0.2", 38 | "chalk": "^1.1.3", 39 | "commander": "^2.9.0" 40 | }, 41 | "devDependencies": { 42 | "eslint": "^3.18.0" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const AWS = require('aws-sdk-promise') 4 | const assert = require('assert') 5 | 6 | module.exports = execute 7 | 8 | function execute(options) { 9 | return verifyOptions(options) 10 | .then(deployTaskDefinition) 11 | } 12 | 13 | function verifyOptions(options) { 14 | try { 15 | assert.ok(options.awsAccessKey, 'AWS access key missing') 16 | assert.ok(options.awsSecretKey, 'AWS secret key missing') 17 | assert.ok(options.region, 'AWS region missing') 18 | assert.ok(options.cluster, 'ECS cluster name missing') 19 | assert.ok(options.service, 'ECS service name missing') 20 | assert.ok(options.image, 'ECS image name missing') 21 | 22 | process.env.AWS_ACCESS_KEY_ID = options.awsAccessKey 23 | process.env.AWS_SECRET_ACCESS_KEY = options.awsSecretKey 24 | options.image = parseImagePath(options.image) 25 | if (!options.timeout) options.timeout = 180 26 | 27 | // convert our env variable map into an array to closer match ECS task def format 28 | options.env = options.env 29 | ? Object.keys(options.env).map(name => ({ name, value: options.env[name] })) 30 | : [] 31 | 32 | return Promise.resolve(options) 33 | } catch(e) { 34 | return Promise.reject(e) 35 | } 36 | } 37 | 38 | function deployTaskDefinition(options) { 39 | const ecs = new AWS.ECS({ region: options.region }) 40 | return getService(ecs, options) 41 | .then(service => getActiveTaskDefinition(ecs, service, options)) 42 | .then(taskDef => addNewTaskDefinition(ecs, taskDef, options)) 43 | .then(taskDef => updateService(ecs, taskDef, options)) 44 | .then(service => checkForTaskKill(ecs, service, options)) 45 | .then(service => waitForServiceUpdate(ecs, service, options)) 46 | } 47 | 48 | function getService(ecs, options) { 49 | return ecs.describeServices({ cluster: options.cluster, services: [ options.service ] }).promise() 50 | .then(res => res.data.services.find(service => service.serviceName == options.service)) 51 | .then(service => { 52 | assert.ok(service, `Service ${options.service} not found, aborting.`) 53 | return service 54 | }) 55 | } 56 | 57 | function getActiveTaskDefinition(ecs, service, options) { 58 | if (options.verbose) console.info('get active task definition') 59 | return ecs.describeTaskDefinition({ taskDefinition: service.taskDefinition }).promise().then(res => res.data.taskDefinition) 60 | } 61 | 62 | function addNewTaskDefinition(ecs, template, options) { 63 | if (options.verbose) console.info(`registering new task definition with image '${options.image.uri}'`) 64 | const newTaskDef = newTaskDefinition(template, options) 65 | return ecs.registerTaskDefinition(newTaskDef).promise().then(res => res.data.taskDefinition) 66 | } 67 | 68 | function newTaskDefinition(template, options) { 69 | const containerDefinitions = template.containerDefinitions.map(c => Object.assign({}, c)) 70 | const containers = containerDefinitions.filter(c => parseImagePath(c.image).id === options.image.id) 71 | assert.ok(containers.length, `No container definitions found with image '${options.image.id}', aborting.`) 72 | containers.forEach(c => { 73 | c.image = options.image.uri 74 | c.environment = getEnvVariables(c.environment, options) 75 | }) 76 | 77 | return { 78 | family: template.family, 79 | volumes: template.volumes, 80 | containerDefinitions, 81 | taskRoleArn: template.taskRoleArn 82 | } 83 | } 84 | /* 85 | Overwrites an env variable if it exists, adds it if it doesn't 86 | */ 87 | function getEnvVariables(existing, options) { 88 | if (!options.env.length) return existing 89 | const vars = existing || [] 90 | options.env.forEach(env => { 91 | const copy = Object.assign({}, env) 92 | const i = vars.findIndex(v => v.name === copy.name) 93 | if (~i) vars[i] = copy 94 | else vars.push(copy) 95 | }) 96 | return vars 97 | } 98 | 99 | function parseImagePath(uri) { 100 | const segments = (uri || '').split('/') 101 | const last = segments.pop() 102 | const parts = last.split(':') 103 | const tag = parts.length > 1 ? parts.pop() : '' 104 | const id = segments.concat([ parts.join(':') ]).join('/') 105 | return { uri, id, tag } 106 | } 107 | 108 | function updateService(ecs, taskDef, options) { 109 | if (options.verbose) console.info(`update service with new task definition '${taskDef.taskDefinitionArn}'`) 110 | const serviceOptions = createServiceOptions(taskDef, options) 111 | return ecs.updateService(serviceOptions).promise().then(res => ({ info: res.data.service, taskDef })) 112 | } 113 | 114 | function createServiceOptions(taskDef, options) { 115 | return { 116 | cluster: options.cluster, 117 | service: options.service, 118 | taskDefinition: taskDef.taskDefinitionArn 119 | } 120 | } 121 | 122 | function checkForTaskKill(ecs, service, options) { 123 | if (options.killTask) { 124 | if (options.verbose) console.info('searching for running task to stop') 125 | return ecs.listTasks({ cluster: options.cluster, serviceName: options.service }).promise().then(res => { 126 | if (res.data && res.data.taskArns && res.data.taskArns.length) { 127 | const task = res.data.taskArns[0] 128 | if (options.verbose) console.info(`stopping task '${task}'`) 129 | return ecs.stopTask({ cluster: options.cluster, task, reason: 'Making room for blue/green deployment' }).promise() 130 | .then(() => { 131 | if (options.verbose) console.info(`task '${task}' stopped`) 132 | }, (error) => { 133 | console.warn(`failed to stop task '${task}'`, error) 134 | }) 135 | } else { 136 | console.info('failed to find a running task to stop') 137 | } 138 | }, (error) => { 139 | console.warn(`failed to list tasks under service '${options.service}' in cluster '${options.cluster}'`, error) 140 | }) 141 | .then(() => service) 142 | .catch(() => service) 143 | } 144 | return service 145 | } 146 | 147 | function waitForServiceUpdate(ecs, service, options) { 148 | return new Promise((resolve, reject) => { 149 | const WAIT_TIME = 1000 150 | const MAX_TIMEOUT = options.timeout * 1000 151 | const START_TIME = Date.now() 152 | 153 | function wait() { 154 | if (options.verbose) { 155 | const remaining = MAX_TIMEOUT - (Date.now() - START_TIME) 156 | console.info(`waiting for service update, ${Math.round(remaining / 1000)}s remaining...`) 157 | } 158 | ecs.listTasks({ 159 | cluster: service.info.clusterArn, 160 | serviceName: service.info.serviceName, 161 | desiredStatus: 'RUNNING' 162 | }).promise().then(res => { 163 | const tasks = res.data.taskArns || [] 164 | if (tasks.length) { 165 | ecs.describeTasks({ 166 | tasks, 167 | cluster: service.info.clusterArn 168 | }).promise().then(res => { 169 | const task = res.data.tasks.find(task => task.taskDefinitionArn === service.taskDef.taskDefinitionArn) 170 | if (task) { 171 | resolve(task) 172 | } else if (Date.now() - START_TIME > MAX_TIMEOUT) { 173 | reject(new Error('timeout waiting for service to launch new task definition')) 174 | } else { 175 | setTimeout(wait, WAIT_TIME) 176 | } 177 | }) 178 | .catch(e => reject(e)) 179 | } else if (Date.now() - START_TIME > MAX_TIMEOUT) { 180 | reject(new Error('timeout waiting for service to launch new task definition')) 181 | } else { 182 | setTimeout(wait, WAIT_TIME) 183 | } 184 | }) 185 | } 186 | wait() 187 | }) 188 | } 189 | -------------------------------------------------------------------------------- /src/run.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict' 3 | 4 | const program = require('commander') 5 | const chalk = require('chalk') 6 | const execute = require('./index') 7 | const env = process.env 8 | 9 | program 10 | .version(require('./../package.json').version) 11 | .option('-k, --aws-access-key ', 'aws access key, can be defined via AWS_ACCESS_KEY_ID env variable', String, env.AWS_ACCESS_KEY_ID) 12 | .option('-s, --aws-secret-key ', 'aws secret key, can be defined via AWS_SECRET_ACCESS_KEY env variable', String, env.AWS_SECRET_ACCESS_KEY) 13 | .option('-r, --region ', 'aws region, can be defined via AWS_DEFAULT_REGION env variable.', String, env.AWS_DEFAULT_REGION) 14 | .option('-c, --cluster ', 'ecs cluster, can be defined via AWS_ECS_CLUSTER env variable', String, env.AWS_ECS_CLUSTER) 15 | .option('-n, --service ', 'ecs service, can be defined via AWS_ECS_SERVICE_NAME env variable', String, env.AWS_ECS_SERVICE_NAME) 16 | .option('-i, --image ', 'docker image to use in new task definition e.g. user/image:tag, can be defined via AWS_ECS_TASK_IMAGE env variable', String, env.AWS_ECS_TASK_IMAGE) 17 | .option('-t, --timeout ', 'maximum timeout (sec) to wait for ECS service to launch new task, defaults to 180', parseInt, '180') 18 | .option('-v, --verbose', 'enable verbose mode') 19 | .option('-e, --env ', 'environment variable in "=" format', toKvps, {}) 20 | .option('--kill-task', 'stop a running task to allow space for a rolling blue/green deployment') 21 | .parse(process.argv) 22 | 23 | execute(program) 24 | .then(newTask => complete(newTask), e => error(e)) 25 | 26 | 27 | function toKvps(val, map) { 28 | const i = val.indexOf('=') 29 | if (i < 1) return map 30 | const name = val.slice(0, i) 31 | const value = val.slice(i+1) 32 | map[name] = value 33 | return map 34 | } 35 | 36 | function complete(newTask) { 37 | console.info(chalk.bold.cyan(`task '${newTask.taskDefinitionArn}' created and deployed`)) 38 | process.exit(0) 39 | } 40 | 41 | function error(e) { 42 | const msg = (e instanceof Error) ? e.message : e 43 | console.error(chalk.red(msg)) 44 | process.exit(1) 45 | } 46 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | acorn-jsx@^3.0.0: 6 | version "3.0.1" 7 | resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" 8 | dependencies: 9 | acorn "^3.0.4" 10 | 11 | acorn@4.0.4: 12 | version "4.0.4" 13 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.4.tgz#17a8d6a7a6c4ef538b814ec9abac2779293bf30a" 14 | 15 | acorn@^3.0.4: 16 | version "3.3.0" 17 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" 18 | 19 | ajv-keywords@^1.0.0: 20 | version "1.5.1" 21 | resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" 22 | 23 | ajv@^4.7.0: 24 | version "4.11.5" 25 | resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.5.tgz#b6ee74657b993a01dce44b7944d56f485828d5bd" 26 | dependencies: 27 | co "^4.6.0" 28 | json-stable-stringify "^1.0.1" 29 | 30 | ansi-escapes@^1.1.0: 31 | version "1.4.0" 32 | resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" 33 | 34 | ansi-regex@^2.0.0: 35 | version "2.1.1" 36 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 37 | 38 | ansi-styles@^2.2.1: 39 | version "2.2.1" 40 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 41 | 42 | argparse@^1.0.7: 43 | version "1.0.9" 44 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" 45 | dependencies: 46 | sprintf-js "~1.0.2" 47 | 48 | array-union@^1.0.1: 49 | version "1.0.2" 50 | resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" 51 | dependencies: 52 | array-uniq "^1.0.1" 53 | 54 | array-uniq@^1.0.1: 55 | version "1.0.3" 56 | resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" 57 | 58 | arrify@^1.0.0: 59 | version "1.0.1" 60 | resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" 61 | 62 | asap@~1.0.0: 63 | version "1.0.0" 64 | resolved "https://registry.yarnpkg.com/asap/-/asap-1.0.0.tgz#b2a45da5fdfa20b0496fc3768cc27c12fa916a7d" 65 | 66 | aws-sdk-promise@0.0.2: 67 | version "0.0.2" 68 | resolved "https://registry.yarnpkg.com/aws-sdk-promise/-/aws-sdk-promise-0.0.2.tgz#2886bd1fc4c47ebcb9afdd6c597cf4260fb9e5e8" 69 | dependencies: 70 | promise "^6.1.0" 71 | 72 | aws-sdk@^2.28.0: 73 | version "2.28.0" 74 | resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.28.0.tgz#0b7628c5d48820187332c5a30835945c41f84f46" 75 | dependencies: 76 | buffer "4.9.1" 77 | crypto-browserify "1.0.9" 78 | jmespath "0.15.0" 79 | querystring "0.2.0" 80 | sax "1.1.5" 81 | url "0.10.3" 82 | uuid "3.0.0" 83 | xml2js "0.4.15" 84 | xmlbuilder "2.6.2" 85 | 86 | babel-code-frame@^6.16.0: 87 | version "6.22.0" 88 | resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" 89 | dependencies: 90 | chalk "^1.1.0" 91 | esutils "^2.0.2" 92 | js-tokens "^3.0.0" 93 | 94 | balanced-match@^0.4.1: 95 | version "0.4.2" 96 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" 97 | 98 | base64-js@^1.0.2: 99 | version "1.2.0" 100 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1" 101 | 102 | brace-expansion@^1.0.0: 103 | version "1.1.6" 104 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" 105 | dependencies: 106 | balanced-match "^0.4.1" 107 | concat-map "0.0.1" 108 | 109 | buffer-shims@^1.0.0: 110 | version "1.0.0" 111 | resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" 112 | 113 | buffer@4.9.1: 114 | version "4.9.1" 115 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" 116 | dependencies: 117 | base64-js "^1.0.2" 118 | ieee754 "^1.1.4" 119 | isarray "^1.0.0" 120 | 121 | caller-path@^0.1.0: 122 | version "0.1.0" 123 | resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" 124 | dependencies: 125 | callsites "^0.2.0" 126 | 127 | callsites@^0.2.0: 128 | version "0.2.0" 129 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" 130 | 131 | chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: 132 | version "1.1.3" 133 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 134 | dependencies: 135 | ansi-styles "^2.2.1" 136 | escape-string-regexp "^1.0.2" 137 | has-ansi "^2.0.0" 138 | strip-ansi "^3.0.0" 139 | supports-color "^2.0.0" 140 | 141 | circular-json@^0.3.1: 142 | version "0.3.1" 143 | resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d" 144 | 145 | cli-cursor@^1.0.1: 146 | version "1.0.2" 147 | resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" 148 | dependencies: 149 | restore-cursor "^1.0.1" 150 | 151 | cli-width@^2.0.0: 152 | version "2.1.0" 153 | resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a" 154 | 155 | co@^4.6.0: 156 | version "4.6.0" 157 | resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" 158 | 159 | code-point-at@^1.0.0: 160 | version "1.1.0" 161 | resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" 162 | 163 | commander@^2.9.0: 164 | version "2.9.0" 165 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" 166 | dependencies: 167 | graceful-readlink ">= 1.0.0" 168 | 169 | concat-map@0.0.1: 170 | version "0.0.1" 171 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 172 | 173 | concat-stream@^1.5.2: 174 | version "1.6.0" 175 | resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" 176 | dependencies: 177 | inherits "^2.0.3" 178 | readable-stream "^2.2.2" 179 | typedarray "^0.0.6" 180 | 181 | core-util-is@~1.0.0: 182 | version "1.0.2" 183 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 184 | 185 | crypto-browserify@1.0.9: 186 | version "1.0.9" 187 | resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-1.0.9.tgz#cc5449685dfb85eb11c9828acc7cb87ab5bbfcc0" 188 | 189 | d@1: 190 | version "1.0.0" 191 | resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" 192 | dependencies: 193 | es5-ext "^0.10.9" 194 | 195 | debug@^2.1.1: 196 | version "2.6.3" 197 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.3.tgz#0f7eb8c30965ec08c72accfa0130c8b79984141d" 198 | dependencies: 199 | ms "0.7.2" 200 | 201 | deep-is@~0.1.3: 202 | version "0.1.3" 203 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" 204 | 205 | del@^2.0.2: 206 | version "2.2.2" 207 | resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" 208 | dependencies: 209 | globby "^5.0.0" 210 | is-path-cwd "^1.0.0" 211 | is-path-in-cwd "^1.0.0" 212 | object-assign "^4.0.1" 213 | pify "^2.0.0" 214 | pinkie-promise "^2.0.0" 215 | rimraf "^2.2.8" 216 | 217 | doctrine@^2.0.0: 218 | version "2.0.0" 219 | resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" 220 | dependencies: 221 | esutils "^2.0.2" 222 | isarray "^1.0.0" 223 | 224 | es5-ext@^0.10.14, es5-ext@^0.10.9, es5-ext@~0.10.14: 225 | version "0.10.14" 226 | resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.14.tgz#625bc9ab9cac0f6fb9dc271525823d1800b3d360" 227 | dependencies: 228 | es6-iterator "2" 229 | es6-symbol "~3.1" 230 | 231 | es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1: 232 | version "2.0.1" 233 | resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512" 234 | dependencies: 235 | d "1" 236 | es5-ext "^0.10.14" 237 | es6-symbol "^3.1" 238 | 239 | es6-map@^0.1.3: 240 | version "0.1.5" 241 | resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" 242 | dependencies: 243 | d "1" 244 | es5-ext "~0.10.14" 245 | es6-iterator "~2.0.1" 246 | es6-set "~0.1.5" 247 | es6-symbol "~3.1.1" 248 | event-emitter "~0.3.5" 249 | 250 | es6-set@~0.1.5: 251 | version "0.1.5" 252 | resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" 253 | dependencies: 254 | d "1" 255 | es5-ext "~0.10.14" 256 | es6-iterator "~2.0.1" 257 | es6-symbol "3.1.1" 258 | event-emitter "~0.3.5" 259 | 260 | es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1: 261 | version "3.1.1" 262 | resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" 263 | dependencies: 264 | d "1" 265 | es5-ext "~0.10.14" 266 | 267 | es6-weak-map@^2.0.1: 268 | version "2.0.2" 269 | resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f" 270 | dependencies: 271 | d "1" 272 | es5-ext "^0.10.14" 273 | es6-iterator "^2.0.1" 274 | es6-symbol "^3.1.1" 275 | 276 | escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: 277 | version "1.0.5" 278 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 279 | 280 | escope@^3.6.0: 281 | version "3.6.0" 282 | resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3" 283 | dependencies: 284 | es6-map "^0.1.3" 285 | es6-weak-map "^2.0.1" 286 | esrecurse "^4.1.0" 287 | estraverse "^4.1.1" 288 | 289 | eslint@^3.18.0: 290 | version "3.18.0" 291 | resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.18.0.tgz#647e985c4ae71502d20ac62c109f66d5104c8a4b" 292 | dependencies: 293 | babel-code-frame "^6.16.0" 294 | chalk "^1.1.3" 295 | concat-stream "^1.5.2" 296 | debug "^2.1.1" 297 | doctrine "^2.0.0" 298 | escope "^3.6.0" 299 | espree "^3.4.0" 300 | esquery "^1.0.0" 301 | estraverse "^4.2.0" 302 | esutils "^2.0.2" 303 | file-entry-cache "^2.0.0" 304 | glob "^7.0.3" 305 | globals "^9.14.0" 306 | ignore "^3.2.0" 307 | imurmurhash "^0.1.4" 308 | inquirer "^0.12.0" 309 | is-my-json-valid "^2.10.0" 310 | is-resolvable "^1.0.0" 311 | js-yaml "^3.5.1" 312 | json-stable-stringify "^1.0.0" 313 | levn "^0.3.0" 314 | lodash "^4.0.0" 315 | mkdirp "^0.5.0" 316 | natural-compare "^1.4.0" 317 | optionator "^0.8.2" 318 | path-is-inside "^1.0.1" 319 | pluralize "^1.2.1" 320 | progress "^1.1.8" 321 | require-uncached "^1.0.2" 322 | shelljs "^0.7.5" 323 | strip-bom "^3.0.0" 324 | strip-json-comments "~2.0.1" 325 | table "^3.7.8" 326 | text-table "~0.2.0" 327 | user-home "^2.0.0" 328 | 329 | espree@^3.4.0: 330 | version "3.4.0" 331 | resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.0.tgz#41656fa5628e042878025ef467e78f125cb86e1d" 332 | dependencies: 333 | acorn "4.0.4" 334 | acorn-jsx "^3.0.0" 335 | 336 | esprima@^3.1.1: 337 | version "3.1.3" 338 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" 339 | 340 | esquery@^1.0.0: 341 | version "1.0.0" 342 | resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" 343 | dependencies: 344 | estraverse "^4.0.0" 345 | 346 | esrecurse@^4.1.0: 347 | version "4.1.0" 348 | resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.1.0.tgz#4713b6536adf7f2ac4f327d559e7756bff648220" 349 | dependencies: 350 | estraverse "~4.1.0" 351 | object-assign "^4.0.1" 352 | 353 | estraverse@^4.0.0, estraverse@^4.1.1, estraverse@^4.2.0: 354 | version "4.2.0" 355 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" 356 | 357 | estraverse@~4.1.0: 358 | version "4.1.1" 359 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.1.1.tgz#f6caca728933a850ef90661d0e17982ba47111a2" 360 | 361 | esutils@^2.0.2: 362 | version "2.0.2" 363 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" 364 | 365 | event-emitter@~0.3.5: 366 | version "0.3.5" 367 | resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" 368 | dependencies: 369 | d "1" 370 | es5-ext "~0.10.14" 371 | 372 | exit-hook@^1.0.0: 373 | version "1.1.1" 374 | resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" 375 | 376 | fast-levenshtein@~2.0.4: 377 | version "2.0.6" 378 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" 379 | 380 | figures@^1.3.5: 381 | version "1.7.0" 382 | resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" 383 | dependencies: 384 | escape-string-regexp "^1.0.5" 385 | object-assign "^4.1.0" 386 | 387 | file-entry-cache@^2.0.0: 388 | version "2.0.0" 389 | resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" 390 | dependencies: 391 | flat-cache "^1.2.1" 392 | object-assign "^4.0.1" 393 | 394 | flat-cache@^1.2.1: 395 | version "1.2.2" 396 | resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96" 397 | dependencies: 398 | circular-json "^0.3.1" 399 | del "^2.0.2" 400 | graceful-fs "^4.1.2" 401 | write "^0.2.1" 402 | 403 | fs.realpath@^1.0.0: 404 | version "1.0.0" 405 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 406 | 407 | generate-function@^2.0.0: 408 | version "2.0.0" 409 | resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74" 410 | 411 | generate-object-property@^1.1.0: 412 | version "1.2.0" 413 | resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" 414 | dependencies: 415 | is-property "^1.0.0" 416 | 417 | glob@^7.0.0, glob@^7.0.3, glob@^7.0.5: 418 | version "7.1.1" 419 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" 420 | dependencies: 421 | fs.realpath "^1.0.0" 422 | inflight "^1.0.4" 423 | inherits "2" 424 | minimatch "^3.0.2" 425 | once "^1.3.0" 426 | path-is-absolute "^1.0.0" 427 | 428 | globals@^9.14.0: 429 | version "9.16.0" 430 | resolved "https://registry.yarnpkg.com/globals/-/globals-9.16.0.tgz#63e903658171ec2d9f51b1d31de5e2b8dc01fb80" 431 | 432 | globby@^5.0.0: 433 | version "5.0.0" 434 | resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" 435 | dependencies: 436 | array-union "^1.0.1" 437 | arrify "^1.0.0" 438 | glob "^7.0.3" 439 | object-assign "^4.0.1" 440 | pify "^2.0.0" 441 | pinkie-promise "^2.0.0" 442 | 443 | graceful-fs@^4.1.2: 444 | version "4.1.11" 445 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" 446 | 447 | "graceful-readlink@>= 1.0.0": 448 | version "1.0.1" 449 | resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" 450 | 451 | has-ansi@^2.0.0: 452 | version "2.0.0" 453 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 454 | dependencies: 455 | ansi-regex "^2.0.0" 456 | 457 | ieee754@^1.1.4: 458 | version "1.1.8" 459 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" 460 | 461 | ignore@^3.2.0: 462 | version "3.2.6" 463 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.2.6.tgz#26e8da0644be0bb4cb39516f6c79f0e0f4ffe48c" 464 | 465 | imurmurhash@^0.1.4: 466 | version "0.1.4" 467 | resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" 468 | 469 | inflight@^1.0.4: 470 | version "1.0.6" 471 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 472 | dependencies: 473 | once "^1.3.0" 474 | wrappy "1" 475 | 476 | inherits@2, inherits@^2.0.3, inherits@~2.0.1: 477 | version "2.0.3" 478 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 479 | 480 | inquirer@^0.12.0: 481 | version "0.12.0" 482 | resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e" 483 | dependencies: 484 | ansi-escapes "^1.1.0" 485 | ansi-regex "^2.0.0" 486 | chalk "^1.0.0" 487 | cli-cursor "^1.0.1" 488 | cli-width "^2.0.0" 489 | figures "^1.3.5" 490 | lodash "^4.3.0" 491 | readline2 "^1.0.1" 492 | run-async "^0.1.0" 493 | rx-lite "^3.1.2" 494 | string-width "^1.0.1" 495 | strip-ansi "^3.0.0" 496 | through "^2.3.6" 497 | 498 | interpret@^1.0.0: 499 | version "1.0.1" 500 | resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.1.tgz#d579fb7f693b858004947af39fa0db49f795602c" 501 | 502 | is-fullwidth-code-point@^1.0.0: 503 | version "1.0.0" 504 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" 505 | dependencies: 506 | number-is-nan "^1.0.0" 507 | 508 | is-fullwidth-code-point@^2.0.0: 509 | version "2.0.0" 510 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 511 | 512 | is-my-json-valid@^2.10.0: 513 | version "2.16.0" 514 | resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693" 515 | dependencies: 516 | generate-function "^2.0.0" 517 | generate-object-property "^1.1.0" 518 | jsonpointer "^4.0.0" 519 | xtend "^4.0.0" 520 | 521 | is-path-cwd@^1.0.0: 522 | version "1.0.0" 523 | resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" 524 | 525 | is-path-in-cwd@^1.0.0: 526 | version "1.0.0" 527 | resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" 528 | dependencies: 529 | is-path-inside "^1.0.0" 530 | 531 | is-path-inside@^1.0.0: 532 | version "1.0.0" 533 | resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" 534 | dependencies: 535 | path-is-inside "^1.0.1" 536 | 537 | is-property@^1.0.0: 538 | version "1.0.2" 539 | resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" 540 | 541 | is-resolvable@^1.0.0: 542 | version "1.0.0" 543 | resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" 544 | dependencies: 545 | tryit "^1.0.1" 546 | 547 | isarray@^1.0.0, isarray@~1.0.0: 548 | version "1.0.0" 549 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 550 | 551 | jmespath@0.15.0: 552 | version "0.15.0" 553 | resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" 554 | 555 | js-tokens@^3.0.0: 556 | version "3.0.1" 557 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" 558 | 559 | js-yaml@^3.5.1: 560 | version "3.8.2" 561 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.2.tgz#02d3e2c0f6beab20248d412c352203827d786721" 562 | dependencies: 563 | argparse "^1.0.7" 564 | esprima "^3.1.1" 565 | 566 | json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1: 567 | version "1.0.1" 568 | resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" 569 | dependencies: 570 | jsonify "~0.0.0" 571 | 572 | jsonify@~0.0.0: 573 | version "0.0.0" 574 | resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" 575 | 576 | jsonpointer@^4.0.0: 577 | version "4.0.1" 578 | resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9" 579 | 580 | levn@^0.3.0, levn@~0.3.0: 581 | version "0.3.0" 582 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" 583 | dependencies: 584 | prelude-ls "~1.1.2" 585 | type-check "~0.3.2" 586 | 587 | lodash@^4.0.0, lodash@^4.3.0: 588 | version "4.17.4" 589 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" 590 | 591 | lodash@~3.5.0: 592 | version "3.5.0" 593 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.5.0.tgz#19bb3f4d51278f0b8c818ed145c74ecf9fe40e6d" 594 | 595 | minimatch@^3.0.2: 596 | version "3.0.3" 597 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" 598 | dependencies: 599 | brace-expansion "^1.0.0" 600 | 601 | minimist@0.0.8: 602 | version "0.0.8" 603 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 604 | 605 | mkdirp@^0.5.0, mkdirp@^0.5.1: 606 | version "0.5.1" 607 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 608 | dependencies: 609 | minimist "0.0.8" 610 | 611 | ms@0.7.2: 612 | version "0.7.2" 613 | resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" 614 | 615 | mute-stream@0.0.5: 616 | version "0.0.5" 617 | resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0" 618 | 619 | natural-compare@^1.4.0: 620 | version "1.4.0" 621 | resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" 622 | 623 | number-is-nan@^1.0.0: 624 | version "1.0.1" 625 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" 626 | 627 | object-assign@^4.0.1, object-assign@^4.1.0: 628 | version "4.1.1" 629 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 630 | 631 | once@^1.3.0: 632 | version "1.4.0" 633 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 634 | dependencies: 635 | wrappy "1" 636 | 637 | onetime@^1.0.0: 638 | version "1.1.0" 639 | resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" 640 | 641 | optionator@^0.8.2: 642 | version "0.8.2" 643 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" 644 | dependencies: 645 | deep-is "~0.1.3" 646 | fast-levenshtein "~2.0.4" 647 | levn "~0.3.0" 648 | prelude-ls "~1.1.2" 649 | type-check "~0.3.2" 650 | wordwrap "~1.0.0" 651 | 652 | os-homedir@^1.0.0: 653 | version "1.0.2" 654 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" 655 | 656 | path-is-absolute@^1.0.0: 657 | version "1.0.1" 658 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 659 | 660 | path-is-inside@^1.0.1: 661 | version "1.0.2" 662 | resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" 663 | 664 | path-parse@^1.0.5: 665 | version "1.0.5" 666 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" 667 | 668 | pify@^2.0.0: 669 | version "2.3.0" 670 | resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" 671 | 672 | pinkie-promise@^2.0.0: 673 | version "2.0.1" 674 | resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" 675 | dependencies: 676 | pinkie "^2.0.0" 677 | 678 | pinkie@^2.0.0: 679 | version "2.0.4" 680 | resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" 681 | 682 | pluralize@^1.2.1: 683 | version "1.2.1" 684 | resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45" 685 | 686 | prelude-ls@~1.1.2: 687 | version "1.1.2" 688 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" 689 | 690 | process-nextick-args@~1.0.6: 691 | version "1.0.7" 692 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" 693 | 694 | progress@^1.1.8: 695 | version "1.1.8" 696 | resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be" 697 | 698 | promise@^6.1.0: 699 | version "6.1.0" 700 | resolved "https://registry.yarnpkg.com/promise/-/promise-6.1.0.tgz#2ce729f6b94b45c26891ad0602c5c90e04c6eef6" 701 | dependencies: 702 | asap "~1.0.0" 703 | 704 | punycode@1.3.2: 705 | version "1.3.2" 706 | resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" 707 | 708 | querystring@0.2.0: 709 | version "0.2.0" 710 | resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" 711 | 712 | readable-stream@^2.2.2: 713 | version "2.2.6" 714 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.6.tgz#8b43aed76e71483938d12a8d46c6cf1a00b1f816" 715 | dependencies: 716 | buffer-shims "^1.0.0" 717 | core-util-is "~1.0.0" 718 | inherits "~2.0.1" 719 | isarray "~1.0.0" 720 | process-nextick-args "~1.0.6" 721 | string_decoder "~0.10.x" 722 | util-deprecate "~1.0.1" 723 | 724 | readline2@^1.0.1: 725 | version "1.0.1" 726 | resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35" 727 | dependencies: 728 | code-point-at "^1.0.0" 729 | is-fullwidth-code-point "^1.0.0" 730 | mute-stream "0.0.5" 731 | 732 | rechoir@^0.6.2: 733 | version "0.6.2" 734 | resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" 735 | dependencies: 736 | resolve "^1.1.6" 737 | 738 | require-uncached@^1.0.2: 739 | version "1.0.3" 740 | resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" 741 | dependencies: 742 | caller-path "^0.1.0" 743 | resolve-from "^1.0.0" 744 | 745 | resolve-from@^1.0.0: 746 | version "1.0.1" 747 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" 748 | 749 | resolve@^1.1.6: 750 | version "1.3.2" 751 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.2.tgz#1f0442c9e0cbb8136e87b9305f932f46c7f28235" 752 | dependencies: 753 | path-parse "^1.0.5" 754 | 755 | restore-cursor@^1.0.1: 756 | version "1.0.1" 757 | resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" 758 | dependencies: 759 | exit-hook "^1.0.0" 760 | onetime "^1.0.0" 761 | 762 | rimraf@^2.2.8: 763 | version "2.6.1" 764 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" 765 | dependencies: 766 | glob "^7.0.5" 767 | 768 | run-async@^0.1.0: 769 | version "0.1.0" 770 | resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389" 771 | dependencies: 772 | once "^1.3.0" 773 | 774 | rx-lite@^3.1.2: 775 | version "3.1.2" 776 | resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102" 777 | 778 | sax@1.1.5, sax@>=0.6.0: 779 | version "1.1.5" 780 | resolved "https://registry.yarnpkg.com/sax/-/sax-1.1.5.tgz#1da50a8d00cdecd59405659f5ff85349fe773743" 781 | 782 | shelljs@^0.7.5: 783 | version "0.7.7" 784 | resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.7.tgz#b2f5c77ef97148f4b4f6e22682e10bba8667cff1" 785 | dependencies: 786 | glob "^7.0.0" 787 | interpret "^1.0.0" 788 | rechoir "^0.6.2" 789 | 790 | slice-ansi@0.0.4: 791 | version "0.0.4" 792 | resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" 793 | 794 | sprintf-js@~1.0.2: 795 | version "1.0.3" 796 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 797 | 798 | string-width@^1.0.1: 799 | version "1.0.2" 800 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" 801 | dependencies: 802 | code-point-at "^1.0.0" 803 | is-fullwidth-code-point "^1.0.0" 804 | strip-ansi "^3.0.0" 805 | 806 | string-width@^2.0.0: 807 | version "2.0.0" 808 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.0.0.tgz#635c5436cc72a6e0c387ceca278d4e2eec52687e" 809 | dependencies: 810 | is-fullwidth-code-point "^2.0.0" 811 | strip-ansi "^3.0.0" 812 | 813 | string_decoder@~0.10.x: 814 | version "0.10.31" 815 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" 816 | 817 | strip-ansi@^3.0.0: 818 | version "3.0.1" 819 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 820 | dependencies: 821 | ansi-regex "^2.0.0" 822 | 823 | strip-bom@^3.0.0: 824 | version "3.0.0" 825 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" 826 | 827 | strip-json-comments@~2.0.1: 828 | version "2.0.1" 829 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" 830 | 831 | supports-color@^2.0.0: 832 | version "2.0.0" 833 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 834 | 835 | table@^3.7.8: 836 | version "3.8.3" 837 | resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f" 838 | dependencies: 839 | ajv "^4.7.0" 840 | ajv-keywords "^1.0.0" 841 | chalk "^1.1.1" 842 | lodash "^4.0.0" 843 | slice-ansi "0.0.4" 844 | string-width "^2.0.0" 845 | 846 | text-table@~0.2.0: 847 | version "0.2.0" 848 | resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" 849 | 850 | through@^2.3.6: 851 | version "2.3.8" 852 | resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" 853 | 854 | tryit@^1.0.1: 855 | version "1.0.3" 856 | resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" 857 | 858 | type-check@~0.3.2: 859 | version "0.3.2" 860 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" 861 | dependencies: 862 | prelude-ls "~1.1.2" 863 | 864 | typedarray@^0.0.6: 865 | version "0.0.6" 866 | resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" 867 | 868 | url@0.10.3: 869 | version "0.10.3" 870 | resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" 871 | dependencies: 872 | punycode "1.3.2" 873 | querystring "0.2.0" 874 | 875 | user-home@^2.0.0: 876 | version "2.0.0" 877 | resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" 878 | dependencies: 879 | os-homedir "^1.0.0" 880 | 881 | util-deprecate@~1.0.1: 882 | version "1.0.2" 883 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 884 | 885 | uuid@3.0.0: 886 | version "3.0.0" 887 | resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.0.tgz#6728fc0459c450d796a99c31837569bdf672d728" 888 | 889 | wordwrap@~1.0.0: 890 | version "1.0.0" 891 | resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" 892 | 893 | wrappy@1: 894 | version "1.0.2" 895 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 896 | 897 | write@^0.2.1: 898 | version "0.2.1" 899 | resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" 900 | dependencies: 901 | mkdirp "^0.5.1" 902 | 903 | xml2js@0.4.15: 904 | version "0.4.15" 905 | resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.15.tgz#95cd03ff2dd144ec28bc6273bf2b2890c581ad0c" 906 | dependencies: 907 | sax ">=0.6.0" 908 | xmlbuilder ">=2.4.6" 909 | 910 | xmlbuilder@2.6.2, xmlbuilder@>=2.4.6: 911 | version "2.6.2" 912 | resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-2.6.2.tgz#f916f6d10d45dc171b1be2e6e673fb6e0cc35d0a" 913 | dependencies: 914 | lodash "~3.5.0" 915 | 916 | xtend@^4.0.0: 917 | version "4.0.1" 918 | resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" 919 | --------------------------------------------------------------------------------