├── .eslintrc ├── .gitignore ├── LICENSE ├── README.md ├── bin └── main.js ├── lib ├── git.js ├── logger.js ├── render.js └── validator.js ├── package-lock.json └── package.json /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "airbnb-base", 3 | "env": { 4 | "node": true, 5 | "es6": true 6 | }, 7 | "rules": { 8 | "object-shorthand": "off", 9 | "arrow-parens": ["error", "always"], 10 | "comma-dangle": ["error", "never"], 11 | "no-shadow": ["off", { "hoist": "never", "builtinGlobals": true }], 12 | "max-len": ["off", 120], 13 | "array-bracket-spacing": ["off", "never"], 14 | "object-property-newline": "off", 15 | "no-sequences": "off", 16 | "no-param-reassign": ["error", { "props": false }], 17 | "no-unused-expressions": ["error", { "allowShortCircuit": true }], 18 | "padded-blocks": ["off", "always"], 19 | "arrow-body-style": ["off", "as-needed"], 20 | "no-use-before-define": ["error", { "functions": false, "classes": true }], 21 | "new-cap": ["error", { "properties": true, "capIsNewExceptionPattern": "^Awesomplete." }], 22 | "no-mixed-operators": ["error", {"groups": [["&", "|", "^", "~", "<<", ">>", ">>>"], ["&&", "||"]]}], 23 | "no-return-assign": "off", 24 | "consistent-return": "off", 25 | "default-case": "off", 26 | "no-plusplus": "off", 27 | "no-bitwise": "off", 28 | "no-debugger": "off", 29 | "prefer-template": "off", 30 | "class-methods-use-this": "off", 31 | "func-names": ["off", "never"], 32 | "prefer-destructuring": "off", 33 | "function-paren-newline": "off", 34 | "prefer-promise-reject-errors": "off", 35 | "no-console": "off", 36 | "object-curly-newline": "off", 37 | "space-before-function-paren": "off", 38 | "global-require": "off", 39 | "indent": "off" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .cache 2 | .DS_Store 3 | .forever 4 | .node-gyp 5 | .npm 6 | node_modules 7 | npm-debug.log 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 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 | # releaser 2 | 3 | A release note generator that reads and parses git commits and retrieves issue links from GitHub. 4 | 5 | ## Usage 6 | 7 | `releaser --dir --upstream / --token ` 8 | 9 | ## Arguments 10 | 11 | ``` 12 | --config [value] configuration file in js 13 | --dir read commits and tags from this local git directory 14 | --upstream GitHub / 15 | --token GitHub token 16 | --tag [value] get changelog from this tag 17 | --type [value] Type of new release (semver) 18 | -h, --help output usage information 19 | ``` 20 | 21 | ## Git 22 | By default, it expects the commits and tags to follow a specific format. 23 | 24 | ### Tags 25 | Tags are expected to follow the semver convention as `v1.0.0`. It is customizable through the `tagRegex` configuration option. 26 | 27 | ### Commits 28 | Commits are expected to follow the following convention: 29 | 30 | * `/(Fix|Close|Resolve) #(\d+)/g `: A commit name that matches this regex will automatically be resolved to the corresponding GitHub issue with the title of the issue as the name of the change. This is overridable through the `issueRegex` parameter in a configuration file. 31 | * `Hotfix - Message`: A commit name that starts with `Hotfix` will get included as `others` with Message as the name of the change. This is customisable through the `labels > local` parameter in a configuration file. 32 | 33 | ### Issue labels 34 | By default, only issues that contain the labels `[Bug, Feature]` will be included in the release notes. This is customisable through the `externalLabels` parameter in a configuration file. 35 | 36 | ## Render 37 | By default, the changelog is rendered in markdown. It is possible to override the rendering functions through the configuration file. 38 | 39 | ## Configuration 40 | Example `releaser.config.js`: 41 | 42 | ```javascript 43 | module.exports = { 44 | upstream: 'ProtonMail/WebClient', 45 | dir: '.', 46 | rotate: 5, 47 | tagRegex: 'v\d+.\d+.\d+', 48 | labels: { 49 | external: [{ match: 'Enhancement', name: 'Features' }, { match: 'Bug', name: 'Bugs' }], 50 | local: [{ match: /Hotfix [-~]? ?/, name: 'Others' }] 51 | }, 52 | render: { 53 | commit: function commit({ title, issueNumber, name }) { 54 | const issue = (number) => number && `#${number} ` || ''; 55 | return `* ${issue(issueNumber)}${title || name}`; 56 | } 57 | } 58 | }; 59 | 60 | ``` 61 | 62 | ## Author 63 | 64 | Mattias Svanström (@mmso) - ProtonMail 65 | -------------------------------------------------------------------------------- /bin/main.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const path = require('path'); 4 | const _ = require('lodash'); 5 | const commander = require('commander'); 6 | const fs = require('fs'); 7 | const validator = require('../lib/validator'); 8 | const git = require('../lib/git'); 9 | const render = require('../lib/render'); 10 | const Logger = require('../lib/logger'); 11 | const semver = require('semver'); 12 | 13 | const getNextVersion = (fromTagName, type) => { 14 | const [, currentTag ] = fromTagName.split('v'); 15 | const nextVersion = semver.inc(currentTag, type); 16 | return `v${nextVersion}`; 17 | }; 18 | 19 | /** 20 | * Run the main program. 21 | * @param {string} owner GitHub owner 22 | * @param {string} repo GitHub repo 23 | * @param {string} token GitHub token 24 | * @param {string} dir Git directory 25 | * @param {RegExp} issueRegex Regex to match external issues 26 | * @param {string} tag Name to start from 27 | * @param {RegExp} tagRegex Regex to tags 28 | * @param {Array} externalLabels External commit labels 29 | * @param {Array} localLabels Local commit labels 30 | * @param {Object} render Render functions. 31 | * @param {Object} logger Logger functions. 32 | * @param {String} type Type of release (semver) 33 | * @returns {Promise} 34 | */ 35 | async function main({ owner, repo, token, dir, issueRegex, tag, tagRegex, externalLabels, localLabels, render, logger, type }) { 36 | logger.progress(`Loading ${dir}`); 37 | 38 | // Get all tags. 39 | const { commits, from: fromTag, to: toTag } = await git.read({ dir, tag, tagRegex }); 40 | 41 | logger.success(`Found tags from ${fromTag.name} ${fromTag.date} to ${toTag.name} ${toTag.date}`); 42 | logger.success(`With ${commits.length} commits`); 43 | 44 | const { groupedCommits, issues } = await git.retrieve({ 45 | commits, 46 | issueRegex, 47 | owner, 48 | repo, 49 | token, 50 | externalLabels, 51 | localLabels, 52 | logger 53 | }); 54 | 55 | for (let i = 0; i < groupedCommits.length; ++i) { 56 | const { commits, name } = groupedCommits[i]; 57 | logger.success(`${commits.length} ${name} fixed`); 58 | } 59 | 60 | const { date, name: fromVersion } = fromTag; 61 | 62 | const data = render.all({ 63 | version: type ? getNextVersion(fromVersion, type) : fromVersion, 64 | date, 65 | issues, 66 | groupedCommits, 67 | render 68 | }); 69 | 70 | process.stdout.write(data); 71 | } 72 | 73 | /** 74 | * Reads a configuration file from a specified pathname. 75 | * @param {string} pathname 76 | * @returns {Object} 77 | */ 78 | function readConfiguration(pathname) { 79 | if (!pathname) { 80 | return {}; 81 | } 82 | const resolvedPathname = path.resolve(pathname); 83 | const fail = () => { 84 | console.error(`configuration file ${resolvedPathname} needs to be a valid js file`); 85 | process.exit(1); 86 | }; 87 | if (!pathname.endsWith('.js')) { 88 | fail(); 89 | } 90 | try { 91 | // eslint-disable-next-line import/no-dynamic-require 92 | const data = require(resolvedPathname); 93 | if (!_.isObject(data)) { 94 | fail(); 95 | } 96 | return data; 97 | } catch (e) { 98 | fail(); 99 | } 100 | } 101 | 102 | /** 103 | * Parses a list of arguments. 104 | * @param {Array} argv 105 | * @returns {Object} Parsed args. 106 | */ 107 | function parseCmd(argv) { 108 | commander 109 | .version('0.1.0') 110 | .option('--config [value]', 'configuration file in js') 111 | .option('--dir ', 'read commits and tags from this local git directory') 112 | .option('--upstream ', 'GitHub /') 113 | .option('--token [value]', 'GitHub token') 114 | .option('--verbosity [value]', 'verbosity level', (val) => parseInt(val, 10)) 115 | .option('--tag [value]', 'get changelog from this tag') 116 | .option('--type [value]', 'Type of new release (semver)') 117 | .parse(argv); 118 | 119 | const defaults = { 120 | issueRegex: /(Fix|Close|Resolve) #(\d+)/g, 121 | tagRegex: /v\d+.\d+.\d+/, 122 | labels: { 123 | external: [{ match: 'Feature', name: 'Features' }, { match: 'Bug', name: 'Bugs' }], 124 | local: [{ match: /Hotfix [-~]? ?/, name: 'Others' }] 125 | }, 126 | verbosity: 3, 127 | render: { 128 | all: render.all, 129 | commit: render.commit, 130 | group: render.group, 131 | version: render.version, 132 | combine: render.combine 133 | } 134 | }; 135 | const configuration = _.merge({}, 136 | defaults, 137 | readConfiguration(commander.config), 138 | _.pick(commander, ['dir', 'upstream', 'token', 'rotate', 'tag', 'tagRegex', 'verbosity', 'type']) 139 | ); 140 | 141 | const { valid, error } = validator.validate(configuration); 142 | if (!valid) { 143 | console.error(error); 144 | process.exit(1); 145 | } 146 | 147 | const { dir, upstream, labels, ...rest } = configuration; 148 | 149 | // Ensure valid git directory. 150 | const inputDirectory = path.resolve(dir); 151 | // The directory must exist and be valid git repo, otherwise we can't read it. 152 | if (!fs.existsSync(inputDirectory) || !fs.existsSync(`${inputDirectory}/.git`)) { 153 | console.error(`${inputDirectory} does not exist, or is not a valid git repo.`); 154 | process.exit(1); 155 | } 156 | 157 | // Ensure valid GitHub repo. 158 | const parseGitHub = (upstream = '') => { 159 | const splitted = upstream.split('/'); 160 | if (splitted.length !== 2) { 161 | console.error(`${upstream} invalid GitHub repo.`); 162 | process.exit(1); 163 | } 164 | return { owner: splitted[0], repo: splitted[1] }; 165 | }; 166 | 167 | // eslint-disable-next-line new-cap 168 | const logger = Logger({ level: configuration.verbosity }); 169 | 170 | return { 171 | logger, 172 | ...parseGitHub(upstream), 173 | dir: inputDirectory, 174 | externalLabels: labels.external, 175 | localLabels: labels.local, 176 | ...rest 177 | }; 178 | } 179 | 180 | main(parseCmd(process.argv)) 181 | .catch((e) => { 182 | if (e.code && e.code === '504') { 183 | console.error(`Failed connecting to GitHub: ${e.message}`); 184 | } else { 185 | console.error(e.message); 186 | } 187 | console.error(e); 188 | process.exit(1); 189 | }); 190 | -------------------------------------------------------------------------------- /lib/git.js: -------------------------------------------------------------------------------- 1 | const execShell = require('execa').shell; 2 | const _ = require('lodash'); 3 | const Octokit = require('@octokit/rest'); 4 | 5 | const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); 6 | 7 | /** 8 | * Get local commits from git. 9 | * @param {string} cwd the directory to read from. 10 | * @param {string} from the tag to start from. 11 | * @param {string} to the tag to read to. 12 | * @returns {Promise} 13 | */ 14 | async function getCommitsFromGit({ cwd, from, to }) { 15 | const { stdout } = await execShell(`git log --pretty=format:"%h %aI %s" ${from}...${to}`, { cwd }); 16 | return stdout; 17 | } 18 | 19 | /** 20 | * Get local tags from git. 21 | * @param {string} cwd the directory to read from. 22 | * @param {number} count the number of tags to get. 23 | * @returns {Promise} 24 | */ 25 | async function getLatestTagsFromGit({ cwd, count }) { 26 | const { stdout } = await execShell(`git log --tags --simplify-by-decoration --pretty="format:%aI %D" | grep tag: | sort -r | head -${count}`, { cwd }); 27 | return stdout; 28 | } 29 | 30 | /** 31 | * Get an issue from GitHub. 32 | * @param {Object} github GitHub API instance. 33 | * @param {string} owner Name of owner. 34 | * @param {string} repo Name of repo. 35 | * @param {number} number Number of the issue. 36 | * @returns {Promise} 37 | */ 38 | async function getIssueFromGitHub({ github, owner, repo, number }) { 39 | return github.issues.get({ 40 | owner, 41 | repo, 42 | number 43 | }); 44 | } 45 | 46 | /** 47 | * Get a promise function with retries. 48 | * @param {Function} fn 49 | * @param {number} retries 50 | * @param {number} timeout 51 | * @returns {Function} 52 | */ 53 | const getWithRetry = (fn, retries = 10, timeout = 1500) => async (...args) => { 54 | for (let i = 0; i < retries; ++i) { 55 | try { 56 | // eslint-disable-next-line no-await-in-loop 57 | const results = await fn(...args); 58 | return results; 59 | } catch (e) { 60 | if (i === retries - 1) { 61 | throw e; 62 | } 63 | // eslint-disable-next-line no-await-in-loop 64 | await delay(timeout); 65 | } 66 | } 67 | }; 68 | 69 | /** 70 | * Parse issue from GitHub. 71 | * @param {Object} issue Issue as it is from GitHub. 72 | * @return {{title: string, number: number, labels: array}} 73 | */ 74 | function parseGitHubIssue(issue = {}) { 75 | const { number, title, labels = [] } = issue.data || {}; 76 | const parseLabel = ({ name }) => name; 77 | return { 78 | title, 79 | number: parseInt(number, 10), 80 | labels: labels.map(parseLabel) 81 | }; 82 | } 83 | 84 | /** 85 | * Parse issues from external source. 86 | * @param {Function} parser 87 | * @param {Array} issues 88 | * @return {Object} containing all issues mapped by key -> issue number. 89 | */ 90 | function parseIssues(parser, issues) { 91 | return issues.reduce((agg, issue) => { 92 | const { number, title, labels = [] } = parser(issue); 93 | agg[number] = { 94 | title, 95 | labels 96 | }; 97 | return agg; 98 | }, {}); 99 | } 100 | 101 | /** 102 | * Get two git tags from the directory. 103 | * If given a version, attempt to match this version and retrieve the version before it. 104 | * If not given a version, retrieve the newest tag and the tag before it. 105 | * @param {Array} tags from git. 106 | * @param {string} tag optional tag to start from. 107 | * @returns {Object} 108 | * @returns {{from: {name: string, date: string}, to: {name: string, date: string}}} 109 | */ 110 | function getTagsBetween({ tags = [], tag }) { 111 | // Find the tag matching the specified version, or start from the first item in the array. 112 | const fromIndex = tag ? tags.findIndex((t) => t.name === tag) : 0; 113 | // Take the next tag in the list. 114 | const toIndex = fromIndex + 1; 115 | if (fromIndex === -1 || toIndex >= tags.length) { 116 | return; 117 | } 118 | return { 119 | from: tags[fromIndex], 120 | to: tags[toIndex] 121 | }; 122 | } 123 | 124 | /** 125 | * Parse a git tag. 126 | * ex: 2018-09-05T13:55:53+02:00 HEAD -> v3, tag: v3.14.5, origin/v3, origin/HEAD 127 | * ex: 2018-08-07T10:28:33+02:00 tag: v3.14.4 128 | * @param {RegExp} tagRegex 129 | */ 130 | function tagParser(tagRegex) { 131 | return (input = '') => { 132 | const regex = /([^ ]+) (.*)/; 133 | const result = input.match(regex); 134 | if (!result || result.length < 3) { 135 | return []; 136 | } 137 | const [, date, tags] = result; 138 | if (!tags) { 139 | return []; 140 | } 141 | return [ 142 | ...tags 143 | .split(', ') 144 | .map((x) => x.replace('tag: ', '')) 145 | .filter((x) => x.match(tagRegex)) 146 | .map((x) => ({ 147 | name: x, 148 | date 149 | })) 150 | ]; 151 | }; 152 | } 153 | 154 | /** 155 | * Parse multiple linked GitHub issues from a git commit. 156 | * @param {RegExp} regex Regex matching external issues where the first group is the issue number. 157 | * @param {string} input 158 | * @returns {Array} Array of issues. 159 | */ 160 | function matchGithubIssues(regex, input) { 161 | let issuesMatch = regex.exec(input); 162 | const result = []; 163 | while (issuesMatch != null) { 164 | result.push(issuesMatch[2]); 165 | issuesMatch = regex.exec(input); 166 | } 167 | return result; 168 | } 169 | 170 | /** 171 | * Parse a git commit. 172 | * ex: 72d9d941d 2018-01-02T19:32:20+01:00 Fix #1129 - Error dompurify when load 173 | * @param {string} input Commit name. 174 | * @returns {Object} 175 | * @returns {{name: string, hash: string, date: string, issues: Array}} 176 | */ 177 | function commitParser(input = '') { 178 | const regex = /^(.{9}) ([^ ]+) (.*)/; 179 | const result = input.match(regex); 180 | if (!result || result.length < 4) { 181 | return; 182 | } 183 | const name = result[3]; 184 | return { 185 | name, 186 | hash: result[1], 187 | date: result[2] 188 | }; 189 | } 190 | 191 | /** 192 | * Filter commits containing a specific issue type, and map the issueNumber to the commit. 193 | * @param {Array} commits The list of commits from the local git history. 194 | * @param {Array} issues The list of issues from GitHub. 195 | * @param {string} match The issue label includes this text. 196 | * @returns {Array} 197 | */ 198 | function filterExternalIssues({ commits = [], issues = [], match = '' }) { 199 | const filterIssueType = (commitIssue) => { 200 | if (issues[commitIssue]) { 201 | return issues[commitIssue].labels.includes(match); 202 | } 203 | }; 204 | return _.flatMap(commits, (commit) => { 205 | const commitIssues = commit.issues || []; 206 | return commitIssues 207 | .filter(filterIssueType) 208 | .map((commitIssue) => ({ 209 | ...commit, 210 | issueNumber: commitIssue 211 | })); 212 | }); 213 | } 214 | 215 | /** 216 | * Filter issues that do not contain linked GitHub issues. 217 | * @param {string} Name of the commit 218 | * @param {Array} issues List of linked GitHub issues. 219 | * @param {string} match The commit name inclues this text. 220 | * @returns {boolean} 221 | */ 222 | const filterLocalCommits = ({ name = '', issues = [], match = '' }) => { 223 | return issues.length === 0 && (match instanceof RegExp ? match.test(name) : name.includes(match)); 224 | }; 225 | 226 | /** 227 | * Remove unwanted words from a commit name. 228 | * @param {string} match The pattern, which is concatenated with - or ~ 229 | * @returns {function(*)} 230 | */ 231 | const removeMatch = (match) => { 232 | return (commit) => { 233 | const name = commit.name.replace(match, ''); 234 | return { 235 | ...commit, 236 | name 237 | }; 238 | }; 239 | }; 240 | 241 | /** 242 | * Retrieves issues from the GitHub API in batches in order to avoid timeouts. 243 | * @param {Object} github GitHub API instance. 244 | * @param {string} owner Name of owner. 245 | * @param {string} repo Name of repo. 246 | * @param {Array} issues List of issue numbers to retrieve. 247 | * @param {number} n Number of issues to retrieve per batch. 248 | * @param {number} ms Number of ms to wait before retrieving the next batch of items. 249 | * @param {Object} logger Logger functions. 250 | * @returns {Promise} Array of resolved GitHub issues. 251 | */ 252 | async function getIssuesFromGitHub({ github, owner, repo, issues = [], n = 5, ms = 500, logger }) { 253 | logger.progress(`Getting ${issues.length} issues from GitHub ${owner}/${repo}`); 254 | logger.progress(`Chunking ${issues.length} issues in chunks of ${n}`); 255 | 256 | const chunks = _.chunk(issues, n); 257 | const get = getWithRetry(getIssueFromGitHub); 258 | 259 | const result = []; 260 | // eslint-disable-next-line no-restricted-syntax 261 | for (const chunk of chunks) { 262 | logger.progress(` getting ${chunk.length} issues from GitHub...`); 263 | result.push( 264 | // eslint-disable-next-line no-await-in-loop 265 | ...(await Promise.all( 266 | chunk.map((issue) => get({ github, owner, repo, number: issue })) 267 | ) 268 | ) 269 | ); 270 | 271 | const remaining = issues.length - result.length; 272 | if (remaining > 0) { 273 | logger.success(` getting ${remaining} more issues from GitHub...`); 274 | logger.progress(` waiting ${ms}ms...`); 275 | 276 | // eslint-disable-next-line no-await-in-loop 277 | await delay(ms); 278 | } 279 | } 280 | return result; 281 | } 282 | 283 | /** 284 | * Parse an output string, separated by newline. 285 | * @param {Function} parser 286 | * @param {string} input 287 | * @returns {Array} 288 | */ 289 | function parseOutput(parser, input = '') { 290 | return _.flatMap(input 291 | .split(/\r?\n/) 292 | .map(parser) 293 | ).filter(Boolean); 294 | } 295 | 296 | /** 297 | * Retrieves issues from GitHub. 298 | * @param {Array} numbers List of numbers to issues. 299 | * @param {string} owner Name of owner. 300 | * @param {string} repo Name of repo. 301 | * @param {string} token GitHub token. 302 | * @param {Object} logger Logger functions. 303 | * @return {Object} containing all issues mapped by key -> issue number. 304 | */ 305 | async function retrieveIssuesFromGitHub({ numbers, token, owner, repo, logger }) { 306 | const github = new Octokit({ 307 | timeout: 15000 308 | }); 309 | 310 | if (token) { 311 | github.authenticate({ 312 | type: 'token', 313 | token 314 | }); 315 | } 316 | 317 | return parseIssues(parseGitHubIssue, await getIssuesFromGitHub({ 318 | github, 319 | owner, 320 | repo, 321 | issues: numbers, 322 | logger 323 | })); 324 | } 325 | 326 | /** 327 | * Retrieves local commit issues from external source. 328 | * @param {Array} commits List of commits. 329 | * @param {Array} externalLabels List of GitHub label names. 330 | * @param {Array} localLabels Include commits not linked to a GitHub issue. 331 | * @param {RegExp} issueRegex Regex to match against external issue links 332 | * @param {string} owner Name of owner. 333 | * @param {string} repo Name of repo. 334 | * @param {string} token GitHub token. 335 | * @param {Object} logger Logger functions. 336 | * @returns {Promise<{issues: Object, groupedCommits: Array}>} 337 | */ 338 | async function retrieve({ commits, issueRegex, externalLabels, localLabels, owner, repo, token, logger }) { 339 | const commitsWithIssues = commits.map((commit) => ({ 340 | ...commit, 341 | issues: matchGithubIssues(issueRegex, commit.name) 342 | })); 343 | 344 | // Get issues from GitHub. 345 | const numbers = _.flatMap(commitsWithIssues, (c) => c.issues); 346 | 347 | // TODO: Add support for GitLab 348 | const issues = await retrieveIssuesFromGitHub({ numbers, repo, owner, token, logger }); 349 | 350 | // Return the commits together with the label name. 351 | const resultify = (labels) => (commits, i) => ({ 352 | commits, 353 | name: labels[i].name 354 | }); 355 | 356 | // Filter the commits linked to GitHub issues with a specific label. 357 | const githubCommits = 358 | externalLabels 359 | .map((label) => filterExternalIssues({ 360 | commits: commitsWithIssues, 361 | issues, 362 | match: label.match 363 | }) 364 | ) 365 | .map((resultify(externalLabels))); 366 | 367 | // Filter the commits not linked to any issue. 368 | const localCommits = 369 | localLabels 370 | .map((label) => commits 371 | .filter((commit) => filterLocalCommits({ 372 | name: commit.name, 373 | issues: commit.issues, 374 | match: label.match 375 | })) 376 | .map(removeMatch(label.match)) 377 | ) 378 | .map((resultify(localLabels))); 379 | 380 | return { 381 | issues, 382 | groupedCommits: [].concat(githubCommits, localCommits) 383 | }; 384 | } 385 | 386 | /** 387 | * Reads the tags and commits from a local git repo. 388 | * @param {string} dir 389 | * @param {string} tag 390 | * @param {RegExp} tagRegex 391 | * @returns {Promise<{commits: Array, from: {name: string, date: string}}>} 392 | */ 393 | async function read({ dir, tag, tagRegex }) { 394 | // Get and parse tags. 395 | const tags = parseOutput(tagParser(tagRegex), await getLatestTagsFromGit({ 396 | cwd: dir, 397 | count: 20 398 | })); 399 | if (tags.length <= 1) { 400 | throw new Error(`Failed to get tags with ${tagRegex}`); 401 | } 402 | 403 | // Get two tags, either from a specified tag or latest tag. 404 | const between = getTagsBetween({ 405 | tags, 406 | tag 407 | }); 408 | if (!between) { 409 | throw new Error('Failed to get tags'); 410 | } 411 | 412 | const { from: fromTag, to: toTag } = between; 413 | 414 | // Get all commits between the tags. 415 | const commits = parseOutput(commitParser, await getCommitsFromGit({ 416 | cwd: dir, 417 | from: fromTag.name, 418 | to: toTag.name 419 | })); 420 | 421 | return { 422 | commits, 423 | from: fromTag, 424 | to: toTag 425 | }; 426 | } 427 | 428 | module.exports = { 429 | read, 430 | retrieve 431 | }; 432 | -------------------------------------------------------------------------------- /lib/logger.js: -------------------------------------------------------------------------------- 1 | const chalk = require('chalk'); 2 | 3 | const Logger = ({ level }) => { 4 | const noop = () => { 5 | }; 6 | 7 | const progress = level >= 2 ? (msg) => console.log(`${chalk.black('.')} ${msg}`) : noop; 8 | const success = level >= 3 ? (msg) => console.log(`${chalk.green('✓ ' + msg)}`) : noop; 9 | const error = level >= 1 ? (msg) => console.log(`${chalk.magentaBright(' ⚠ ')} ${chalk.red(msg)}`) : noop; 10 | 11 | return { 12 | success, 13 | progress, 14 | error 15 | }; 16 | }; 17 | 18 | module.exports = Logger; 19 | -------------------------------------------------------------------------------- /lib/render.js: -------------------------------------------------------------------------------- 1 | function commit({ title, hash, issueNumber, name }) { 2 | // eslint-disable-next-line no-mixed-operators 3 | const issue = (number) => number && `#${number} ` || ''; 4 | return `* (${hash}) ${issue(issueNumber)}${title || name}`; 5 | } 6 | 7 | function group({ name, commits }) { 8 | return `### ${name} 9 | ${commits.join('\n')} 10 | `; 11 | } 12 | 13 | function version({ version, date }) { 14 | return `# [${version}] - ${date}`; 15 | } 16 | 17 | function combine({ version, groups }) { 18 | return [ 19 | version, 20 | ...groups 21 | ].join('\n').trim(); 22 | } 23 | 24 | function all({ version, date, groupedCommits = [], issues = {}, render }) { 25 | const renderedGroups = groupedCommits 26 | .filter((group) => group.commits.length > 0) 27 | .map((group) => render.group({ 28 | commits: group.commits.map((commit) => render.commit({ ...commit, ...issues[commit.issueNumber] })), 29 | name: group.name 30 | }) 31 | ); 32 | return render.combine({ 33 | version: render.version({ version, date }), 34 | groups: renderedGroups 35 | }); 36 | } 37 | 38 | module.exports = { 39 | version, 40 | group, 41 | commit, 42 | combine, 43 | all 44 | }; 45 | -------------------------------------------------------------------------------- /lib/validator.js: -------------------------------------------------------------------------------- 1 | const Ajv = require('ajv'); 2 | 3 | const labelSchema = { 4 | type: 'object', 5 | properties: { 6 | match: { anyOf: [{ type: 'string' }, { instanceof: 'RegExp' }] }, 7 | name: { type: 'string' } 8 | }, 9 | required: ['match', 'name'], 10 | additionalProperties: false 11 | }; 12 | 13 | const labelsSchema = { 14 | type: 'object', 15 | properties: { 16 | external: { type: 'array', items: labelSchema }, 17 | local: { type: 'array', items: labelSchema } 18 | }, 19 | additionalProperties: false 20 | }; 21 | 22 | const renderSchema = { 23 | type: 'object', 24 | properties: { 25 | all: { instanceof: 'Function' }, 26 | commit: { instanceof: 'Function' }, 27 | version: { instanceof: 'Function' }, 28 | group: { instanceof: 'Function' }, 29 | combine: { instanceof: 'Function' } 30 | }, 31 | additionalProperties: false 32 | }; 33 | 34 | const schema = { 35 | type: 'object', 36 | properties: { 37 | type: { type: 'string' }, 38 | dir: { type: 'string' }, 39 | upstream: { type: 'string' }, 40 | issueRegex: { instance: 'RegExp' }, 41 | token: { type: 'string' }, 42 | verbosity: { type: 'integer' }, 43 | tag: { type: 'string' }, 44 | tagRegex: { instance: 'RegExp' }, 45 | labels: labelsSchema, 46 | render: renderSchema 47 | }, 48 | required: ['dir', 'upstream', 'render'], 49 | additionalProperties: false 50 | }; 51 | 52 | const ajv = new Ajv(); 53 | const CLASSES = { 54 | RegExp: RegExp, 55 | Function: Function 56 | }; 57 | 58 | ajv.addKeyword('instanceof', { 59 | compile: function (schema) { 60 | const Class = CLASSES[schema]; 61 | return function (data) { 62 | return data instanceof Class; 63 | }; 64 | } 65 | }); 66 | 67 | const validate = (configuration) => { 68 | const validate = ajv.compile(schema); 69 | const valid = validate(configuration); 70 | return { 71 | valid, 72 | error: !valid ? ajv.errorsText(validate.errors) : undefined 73 | }; 74 | }; 75 | 76 | module.exports = { 77 | validate 78 | }; 79 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "releaser", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@babel/code-frame": { 8 | "version": "7.5.5", 9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", 10 | "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", 11 | "requires": { 12 | "@babel/highlight": "^7.0.0" 13 | } 14 | }, 15 | "@babel/highlight": { 16 | "version": "7.5.0", 17 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", 18 | "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", 19 | "requires": { 20 | "chalk": "^2.0.0", 21 | "esutils": "^2.0.2", 22 | "js-tokens": "^4.0.0" 23 | } 24 | }, 25 | "@octokit/rest": { 26 | "version": "15.18.3", 27 | "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.3.tgz", 28 | "integrity": "sha512-oHABAvvC83tPIuvUfWRaw9eLThFrCxBgywl+KvEwfTFjoCrMOfEaMh0r39+Ub/EEbV345GJiMzN+zPZ4kqOvbA==", 29 | "requires": { 30 | "before-after-hook": "^1.1.0", 31 | "btoa-lite": "^1.0.0", 32 | "debug": "^3.1.0", 33 | "http-proxy-agent": "^2.1.0", 34 | "https-proxy-agent": "^2.2.0", 35 | "lodash": "^4.17.4", 36 | "node-fetch": "^2.1.1", 37 | "universal-user-agent": "^2.0.0", 38 | "url-template": "^2.0.8" 39 | }, 40 | "dependencies": { 41 | "agent-base": { 42 | "version": "4.3.0", 43 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", 44 | "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", 45 | "requires": { 46 | "es6-promisify": "^5.0.0" 47 | } 48 | }, 49 | "debug": { 50 | "version": "3.2.6", 51 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", 52 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", 53 | "requires": { 54 | "ms": "^2.1.1" 55 | } 56 | }, 57 | "https-proxy-agent": { 58 | "version": "2.2.2", 59 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz", 60 | "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==", 61 | "requires": { 62 | "agent-base": "^4.3.0", 63 | "debug": "^3.1.0" 64 | } 65 | }, 66 | "ms": { 67 | "version": "2.1.2", 68 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 69 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 70 | } 71 | } 72 | }, 73 | "acorn": { 74 | "version": "6.3.0", 75 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", 76 | "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==" 77 | }, 78 | "acorn-jsx": { 79 | "version": "5.0.2", 80 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", 81 | "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==" 82 | }, 83 | "agent-base": { 84 | "version": "4.2.0", 85 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.0.tgz", 86 | "integrity": "sha512-c+R/U5X+2zz2+UCrCFv6odQzJdoqI+YecuhnAJLa1zYaMc13zPfwMwZrr91Pd1DYNo/yPRbiM4WVf9whgwFsIg==", 87 | "requires": { 88 | "es6-promisify": "^5.0.0" 89 | } 90 | }, 91 | "ajv": { 92 | "version": "6.0.1", 93 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.0.1.tgz", 94 | "integrity": "sha1-KJhYCp8971+chd/q16IiPvE889o=", 95 | "requires": { 96 | "fast-deep-equal": "^1.0.0", 97 | "fast-json-stable-stringify": "^2.0.0", 98 | "json-schema-traverse": "^0.3.0" 99 | } 100 | }, 101 | "ansi-escapes": { 102 | "version": "3.2.0", 103 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", 104 | "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" 105 | }, 106 | "ansi-regex": { 107 | "version": "3.0.0", 108 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 109 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" 110 | }, 111 | "ansi-styles": { 112 | "version": "3.2.1", 113 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 114 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 115 | "requires": { 116 | "color-convert": "^1.9.0" 117 | } 118 | }, 119 | "argparse": { 120 | "version": "1.0.9", 121 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", 122 | "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", 123 | "requires": { 124 | "sprintf-js": "~1.0.2" 125 | } 126 | }, 127 | "astral-regex": { 128 | "version": "1.0.0", 129 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", 130 | "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" 131 | }, 132 | "balanced-match": { 133 | "version": "1.0.0", 134 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 135 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 136 | }, 137 | "before-after-hook": { 138 | "version": "1.4.0", 139 | "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz", 140 | "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==" 141 | }, 142 | "brace-expansion": { 143 | "version": "1.1.8", 144 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", 145 | "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", 146 | "requires": { 147 | "balanced-match": "^1.0.0", 148 | "concat-map": "0.0.1" 149 | } 150 | }, 151 | "btoa-lite": { 152 | "version": "1.0.0", 153 | "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz", 154 | "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=" 155 | }, 156 | "builtin-modules": { 157 | "version": "1.1.1", 158 | "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", 159 | "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" 160 | }, 161 | "callsites": { 162 | "version": "3.1.0", 163 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 164 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" 165 | }, 166 | "chalk": { 167 | "version": "2.3.0", 168 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", 169 | "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", 170 | "requires": { 171 | "ansi-styles": "^3.1.0", 172 | "escape-string-regexp": "^1.0.5", 173 | "supports-color": "^4.0.0" 174 | }, 175 | "dependencies": { 176 | "ansi-styles": { 177 | "version": "3.2.0", 178 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", 179 | "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", 180 | "requires": { 181 | "color-convert": "^1.9.0" 182 | } 183 | }, 184 | "supports-color": { 185 | "version": "4.5.0", 186 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", 187 | "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", 188 | "requires": { 189 | "has-flag": "^2.0.0" 190 | } 191 | } 192 | } 193 | }, 194 | "chardet": { 195 | "version": "0.7.0", 196 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", 197 | "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" 198 | }, 199 | "cli-cursor": { 200 | "version": "2.1.0", 201 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", 202 | "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", 203 | "requires": { 204 | "restore-cursor": "^2.0.0" 205 | } 206 | }, 207 | "cli-width": { 208 | "version": "2.2.0", 209 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", 210 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" 211 | }, 212 | "color-convert": { 213 | "version": "1.9.1", 214 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", 215 | "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", 216 | "requires": { 217 | "color-name": "^1.1.1" 218 | } 219 | }, 220 | "color-name": { 221 | "version": "1.1.3", 222 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 223 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 224 | }, 225 | "commander": { 226 | "version": "2.13.0", 227 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", 228 | "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==" 229 | }, 230 | "concat-map": { 231 | "version": "0.0.1", 232 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 233 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 234 | }, 235 | "confusing-browser-globals": { 236 | "version": "1.0.9", 237 | "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz", 238 | "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==" 239 | }, 240 | "contains-path": { 241 | "version": "0.1.0", 242 | "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", 243 | "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=" 244 | }, 245 | "debug": { 246 | "version": "2.6.9", 247 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 248 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 249 | "requires": { 250 | "ms": "2.0.0" 251 | } 252 | }, 253 | "deep-is": { 254 | "version": "0.1.3", 255 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 256 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" 257 | }, 258 | "define-properties": { 259 | "version": "1.1.3", 260 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", 261 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", 262 | "requires": { 263 | "object-keys": "^1.0.12" 264 | } 265 | }, 266 | "doctrine": { 267 | "version": "3.0.0", 268 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 269 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 270 | "requires": { 271 | "esutils": "^2.0.2" 272 | } 273 | }, 274 | "emoji-regex": { 275 | "version": "7.0.3", 276 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 277 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" 278 | }, 279 | "end-of-stream": { 280 | "version": "1.4.4", 281 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", 282 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", 283 | "requires": { 284 | "once": "^1.4.0" 285 | } 286 | }, 287 | "entities": { 288 | "version": "1.1.1", 289 | "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", 290 | "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=" 291 | }, 292 | "error-ex": { 293 | "version": "1.3.1", 294 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", 295 | "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", 296 | "requires": { 297 | "is-arrayish": "^0.2.1" 298 | } 299 | }, 300 | "es-abstract": { 301 | "version": "1.14.2", 302 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.14.2.tgz", 303 | "integrity": "sha512-DgoQmbpFNOofkjJtKwr87Ma5EW4Dc8fWhD0R+ndq7Oc456ivUfGOOP6oAZTTKl5/CcNMP+EN+e3/iUzgE0veZg==", 304 | "requires": { 305 | "es-to-primitive": "^1.2.0", 306 | "function-bind": "^1.1.1", 307 | "has": "^1.0.3", 308 | "has-symbols": "^1.0.0", 309 | "is-callable": "^1.1.4", 310 | "is-regex": "^1.0.4", 311 | "object-inspect": "^1.6.0", 312 | "object-keys": "^1.1.1", 313 | "string.prototype.trimleft": "^2.0.0", 314 | "string.prototype.trimright": "^2.0.0" 315 | }, 316 | "dependencies": { 317 | "has": { 318 | "version": "1.0.3", 319 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 320 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 321 | "requires": { 322 | "function-bind": "^1.1.1" 323 | } 324 | } 325 | } 326 | }, 327 | "es-to-primitive": { 328 | "version": "1.2.0", 329 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", 330 | "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", 331 | "requires": { 332 | "is-callable": "^1.1.4", 333 | "is-date-object": "^1.0.1", 334 | "is-symbol": "^1.0.2" 335 | } 336 | }, 337 | "es6-promise": { 338 | "version": "4.2.2", 339 | "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.2.tgz", 340 | "integrity": "sha512-LSas5vsuA6Q4nEdf9wokY5/AJYXry98i0IzXsv49rYsgDGDNDPbqAYR1Pe23iFxygfbGZNR/5VrHXBCh2BhvUQ==" 341 | }, 342 | "es6-promisify": { 343 | "version": "5.0.0", 344 | "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", 345 | "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", 346 | "requires": { 347 | "es6-promise": "^4.0.3" 348 | } 349 | }, 350 | "escape-string-regexp": { 351 | "version": "1.0.5", 352 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 353 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 354 | }, 355 | "eslint": { 356 | "version": "5.16.0", 357 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", 358 | "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", 359 | "requires": { 360 | "@babel/code-frame": "^7.0.0", 361 | "ajv": "^6.9.1", 362 | "chalk": "^2.1.0", 363 | "cross-spawn": "^6.0.5", 364 | "debug": "^4.0.1", 365 | "doctrine": "^3.0.0", 366 | "eslint-scope": "^4.0.3", 367 | "eslint-utils": "^1.3.1", 368 | "eslint-visitor-keys": "^1.0.0", 369 | "espree": "^5.0.1", 370 | "esquery": "^1.0.1", 371 | "esutils": "^2.0.2", 372 | "file-entry-cache": "^5.0.1", 373 | "functional-red-black-tree": "^1.0.1", 374 | "glob": "^7.1.2", 375 | "globals": "^11.7.0", 376 | "ignore": "^4.0.6", 377 | "import-fresh": "^3.0.0", 378 | "imurmurhash": "^0.1.4", 379 | "inquirer": "^6.2.2", 380 | "js-yaml": "^3.13.0", 381 | "json-stable-stringify-without-jsonify": "^1.0.1", 382 | "levn": "^0.3.0", 383 | "lodash": "^4.17.11", 384 | "minimatch": "^3.0.4", 385 | "mkdirp": "^0.5.1", 386 | "natural-compare": "^1.4.0", 387 | "optionator": "^0.8.2", 388 | "path-is-inside": "^1.0.2", 389 | "progress": "^2.0.0", 390 | "regexpp": "^2.0.1", 391 | "semver": "^5.5.1", 392 | "strip-ansi": "^4.0.0", 393 | "strip-json-comments": "^2.0.1", 394 | "table": "^5.2.3", 395 | "text-table": "^0.2.0" 396 | }, 397 | "dependencies": { 398 | "ajv": { 399 | "version": "6.10.2", 400 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", 401 | "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", 402 | "requires": { 403 | "fast-deep-equal": "^2.0.1", 404 | "fast-json-stable-stringify": "^2.0.0", 405 | "json-schema-traverse": "^0.4.1", 406 | "uri-js": "^4.2.2" 407 | } 408 | }, 409 | "cross-spawn": { 410 | "version": "6.0.5", 411 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", 412 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", 413 | "requires": { 414 | "nice-try": "^1.0.4", 415 | "path-key": "^2.0.1", 416 | "semver": "^5.5.0", 417 | "shebang-command": "^1.2.0", 418 | "which": "^1.2.9" 419 | } 420 | }, 421 | "debug": { 422 | "version": "4.1.1", 423 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 424 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 425 | "requires": { 426 | "ms": "^2.1.1" 427 | } 428 | }, 429 | "fast-deep-equal": { 430 | "version": "2.0.1", 431 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", 432 | "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" 433 | }, 434 | "json-schema-traverse": { 435 | "version": "0.4.1", 436 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 437 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" 438 | }, 439 | "lodash": { 440 | "version": "4.17.15", 441 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 442 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" 443 | }, 444 | "ms": { 445 | "version": "2.1.2", 446 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 447 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 448 | }, 449 | "semver": { 450 | "version": "5.7.1", 451 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 452 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" 453 | } 454 | } 455 | }, 456 | "eslint-config-airbnb-base": { 457 | "version": "13.2.0", 458 | "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.2.0.tgz", 459 | "integrity": "sha512-1mg/7eoB4AUeB0X1c/ho4vb2gYkNH8Trr/EgCT/aGmKhhG+F6vF5s8+iRBlWAzFIAphxIdp3YfEKgEl0f9Xg+w==", 460 | "requires": { 461 | "confusing-browser-globals": "^1.0.5", 462 | "object.assign": "^4.1.0", 463 | "object.entries": "^1.1.0" 464 | } 465 | }, 466 | "eslint-import-resolver-node": { 467 | "version": "0.3.2", 468 | "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", 469 | "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", 470 | "requires": { 471 | "debug": "^2.6.9", 472 | "resolve": "^1.5.0" 473 | } 474 | }, 475 | "eslint-module-utils": { 476 | "version": "2.1.1", 477 | "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz", 478 | "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", 479 | "requires": { 480 | "debug": "^2.6.8", 481 | "pkg-dir": "^1.0.0" 482 | } 483 | }, 484 | "eslint-plugin-import": { 485 | "version": "2.8.0", 486 | "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz", 487 | "integrity": "sha512-Rf7dfKJxZ16QuTgVv1OYNxkZcsu/hULFnC+e+w0Gzi6jMC3guQoWQgxYxc54IDRinlb6/0v5z/PxxIKmVctN+g==", 488 | "requires": { 489 | "builtin-modules": "^1.1.1", 490 | "contains-path": "^0.1.0", 491 | "debug": "^2.6.8", 492 | "doctrine": "1.5.0", 493 | "eslint-import-resolver-node": "^0.3.1", 494 | "eslint-module-utils": "^2.1.1", 495 | "has": "^1.0.1", 496 | "lodash.cond": "^4.3.0", 497 | "minimatch": "^3.0.3", 498 | "read-pkg-up": "^2.0.0" 499 | }, 500 | "dependencies": { 501 | "doctrine": { 502 | "version": "1.5.0", 503 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", 504 | "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", 505 | "requires": { 506 | "esutils": "^2.0.2", 507 | "isarray": "^1.0.0" 508 | } 509 | } 510 | } 511 | }, 512 | "eslint-scope": { 513 | "version": "4.0.3", 514 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", 515 | "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", 516 | "requires": { 517 | "esrecurse": "^4.1.0", 518 | "estraverse": "^4.1.1" 519 | } 520 | }, 521 | "eslint-utils": { 522 | "version": "1.4.2", 523 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", 524 | "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", 525 | "requires": { 526 | "eslint-visitor-keys": "^1.0.0" 527 | } 528 | }, 529 | "eslint-visitor-keys": { 530 | "version": "1.1.0", 531 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", 532 | "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==" 533 | }, 534 | "espree": { 535 | "version": "5.0.1", 536 | "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", 537 | "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", 538 | "requires": { 539 | "acorn": "^6.0.7", 540 | "acorn-jsx": "^5.0.0", 541 | "eslint-visitor-keys": "^1.0.0" 542 | } 543 | }, 544 | "esprima": { 545 | "version": "4.0.1", 546 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 547 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" 548 | }, 549 | "esquery": { 550 | "version": "1.0.1", 551 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", 552 | "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", 553 | "requires": { 554 | "estraverse": "^4.0.0" 555 | } 556 | }, 557 | "esrecurse": { 558 | "version": "4.2.1", 559 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", 560 | "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", 561 | "requires": { 562 | "estraverse": "^4.1.0" 563 | } 564 | }, 565 | "estraverse": { 566 | "version": "4.3.0", 567 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 568 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" 569 | }, 570 | "esutils": { 571 | "version": "2.0.2", 572 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 573 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" 574 | }, 575 | "execa": { 576 | "version": "1.0.0", 577 | "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", 578 | "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", 579 | "requires": { 580 | "cross-spawn": "^6.0.0", 581 | "get-stream": "^4.0.0", 582 | "is-stream": "^1.1.0", 583 | "npm-run-path": "^2.0.0", 584 | "p-finally": "^1.0.0", 585 | "signal-exit": "^3.0.0", 586 | "strip-eof": "^1.0.0" 587 | }, 588 | "dependencies": { 589 | "cross-spawn": { 590 | "version": "6.0.5", 591 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", 592 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", 593 | "requires": { 594 | "nice-try": "^1.0.4", 595 | "path-key": "^2.0.1", 596 | "semver": "^5.5.0", 597 | "shebang-command": "^1.2.0", 598 | "which": "^1.2.9" 599 | }, 600 | "dependencies": { 601 | "semver": { 602 | "version": "5.7.1", 603 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 604 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" 605 | } 606 | } 607 | } 608 | } 609 | }, 610 | "external-editor": { 611 | "version": "3.1.0", 612 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", 613 | "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", 614 | "requires": { 615 | "chardet": "^0.7.0", 616 | "iconv-lite": "^0.4.24", 617 | "tmp": "^0.0.33" 618 | } 619 | }, 620 | "fast-deep-equal": { 621 | "version": "1.0.0", 622 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", 623 | "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" 624 | }, 625 | "fast-json-stable-stringify": { 626 | "version": "2.0.0", 627 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 628 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" 629 | }, 630 | "fast-levenshtein": { 631 | "version": "2.0.6", 632 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 633 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" 634 | }, 635 | "figures": { 636 | "version": "2.0.0", 637 | "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", 638 | "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", 639 | "requires": { 640 | "escape-string-regexp": "^1.0.5" 641 | } 642 | }, 643 | "file-entry-cache": { 644 | "version": "5.0.1", 645 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", 646 | "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", 647 | "requires": { 648 | "flat-cache": "^2.0.1" 649 | } 650 | }, 651 | "find-up": { 652 | "version": "1.1.2", 653 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", 654 | "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", 655 | "requires": { 656 | "path-exists": "^2.0.0", 657 | "pinkie-promise": "^2.0.0" 658 | } 659 | }, 660 | "flat-cache": { 661 | "version": "2.0.1", 662 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", 663 | "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", 664 | "requires": { 665 | "flatted": "^2.0.0", 666 | "rimraf": "2.6.3", 667 | "write": "1.0.3" 668 | } 669 | }, 670 | "flatted": { 671 | "version": "2.0.1", 672 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", 673 | "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==" 674 | }, 675 | "fs.realpath": { 676 | "version": "1.0.0", 677 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 678 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 679 | }, 680 | "function-bind": { 681 | "version": "1.1.1", 682 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 683 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" 684 | }, 685 | "functional-red-black-tree": { 686 | "version": "1.0.1", 687 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 688 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" 689 | }, 690 | "get-stream": { 691 | "version": "4.1.0", 692 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", 693 | "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", 694 | "requires": { 695 | "pump": "^3.0.0" 696 | } 697 | }, 698 | "glob": { 699 | "version": "7.1.4", 700 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", 701 | "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", 702 | "requires": { 703 | "fs.realpath": "^1.0.0", 704 | "inflight": "^1.0.4", 705 | "inherits": "2", 706 | "minimatch": "^3.0.4", 707 | "once": "^1.3.0", 708 | "path-is-absolute": "^1.0.0" 709 | } 710 | }, 711 | "globals": { 712 | "version": "11.12.0", 713 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 714 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" 715 | }, 716 | "graceful-fs": { 717 | "version": "4.1.11", 718 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", 719 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" 720 | }, 721 | "has": { 722 | "version": "1.0.1", 723 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", 724 | "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", 725 | "requires": { 726 | "function-bind": "^1.0.2" 727 | } 728 | }, 729 | "has-flag": { 730 | "version": "2.0.0", 731 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", 732 | "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" 733 | }, 734 | "has-symbols": { 735 | "version": "1.0.0", 736 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", 737 | "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" 738 | }, 739 | "hosted-git-info": { 740 | "version": "2.5.0", 741 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", 742 | "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==" 743 | }, 744 | "http-proxy-agent": { 745 | "version": "2.1.0", 746 | "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", 747 | "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", 748 | "requires": { 749 | "agent-base": "4", 750 | "debug": "3.1.0" 751 | }, 752 | "dependencies": { 753 | "debug": { 754 | "version": "3.1.0", 755 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 756 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 757 | "requires": { 758 | "ms": "2.0.0" 759 | } 760 | } 761 | } 762 | }, 763 | "iconv-lite": { 764 | "version": "0.4.24", 765 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 766 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 767 | "requires": { 768 | "safer-buffer": ">= 2.1.2 < 3" 769 | } 770 | }, 771 | "ignore": { 772 | "version": "4.0.6", 773 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", 774 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" 775 | }, 776 | "import-fresh": { 777 | "version": "3.1.0", 778 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", 779 | "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", 780 | "requires": { 781 | "parent-module": "^1.0.0", 782 | "resolve-from": "^4.0.0" 783 | } 784 | }, 785 | "imurmurhash": { 786 | "version": "0.1.4", 787 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 788 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" 789 | }, 790 | "inflight": { 791 | "version": "1.0.6", 792 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 793 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 794 | "requires": { 795 | "once": "^1.3.0", 796 | "wrappy": "1" 797 | } 798 | }, 799 | "inherits": { 800 | "version": "2.0.4", 801 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 802 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 803 | }, 804 | "inquirer": { 805 | "version": "6.5.2", 806 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", 807 | "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", 808 | "requires": { 809 | "ansi-escapes": "^3.2.0", 810 | "chalk": "^2.4.2", 811 | "cli-cursor": "^2.1.0", 812 | "cli-width": "^2.0.0", 813 | "external-editor": "^3.0.3", 814 | "figures": "^2.0.0", 815 | "lodash": "^4.17.12", 816 | "mute-stream": "0.0.7", 817 | "run-async": "^2.2.0", 818 | "rxjs": "^6.4.0", 819 | "string-width": "^2.1.0", 820 | "strip-ansi": "^5.1.0", 821 | "through": "^2.3.6" 822 | }, 823 | "dependencies": { 824 | "ansi-regex": { 825 | "version": "4.1.0", 826 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 827 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" 828 | }, 829 | "chalk": { 830 | "version": "2.4.2", 831 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 832 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 833 | "requires": { 834 | "ansi-styles": "^3.2.1", 835 | "escape-string-regexp": "^1.0.5", 836 | "supports-color": "^5.3.0" 837 | } 838 | }, 839 | "lodash": { 840 | "version": "4.17.15", 841 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 842 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" 843 | }, 844 | "strip-ansi": { 845 | "version": "5.2.0", 846 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 847 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 848 | "requires": { 849 | "ansi-regex": "^4.1.0" 850 | } 851 | } 852 | } 853 | }, 854 | "is-arrayish": { 855 | "version": "0.2.1", 856 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 857 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" 858 | }, 859 | "is-builtin-module": { 860 | "version": "1.0.0", 861 | "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", 862 | "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", 863 | "requires": { 864 | "builtin-modules": "^1.0.0" 865 | } 866 | }, 867 | "is-callable": { 868 | "version": "1.1.4", 869 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", 870 | "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" 871 | }, 872 | "is-date-object": { 873 | "version": "1.0.1", 874 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", 875 | "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" 876 | }, 877 | "is-fullwidth-code-point": { 878 | "version": "2.0.0", 879 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 880 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" 881 | }, 882 | "is-promise": { 883 | "version": "2.1.0", 884 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", 885 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" 886 | }, 887 | "is-regex": { 888 | "version": "1.0.4", 889 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", 890 | "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", 891 | "requires": { 892 | "has": "^1.0.1" 893 | } 894 | }, 895 | "is-stream": { 896 | "version": "1.1.0", 897 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 898 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" 899 | }, 900 | "is-symbol": { 901 | "version": "1.0.2", 902 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", 903 | "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", 904 | "requires": { 905 | "has-symbols": "^1.0.0" 906 | } 907 | }, 908 | "isarray": { 909 | "version": "1.0.0", 910 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 911 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 912 | }, 913 | "isexe": { 914 | "version": "2.0.0", 915 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 916 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" 917 | }, 918 | "js-tokens": { 919 | "version": "4.0.0", 920 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 921 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" 922 | }, 923 | "js-yaml": { 924 | "version": "3.13.1", 925 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 926 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 927 | "requires": { 928 | "argparse": "^1.0.7", 929 | "esprima": "^4.0.0" 930 | } 931 | }, 932 | "json-schema-traverse": { 933 | "version": "0.3.1", 934 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", 935 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" 936 | }, 937 | "json-stable-stringify-without-jsonify": { 938 | "version": "1.0.1", 939 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 940 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" 941 | }, 942 | "levn": { 943 | "version": "0.3.0", 944 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 945 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 946 | "requires": { 947 | "prelude-ls": "~1.1.2", 948 | "type-check": "~0.3.2" 949 | } 950 | }, 951 | "linkify-it": { 952 | "version": "2.0.3", 953 | "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.0.3.tgz", 954 | "integrity": "sha1-2UpGSPmxwXnWT6lykSaL22zpQ08=", 955 | "requires": { 956 | "uc.micro": "^1.0.1" 957 | } 958 | }, 959 | "load-json-file": { 960 | "version": "2.0.0", 961 | "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", 962 | "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", 963 | "requires": { 964 | "graceful-fs": "^4.1.2", 965 | "parse-json": "^2.2.0", 966 | "pify": "^2.0.0", 967 | "strip-bom": "^3.0.0" 968 | } 969 | }, 970 | "locate-path": { 971 | "version": "2.0.0", 972 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", 973 | "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", 974 | "requires": { 975 | "p-locate": "^2.0.0", 976 | "path-exists": "^3.0.0" 977 | }, 978 | "dependencies": { 979 | "path-exists": { 980 | "version": "3.0.0", 981 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 982 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" 983 | } 984 | } 985 | }, 986 | "lodash": { 987 | "version": "4.17.4", 988 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", 989 | "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" 990 | }, 991 | "lodash.cond": { 992 | "version": "4.5.2", 993 | "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", 994 | "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=" 995 | }, 996 | "macos-release": { 997 | "version": "2.3.0", 998 | "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.3.0.tgz", 999 | "integrity": "sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==" 1000 | }, 1001 | "markdown-it": { 1002 | "version": "8.4.0", 1003 | "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.0.tgz", 1004 | "integrity": "sha512-tNuOCCfunY5v5uhcO2AUMArvKAyKMygX8tfup/JrgnsDqcCATQsAExBq7o5Ml9iMmO82bk6jYNLj6khcrl0JGA==", 1005 | "requires": { 1006 | "argparse": "^1.0.7", 1007 | "entities": "~1.1.1", 1008 | "linkify-it": "^2.0.0", 1009 | "mdurl": "^1.0.1", 1010 | "uc.micro": "^1.0.3" 1011 | } 1012 | }, 1013 | "mdurl": { 1014 | "version": "1.0.1", 1015 | "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", 1016 | "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" 1017 | }, 1018 | "mimic-fn": { 1019 | "version": "1.2.0", 1020 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", 1021 | "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" 1022 | }, 1023 | "minimatch": { 1024 | "version": "3.0.4", 1025 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 1026 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 1027 | "requires": { 1028 | "brace-expansion": "^1.1.7" 1029 | } 1030 | }, 1031 | "minimist": { 1032 | "version": "0.0.8", 1033 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 1034 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" 1035 | }, 1036 | "mkdirp": { 1037 | "version": "0.5.1", 1038 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 1039 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 1040 | "requires": { 1041 | "minimist": "0.0.8" 1042 | } 1043 | }, 1044 | "ms": { 1045 | "version": "2.0.0", 1046 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1047 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 1048 | }, 1049 | "mute-stream": { 1050 | "version": "0.0.7", 1051 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", 1052 | "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" 1053 | }, 1054 | "natural-compare": { 1055 | "version": "1.4.0", 1056 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1057 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" 1058 | }, 1059 | "nice-try": { 1060 | "version": "1.0.5", 1061 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", 1062 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" 1063 | }, 1064 | "node-fetch": { 1065 | "version": "2.6.0", 1066 | "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", 1067 | "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==" 1068 | }, 1069 | "normalize-package-data": { 1070 | "version": "2.4.0", 1071 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", 1072 | "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", 1073 | "requires": { 1074 | "hosted-git-info": "^2.1.4", 1075 | "is-builtin-module": "^1.0.0", 1076 | "semver": "2 || 3 || 4 || 5", 1077 | "validate-npm-package-license": "^3.0.1" 1078 | }, 1079 | "dependencies": { 1080 | "semver": { 1081 | "version": "5.7.1", 1082 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 1083 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" 1084 | } 1085 | } 1086 | }, 1087 | "npm-run-path": { 1088 | "version": "2.0.2", 1089 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", 1090 | "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", 1091 | "requires": { 1092 | "path-key": "^2.0.0" 1093 | } 1094 | }, 1095 | "object-inspect": { 1096 | "version": "1.6.0", 1097 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", 1098 | "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==" 1099 | }, 1100 | "object-keys": { 1101 | "version": "1.1.1", 1102 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 1103 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" 1104 | }, 1105 | "object.assign": { 1106 | "version": "4.1.0", 1107 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", 1108 | "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", 1109 | "requires": { 1110 | "define-properties": "^1.1.2", 1111 | "function-bind": "^1.1.1", 1112 | "has-symbols": "^1.0.0", 1113 | "object-keys": "^1.0.11" 1114 | } 1115 | }, 1116 | "object.entries": { 1117 | "version": "1.1.0", 1118 | "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", 1119 | "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", 1120 | "requires": { 1121 | "define-properties": "^1.1.3", 1122 | "es-abstract": "^1.12.0", 1123 | "function-bind": "^1.1.1", 1124 | "has": "^1.0.3" 1125 | }, 1126 | "dependencies": { 1127 | "has": { 1128 | "version": "1.0.3", 1129 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 1130 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 1131 | "requires": { 1132 | "function-bind": "^1.1.1" 1133 | } 1134 | } 1135 | } 1136 | }, 1137 | "once": { 1138 | "version": "1.4.0", 1139 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1140 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1141 | "requires": { 1142 | "wrappy": "1" 1143 | } 1144 | }, 1145 | "onetime": { 1146 | "version": "2.0.1", 1147 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", 1148 | "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", 1149 | "requires": { 1150 | "mimic-fn": "^1.0.0" 1151 | } 1152 | }, 1153 | "optionator": { 1154 | "version": "0.8.2", 1155 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", 1156 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", 1157 | "requires": { 1158 | "deep-is": "~0.1.3", 1159 | "fast-levenshtein": "~2.0.4", 1160 | "levn": "~0.3.0", 1161 | "prelude-ls": "~1.1.2", 1162 | "type-check": "~0.3.2", 1163 | "wordwrap": "~1.0.0" 1164 | } 1165 | }, 1166 | "os-name": { 1167 | "version": "3.1.0", 1168 | "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz", 1169 | "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==", 1170 | "requires": { 1171 | "macos-release": "^2.2.0", 1172 | "windows-release": "^3.1.0" 1173 | } 1174 | }, 1175 | "os-tmpdir": { 1176 | "version": "1.0.2", 1177 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 1178 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" 1179 | }, 1180 | "p-finally": { 1181 | "version": "1.0.0", 1182 | "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", 1183 | "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" 1184 | }, 1185 | "p-limit": { 1186 | "version": "1.2.0", 1187 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", 1188 | "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", 1189 | "requires": { 1190 | "p-try": "^1.0.0" 1191 | } 1192 | }, 1193 | "p-locate": { 1194 | "version": "2.0.0", 1195 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", 1196 | "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", 1197 | "requires": { 1198 | "p-limit": "^1.1.0" 1199 | } 1200 | }, 1201 | "p-try": { 1202 | "version": "1.0.0", 1203 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", 1204 | "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" 1205 | }, 1206 | "parent-module": { 1207 | "version": "1.0.1", 1208 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 1209 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 1210 | "requires": { 1211 | "callsites": "^3.0.0" 1212 | } 1213 | }, 1214 | "parse-json": { 1215 | "version": "2.2.0", 1216 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", 1217 | "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", 1218 | "requires": { 1219 | "error-ex": "^1.2.0" 1220 | } 1221 | }, 1222 | "path-exists": { 1223 | "version": "2.1.0", 1224 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", 1225 | "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", 1226 | "requires": { 1227 | "pinkie-promise": "^2.0.0" 1228 | } 1229 | }, 1230 | "path-is-absolute": { 1231 | "version": "1.0.1", 1232 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1233 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 1234 | }, 1235 | "path-is-inside": { 1236 | "version": "1.0.2", 1237 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", 1238 | "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" 1239 | }, 1240 | "path-key": { 1241 | "version": "2.0.1", 1242 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 1243 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" 1244 | }, 1245 | "path-parse": { 1246 | "version": "1.0.5", 1247 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", 1248 | "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=" 1249 | }, 1250 | "path-type": { 1251 | "version": "2.0.0", 1252 | "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", 1253 | "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", 1254 | "requires": { 1255 | "pify": "^2.0.0" 1256 | } 1257 | }, 1258 | "pify": { 1259 | "version": "2.3.0", 1260 | "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", 1261 | "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" 1262 | }, 1263 | "pinkie": { 1264 | "version": "2.0.4", 1265 | "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", 1266 | "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" 1267 | }, 1268 | "pinkie-promise": { 1269 | "version": "2.0.1", 1270 | "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", 1271 | "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", 1272 | "requires": { 1273 | "pinkie": "^2.0.0" 1274 | } 1275 | }, 1276 | "pkg-dir": { 1277 | "version": "1.0.0", 1278 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", 1279 | "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", 1280 | "requires": { 1281 | "find-up": "^1.0.0" 1282 | } 1283 | }, 1284 | "prelude-ls": { 1285 | "version": "1.1.2", 1286 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 1287 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" 1288 | }, 1289 | "progress": { 1290 | "version": "2.0.3", 1291 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 1292 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" 1293 | }, 1294 | "pump": { 1295 | "version": "3.0.0", 1296 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 1297 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 1298 | "requires": { 1299 | "end-of-stream": "^1.1.0", 1300 | "once": "^1.3.1" 1301 | } 1302 | }, 1303 | "punycode": { 1304 | "version": "2.1.1", 1305 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 1306 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" 1307 | }, 1308 | "read-pkg": { 1309 | "version": "2.0.0", 1310 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", 1311 | "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", 1312 | "requires": { 1313 | "load-json-file": "^2.0.0", 1314 | "normalize-package-data": "^2.3.2", 1315 | "path-type": "^2.0.0" 1316 | } 1317 | }, 1318 | "read-pkg-up": { 1319 | "version": "2.0.0", 1320 | "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", 1321 | "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", 1322 | "requires": { 1323 | "find-up": "^2.0.0", 1324 | "read-pkg": "^2.0.0" 1325 | }, 1326 | "dependencies": { 1327 | "find-up": { 1328 | "version": "2.1.0", 1329 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", 1330 | "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", 1331 | "requires": { 1332 | "locate-path": "^2.0.0" 1333 | } 1334 | } 1335 | } 1336 | }, 1337 | "regexpp": { 1338 | "version": "2.0.1", 1339 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", 1340 | "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==" 1341 | }, 1342 | "resolve": { 1343 | "version": "1.5.0", 1344 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", 1345 | "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", 1346 | "requires": { 1347 | "path-parse": "^1.0.5" 1348 | } 1349 | }, 1350 | "resolve-from": { 1351 | "version": "4.0.0", 1352 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1353 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" 1354 | }, 1355 | "restore-cursor": { 1356 | "version": "2.0.0", 1357 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", 1358 | "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", 1359 | "requires": { 1360 | "onetime": "^2.0.0", 1361 | "signal-exit": "^3.0.2" 1362 | } 1363 | }, 1364 | "rimraf": { 1365 | "version": "2.6.3", 1366 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 1367 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 1368 | "requires": { 1369 | "glob": "^7.1.3" 1370 | } 1371 | }, 1372 | "run-async": { 1373 | "version": "2.3.0", 1374 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", 1375 | "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", 1376 | "requires": { 1377 | "is-promise": "^2.1.0" 1378 | } 1379 | }, 1380 | "rxjs": { 1381 | "version": "6.5.3", 1382 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", 1383 | "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", 1384 | "requires": { 1385 | "tslib": "^1.9.0" 1386 | } 1387 | }, 1388 | "safer-buffer": { 1389 | "version": "2.1.2", 1390 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1391 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 1392 | }, 1393 | "semver": { 1394 | "version": "6.3.0", 1395 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 1396 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" 1397 | }, 1398 | "shebang-command": { 1399 | "version": "1.2.0", 1400 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 1401 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 1402 | "requires": { 1403 | "shebang-regex": "^1.0.0" 1404 | } 1405 | }, 1406 | "shebang-regex": { 1407 | "version": "1.0.0", 1408 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 1409 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" 1410 | }, 1411 | "signal-exit": { 1412 | "version": "3.0.2", 1413 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 1414 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" 1415 | }, 1416 | "slice-ansi": { 1417 | "version": "2.1.0", 1418 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", 1419 | "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", 1420 | "requires": { 1421 | "ansi-styles": "^3.2.0", 1422 | "astral-regex": "^1.0.0", 1423 | "is-fullwidth-code-point": "^2.0.0" 1424 | } 1425 | }, 1426 | "spdx-correct": { 1427 | "version": "1.0.2", 1428 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", 1429 | "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", 1430 | "requires": { 1431 | "spdx-license-ids": "^1.0.2" 1432 | } 1433 | }, 1434 | "spdx-expression-parse": { 1435 | "version": "1.0.4", 1436 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", 1437 | "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=" 1438 | }, 1439 | "spdx-license-ids": { 1440 | "version": "1.2.2", 1441 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", 1442 | "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=" 1443 | }, 1444 | "sprintf-js": { 1445 | "version": "1.0.3", 1446 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 1447 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" 1448 | }, 1449 | "string-width": { 1450 | "version": "2.1.1", 1451 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 1452 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 1453 | "requires": { 1454 | "is-fullwidth-code-point": "^2.0.0", 1455 | "strip-ansi": "^4.0.0" 1456 | } 1457 | }, 1458 | "string.prototype.trimleft": { 1459 | "version": "2.1.0", 1460 | "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", 1461 | "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", 1462 | "requires": { 1463 | "define-properties": "^1.1.3", 1464 | "function-bind": "^1.1.1" 1465 | } 1466 | }, 1467 | "string.prototype.trimright": { 1468 | "version": "2.1.0", 1469 | "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", 1470 | "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", 1471 | "requires": { 1472 | "define-properties": "^1.1.3", 1473 | "function-bind": "^1.1.1" 1474 | } 1475 | }, 1476 | "strip-ansi": { 1477 | "version": "4.0.0", 1478 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 1479 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 1480 | "requires": { 1481 | "ansi-regex": "^3.0.0" 1482 | } 1483 | }, 1484 | "strip-bom": { 1485 | "version": "3.0.0", 1486 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", 1487 | "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" 1488 | }, 1489 | "strip-eof": { 1490 | "version": "1.0.0", 1491 | "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", 1492 | "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" 1493 | }, 1494 | "strip-json-comments": { 1495 | "version": "2.0.1", 1496 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 1497 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" 1498 | }, 1499 | "supports-color": { 1500 | "version": "5.5.0", 1501 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1502 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1503 | "requires": { 1504 | "has-flag": "^3.0.0" 1505 | }, 1506 | "dependencies": { 1507 | "has-flag": { 1508 | "version": "3.0.0", 1509 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 1510 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" 1511 | } 1512 | } 1513 | }, 1514 | "table": { 1515 | "version": "5.4.6", 1516 | "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", 1517 | "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", 1518 | "requires": { 1519 | "ajv": "^6.10.2", 1520 | "lodash": "^4.17.14", 1521 | "slice-ansi": "^2.1.0", 1522 | "string-width": "^3.0.0" 1523 | }, 1524 | "dependencies": { 1525 | "ajv": { 1526 | "version": "6.10.2", 1527 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", 1528 | "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", 1529 | "requires": { 1530 | "fast-deep-equal": "^2.0.1", 1531 | "fast-json-stable-stringify": "^2.0.0", 1532 | "json-schema-traverse": "^0.4.1", 1533 | "uri-js": "^4.2.2" 1534 | } 1535 | }, 1536 | "ansi-regex": { 1537 | "version": "4.1.0", 1538 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 1539 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" 1540 | }, 1541 | "fast-deep-equal": { 1542 | "version": "2.0.1", 1543 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", 1544 | "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" 1545 | }, 1546 | "json-schema-traverse": { 1547 | "version": "0.4.1", 1548 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 1549 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" 1550 | }, 1551 | "lodash": { 1552 | "version": "4.17.15", 1553 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 1554 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" 1555 | }, 1556 | "string-width": { 1557 | "version": "3.1.0", 1558 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 1559 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 1560 | "requires": { 1561 | "emoji-regex": "^7.0.1", 1562 | "is-fullwidth-code-point": "^2.0.0", 1563 | "strip-ansi": "^5.1.0" 1564 | } 1565 | }, 1566 | "strip-ansi": { 1567 | "version": "5.2.0", 1568 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 1569 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 1570 | "requires": { 1571 | "ansi-regex": "^4.1.0" 1572 | } 1573 | } 1574 | } 1575 | }, 1576 | "text-table": { 1577 | "version": "0.2.0", 1578 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 1579 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" 1580 | }, 1581 | "through": { 1582 | "version": "2.3.8", 1583 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 1584 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" 1585 | }, 1586 | "tmp": { 1587 | "version": "0.0.33", 1588 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 1589 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 1590 | "requires": { 1591 | "os-tmpdir": "~1.0.2" 1592 | } 1593 | }, 1594 | "tslib": { 1595 | "version": "1.10.0", 1596 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", 1597 | "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==" 1598 | }, 1599 | "type-check": { 1600 | "version": "0.3.2", 1601 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 1602 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 1603 | "requires": { 1604 | "prelude-ls": "~1.1.2" 1605 | } 1606 | }, 1607 | "uc.micro": { 1608 | "version": "1.0.3", 1609 | "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.3.tgz", 1610 | "integrity": "sha1-ftUNXg+an7ClczeSWfKndFjVAZI=" 1611 | }, 1612 | "universal-user-agent": { 1613 | "version": "2.1.0", 1614 | "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz", 1615 | "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==", 1616 | "requires": { 1617 | "os-name": "^3.0.0" 1618 | } 1619 | }, 1620 | "uri-js": { 1621 | "version": "4.2.2", 1622 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 1623 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 1624 | "requires": { 1625 | "punycode": "^2.1.0" 1626 | } 1627 | }, 1628 | "url-template": { 1629 | "version": "2.0.8", 1630 | "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz", 1631 | "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=" 1632 | }, 1633 | "validate-npm-package-license": { 1634 | "version": "3.0.1", 1635 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", 1636 | "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", 1637 | "requires": { 1638 | "spdx-correct": "~1.0.0", 1639 | "spdx-expression-parse": "~1.0.0" 1640 | } 1641 | }, 1642 | "which": { 1643 | "version": "1.3.1", 1644 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 1645 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 1646 | "requires": { 1647 | "isexe": "^2.0.0" 1648 | } 1649 | }, 1650 | "windows-release": { 1651 | "version": "3.2.0", 1652 | "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", 1653 | "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==", 1654 | "requires": { 1655 | "execa": "^1.0.0" 1656 | } 1657 | }, 1658 | "wordwrap": { 1659 | "version": "1.0.0", 1660 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 1661 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" 1662 | }, 1663 | "wrappy": { 1664 | "version": "1.0.2", 1665 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1666 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 1667 | }, 1668 | "write": { 1669 | "version": "1.0.3", 1670 | "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", 1671 | "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", 1672 | "requires": { 1673 | "mkdirp": "^0.5.1" 1674 | } 1675 | } 1676 | } 1677 | } 1678 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "releaser", 3 | "version": "1.0.0", 4 | "description": "Generate release notes from git tags and commits.", 5 | "main": "bin/main.js", 6 | "bin": { 7 | "releaser": "bin/main.js" 8 | }, 9 | "scripts": { 10 | "lint": "eslint $(find lib/ -type f -name '*.js') --quiet", 11 | "test": "echo \"Error: no test specified\" && exit 1" 12 | }, 13 | "author": "Mattias Svanström ", 14 | "license": "MIT", 15 | "dependencies": { 16 | "@octokit/rest": "^15.11.4", 17 | "ajv": "^6.0.1", 18 | "chalk": "^2.3.0", 19 | "commander": "^2.13.0", 20 | "eslint": "^5.6.0", 21 | "eslint-config-airbnb-base": "^13.1.0", 22 | "eslint-plugin-import": "^2.8.0", 23 | "execa": "^1.0.0", 24 | "lodash": "^4.17.4", 25 | "markdown-it": "^8.4.0", 26 | "semver": "^6.3.0" 27 | } 28 | } 29 | --------------------------------------------------------------------------------