├── .eslintrc ├── .github └── workflows │ └── test.yml ├── .gitignore ├── .npmignore ├── .nvmrc ├── CODEOWNERS ├── bin ├── generatepath ├── pathreplay └── sample ├── changelog.md ├── index.js ├── license.txt ├── package-lock.json ├── package.json ├── readme.md └── test ├── GeneratePath.test.js ├── RequestStream.test.js ├── SampleStream.test.js ├── bin.test.js └── fixtures ├── AAAAAAAAAAAAAA.2015-10-19-17.e5b6526a ├── AAAAAAAAAAAAAA.2015-10-19-17.e5b6526a.gz ├── AAAAAAAAAAAAAA.2015-10-19-17.e5b6526b.gz ├── AAAAAAAAAAAAAA.2015-10-19-17.e5b6526c.gz └── getObjectResponse.txt /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "indent": [2, 2], 4 | "quotes": [2, "single"], 5 | "quote-props": [2, "as-needed"], 6 | "no-console": [1], 7 | "semi": [2, "always"], 8 | "space-before-function-paren": [2, "never"], 9 | "object-curly-spacing": [2, "always"], 10 | "array-bracket-spacing": [2, "never"], 11 | "comma-spacing": [2, { "before": false, "after": true }], 12 | "key-spacing": [2, { "beforeColon": false, "afterColon": true }] 13 | }, 14 | "env": { 15 | "node": true, 16 | "es6": true 17 | }, 18 | "globals": { 19 | "process": true, 20 | "module": true, 21 | "require": true 22 | }, 23 | "parserOptions": { 24 | "ecmaVersion": 9 25 | }, 26 | "extends": "eslint:recommended" 27 | } 28 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs 3 | 4 | name: Node.js CI 5 | 6 | on: 7 | push: 8 | branches: [main] 9 | pull_request: 10 | branches: [main] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | strategy: 18 | matrix: 19 | node-version: [18.x] 20 | 21 | steps: 22 | - uses: actions/checkout@v3 23 | - name: Use Node.js ${{ matrix.node-version }} 24 | uses: actions/setup-node@v3 25 | with: 26 | node-version: ${{ matrix.node-version }} 27 | cache: 'npm' 28 | - run: npm ci 29 | - run: npm test -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | .vscode -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /test 3 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | 18 -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | 2 | * @mapbox/cloud-platform -------------------------------------------------------------------------------- /bin/generatepath: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var { GeneratePath } = require('..'); 4 | var split = require('split'); 5 | 6 | var type = process.argv[2]; 7 | if (!type || (type !== 'cloudfront' && type !== 'lb')) { 8 | console.error('Usage: generatepath '); 9 | console.error(' can be "cloudfront" or "lb"'); 10 | process.exit(1); 11 | } 12 | 13 | var generatePath = GeneratePath(type); 14 | process.stdin 15 | .pipe(split()) 16 | .pipe(generatePath) 17 | .on('error', function(err) { 18 | console.error(err); 19 | process.exit(1); 20 | }) 21 | .on('data', function(data) { 22 | console.log(data); 23 | }); 24 | -------------------------------------------------------------------------------- /bin/pathreplay: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var { RequestStream } = require('..'); 4 | var keepalive = require('agentkeepalive'); 5 | var split = require('split'); 6 | var stream = require('stream'); 7 | var args = require('minimist')(process.argv.slice(2)); 8 | 9 | var baseurl = args._[0]; 10 | if (!baseurl || baseurl.indexOf('http') == -1) { 11 | console.error('Usage: pathreplay [--concurrency=]'); 12 | process.exit(1); 13 | } 14 | 15 | var hwm = parseInt(args.concurrency) ? parseInt(args.concurrency) : null; 16 | 17 | var agentType = /http:/.test(baseurl)? keepalive : keepalive.HttpsAgent; 18 | var agent = new agentType({ 19 | keepAlive: true, 20 | maxSockets: Math.ceil(require('os').cpus().length * 16), 21 | keepAliveTimeout: 60000 22 | }); 23 | 24 | var transformStream = new stream.Transform({ objectMode: true }); 25 | transformStream._transform = function(line, enc, callback) { 26 | transformStream.push(JSON.parse(line)); 27 | callback(); 28 | }; 29 | 30 | var reqStream = RequestStream({ baseurl: baseurl, agent: agent, hwm: hwm }); 31 | process.stdin 32 | .pipe(split()) 33 | .pipe(transformStream) 34 | .pipe(reqStream) 35 | .on('error', function(err) { 36 | console.error(err); 37 | process.exit(1); 38 | }) 39 | .on('data', function(data) { 40 | console.log(data.body.toString('utf8')); 41 | }); 42 | 43 | -------------------------------------------------------------------------------- /bin/sample: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var { SampleStream } = require('..'); 4 | var split = require('split'); 5 | var argv = require('minimist')(process.argv.slice(2)); 6 | 7 | if (!argv.rate) { 8 | console.error('Usage: sample --rate= [--filter=]'); 9 | process.exit(1); 10 | } 11 | 12 | var sampleStream = SampleStream({ rate: argv.rate, filter: argv.filter || false }); 13 | process.stdin 14 | .pipe(split()) 15 | .pipe(sampleStream) 16 | .on('error', function(err) { 17 | console.error(err); 18 | process.exit(1); 19 | }) 20 | .on('data', function(data) { 21 | console.log(data.toString('utf8')); 22 | }); 23 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. For change log formatting, see http://keepachangelog.com/ 3 | 4 | ## 4.1.0 5 | - Adds option to include given headers in requests 6 | 7 | ## 4.0.0 8 | - Released under the `@mapbox/aws-log-replay` namespace. 9 | - Replace `requestretry` with `got` for the HTTP client [#57](https://github.com/mapbox/aws-log-replay/pull/57) 10 | - Test on Node 16 and 18 11 | - Remove unused dependencies 12 | - Use github actions for running tests 13 | 14 | ## 3.0.0 2022-08-11 15 | - Include request method in stream when generating a path. This will introduce a breaking change. More info in the [#55](https://github.com/mapbox/aws-log-replay/pull/55) PR description 16 | - Request method will be used if passed to RequestStream. Only `GET` or `HEAD` requests are allowed to be replayed 17 | 18 | ## 2.6.1 2022-05-27 19 | - Bumped `requestretry` from 2.0.0 to 7.1.0 20 | 21 | ## 2.6.0 2020-08-13 22 | 23 | - Adds option to include referer in stream when generating a path 24 | - If referer header is passed in to RequestStream, will include referer in request 25 | 26 | ## 2.4.1 2018-01-26 27 | 28 | - Allow timestamps in url paths 29 | 30 | ## 2.4.0 2017-02-23 31 | 32 | - RequestStream strictSSL option to optionally disable SSL cert checking 33 | - RequestStream return all HTTP status codes 34 | 35 | ## 2.3.1 2016-12-08 36 | - Last release without a changelog 37 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var got = require('got'); 2 | var url = require('url'); 3 | var stream = require('stream'); 4 | var crypto = require('crypto'); 5 | var parallel = require('parallel-stream'); 6 | 7 | module.exports = {}; 8 | module.exports.RequestStream = RequestStream; 9 | module.exports.GeneratePath = GeneratePath; 10 | module.exports.SampleStream = SampleStream; 11 | 12 | const allowedMethods = ['GET', 'HEAD']; 13 | 14 | /** 15 | * decode a path according to cloudfront character encoding spec 16 | * http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/AccessLogs.html 17 | * @param {string path} - a cloudfront path to decode 18 | */ 19 | function cloudFrontDecode(path) { 20 | var whitelist = ['3C', '3E', '22', '23', '25', '7B', '7D', '7C', '5C', '5E', '7E', '5B', '5D', '60', '27', '20']; 21 | return path.replace(/%([\dA-F]{2})/g, function(match, hex) { 22 | var code = parseInt(hex, 16); 23 | if ((code < 32) || (code > 127) || (whitelist.indexOf(hex) !== -1)) 24 | return String.fromCharCode(code); 25 | else 26 | return match; 27 | }); 28 | } 29 | 30 | /** 31 | * Transform stream for converting a CF log line into a path and querystring. 32 | * Expects a line-oriented stream of CF log lines. 33 | * @param {string} type 34 | * @param {boolean} keepReferer - set to true if using cloudfront logs and you want to include the referer in the request 35 | */ 36 | function GeneratePath(type, keepReferer = false) { 37 | var generatePath = new stream.Transform({ objectMode: true }); 38 | generatePath._transform = function(line, enc, callback) { 39 | if (!line) return callback(); 40 | if (Buffer.isBuffer(line)) line = line.toString('utf-8'); 41 | if (type.toLowerCase() == 'cloudfront') { 42 | var parts = line.split(/\s+/g); 43 | if (parts.length > 7) { 44 | if (parts[11] && parts[11] !== '-') { 45 | var path = cloudFrontDecode(parts[7] + '?' + parts[11]); 46 | } else { 47 | path = cloudFrontDecode(parts[7]); 48 | } 49 | if (!path) return callback(); 50 | 51 | if (keepReferer && parts[9] && parts[9] !== '-') { 52 | var referer = parts[9]; 53 | } 54 | 55 | const method = parts[5]; 56 | // get Referer & method 57 | if (method && allowedMethods.some((m) => method.includes(m))) { 58 | const obj = { path, method }; 59 | if (referer) obj.referer = referer; 60 | generatePath.push(obj); 61 | } 62 | } 63 | } else if (type.toLowerCase() == 'lb') { 64 | if (line.indexOf('Amazon Route 53 Health Check Service') > -1) return callback(); 65 | parts = line.split(/\s+/g); 66 | if (parts.length < 12) return callback(); 67 | path = parts.length === 18 ? parts[12] : parts[13]; 68 | path = url.parse(path).path; 69 | const method = parts.length === 18 ? parts[11] : parts[12]; 70 | if (!path) return callback(); 71 | 72 | // get request method 73 | // usually it is stored as "GET, regex will help remove the non-alphabetical characters 74 | if (method && allowedMethods.some((m) => method.includes(m))) generatePath.push({ path, method: method.match(/[a-zA-Z]+/g)[0] }); 75 | } 76 | callback(); 77 | }; 78 | return generatePath; 79 | } 80 | 81 | /** 82 | * Transform stream for replaying requests from a log of paths against a specified 83 | * host. LH side expects a line-oriented stream of paths (& querystrings). 84 | * @param {object} options 85 | * @param {string} options.baseurl - Required. An http or https url prepended to paths when making requests. 86 | * @param {string} options.strictSSL - Optional. If true (default), requires SSL/TLS certificates to be valid 87 | * @param {object} options.headers - Optional. Headers to applied to requests 88 | */ 89 | function RequestStream(options) { 90 | options = options || {}; 91 | if (!options.baseurl) throw new Error('options.baseurl should be an http:// or https:// baseurl for replay requests'); 92 | if (!options.hwm) options.hwm = 100; 93 | function transform(data, enc, callback) { 94 | if (this._closed) return setImmediate(callback); 95 | var pathname, referer; 96 | const method = data['method']; 97 | 98 | referer = data['referer']; 99 | if (referer && typeof referer !== 'string') referer = referer.toString('utf8'); 100 | 101 | pathname = data['path']; 102 | if (pathname && typeof pathname !== 'string') pathname = pathname.toString('utf8'); 103 | if (!pathname || pathname.indexOf('/') !== 0) return callback(); 104 | 105 | var url = new URL(pathname, options.baseurl); 106 | 107 | var gotOptions = { 108 | method: method || 'GET', 109 | prefixUrl: options.baseurl, 110 | https: { 111 | rejectUnauthorized: options.strictSSL === false ? false : true 112 | }, 113 | responseType: 'buffer', 114 | time: true, 115 | retry: { limit: 5 }, 116 | throwHttpErrors: false 117 | }; 118 | 119 | if (options.agent) { 120 | if (options.agent.protocol.includes('https')) { 121 | gotOptions.agent = { https: options.agent }; 122 | } else { 123 | gotOptions.agent = { http: options.agent }; 124 | } 125 | } 126 | 127 | if (referer) { 128 | gotOptions.headers = { referer }; 129 | } 130 | 131 | if(options.headers) { 132 | gotOptions.headers = { ...gotOptions.headers, ...options.headers }; 133 | } 134 | 135 | got(url, gotOptions) 136 | .then(({ statusCode, body, timings }) => { 137 | this.push({ 138 | url: url.toString(), 139 | elapsedTime: timings.phases.total, 140 | statusCode, 141 | body 142 | }); 143 | callback(); 144 | }) 145 | .catch((error) => { 146 | return callback(error); 147 | }); 148 | } 149 | 150 | var requestStream = parallel.transform(transform, { concurrency: options.hwm, objectMode: true }); 151 | requestStream.close = function() { 152 | requestStream._closed = true; 153 | }; 154 | 155 | return requestStream; 156 | } 157 | 158 | /** 159 | * Emit lines at a specified sample rate & with optional filter regex. 160 | * Behaves deterministically so given param/input combinations will return 161 | * reliably identical results. 162 | * @param {object} options 163 | * @param {number} options.sample - Required. Sample rate between 0 and 1.0 164 | * @param {string} options.filter - Optional. Regex pre-filter applied to input. 165 | */ 166 | function SampleStream(options) { 167 | options = options || {}; 168 | if (!options.rate) throw new Error('must specify a sample rate (0 < sample < 1)'); 169 | if ((parseFloat(options.rate) <= 0) || (parseFloat(options.rate) >= 1)) throw new Error('rate must be between 0 and 1'); 170 | 171 | var sampleStream = new stream.Transform({ objectMode: true }); 172 | sampleStream.count = 0; 173 | sampleStream.threshold = Math.round(parseFloat(options.rate) * Math.pow(2, 16)); 174 | if (options.filter) { 175 | sampleStream.filterFunction = new RegExp(options.filter); 176 | } 177 | sampleStream._transform = function(line, enc, callback) { 178 | if (!line) return callback(); 179 | if (sampleStream.filterFunction && !sampleStream.filterFunction.test(line)) return callback(); 180 | 181 | var hash = crypto.createHash('md5').update('cloudfront-log-read-salt-' + sampleStream.count).digest().readUInt16LE(0); 182 | if (hash < sampleStream.threshold) 183 | sampleStream.push(line); 184 | sampleStream.count++; 185 | 186 | callback(); 187 | }; 188 | 189 | return sampleStream; 190 | } 191 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | BSD 2-Clause License 2 | 3 | Copyright (c) 2017, Mapbox 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 20 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@mapbox/aws-log-replay", 3 | "version": "4.1.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@mapbox/aws-log-replay", 9 | "version": "4.1.0", 10 | "license": "BSD-2-Clause", 11 | "dependencies": { 12 | "agentkeepalive": "^3.5.1", 13 | "got": "^11.8.6", 14 | "minimist": "^1.2.8", 15 | "parallel-stream": "^1.1.2", 16 | "split": "^1.0.1" 17 | }, 18 | "bin": { 19 | "generatepath": "bin/generatepath", 20 | "pathreplay": "bin/pathreplay", 21 | "sample": "bin/sample" 22 | }, 23 | "devDependencies": { 24 | "eslint": "^4.19.1", 25 | "tape": "3.5.x" 26 | }, 27 | "engines": { 28 | "node": ">=18" 29 | } 30 | }, 31 | "node_modules/@sindresorhus/is": { 32 | "version": "4.6.0", 33 | "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", 34 | "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", 35 | "engines": { 36 | "node": ">=10" 37 | }, 38 | "funding": { 39 | "url": "https://github.com/sindresorhus/is?sponsor=1" 40 | } 41 | }, 42 | "node_modules/@szmarczak/http-timer": { 43 | "version": "4.0.6", 44 | "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", 45 | "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", 46 | "dependencies": { 47 | "defer-to-connect": "^2.0.0" 48 | }, 49 | "engines": { 50 | "node": ">=10" 51 | } 52 | }, 53 | "node_modules/@types/cacheable-request": { 54 | "version": "6.0.3", 55 | "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", 56 | "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", 57 | "dependencies": { 58 | "@types/http-cache-semantics": "*", 59 | "@types/keyv": "^3.1.4", 60 | "@types/node": "*", 61 | "@types/responselike": "^1.0.0" 62 | } 63 | }, 64 | "node_modules/@types/http-cache-semantics": { 65 | "version": "4.0.2", 66 | "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.2.tgz", 67 | "integrity": "sha512-FD+nQWA2zJjh4L9+pFXqWOi0Hs1ryBCfI+985NjluQ1p8EYtoLvjLOKidXBtZ4/IcxDX4o8/E8qDS3540tNliw==" 68 | }, 69 | "node_modules/@types/keyv": { 70 | "version": "3.1.4", 71 | "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", 72 | "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", 73 | "dependencies": { 74 | "@types/node": "*" 75 | } 76 | }, 77 | "node_modules/@types/node": { 78 | "version": "20.7.0", 79 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.7.0.tgz", 80 | "integrity": "sha512-zI22/pJW2wUZOVyguFaUL1HABdmSVxpXrzIqkjsHmyUjNhPoWM1CKfvVuXfetHhIok4RY573cqS0mZ1SJEnoTg==" 81 | }, 82 | "node_modules/@types/responselike": { 83 | "version": "1.0.0", 84 | "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", 85 | "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", 86 | "dependencies": { 87 | "@types/node": "*" 88 | } 89 | }, 90 | "node_modules/acorn": { 91 | "version": "5.7.1", 92 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", 93 | "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==", 94 | "dev": true, 95 | "bin": { 96 | "acorn": "bin/acorn" 97 | }, 98 | "engines": { 99 | "node": ">=0.4.0" 100 | } 101 | }, 102 | "node_modules/acorn-jsx": { 103 | "version": "3.0.1", 104 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", 105 | "integrity": "sha512-AU7pnZkguthwBjKgCg6998ByQNIMjbuDQZ8bb78QAFZwPfmKia8AIzgY/gWgqCjnht8JLdXmB4YxA0KaV60ncQ==", 106 | "dev": true, 107 | "dependencies": { 108 | "acorn": "^3.0.4" 109 | } 110 | }, 111 | "node_modules/acorn-jsx/node_modules/acorn": { 112 | "version": "3.3.0", 113 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", 114 | "integrity": "sha512-OLUyIIZ7mF5oaAUT1w0TFqQS81q3saT46x8t7ukpPjMNk+nbs4ZHhs7ToV8EWnLYLepjETXd4XaCE4uxkMeqUw==", 115 | "dev": true, 116 | "bin": { 117 | "acorn": "bin/acorn" 118 | }, 119 | "engines": { 120 | "node": ">=0.4.0" 121 | } 122 | }, 123 | "node_modules/agentkeepalive": { 124 | "version": "3.5.1", 125 | "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.1.tgz", 126 | "integrity": "sha512-Cte/sTY9/XcygXjJ0q58v//SnEQ7ViWExKyJpLJlLqomDbQyMLh6Is4KuWJ/wmxzhiwkGRple7Gqv1zf6Syz5w==", 127 | "dependencies": { 128 | "humanize-ms": "^1.2.1" 129 | }, 130 | "engines": { 131 | "node": ">= 4.0.0" 132 | } 133 | }, 134 | "node_modules/ajv": { 135 | "version": "5.5.2", 136 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", 137 | "integrity": "sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==", 138 | "dev": true, 139 | "dependencies": { 140 | "co": "^4.6.0", 141 | "fast-deep-equal": "^1.0.0", 142 | "fast-json-stable-stringify": "^2.0.0", 143 | "json-schema-traverse": "^0.3.0" 144 | } 145 | }, 146 | "node_modules/ajv-keywords": { 147 | "version": "2.1.1", 148 | "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", 149 | "integrity": "sha512-ZFztHzVRdGLAzJmpUT9LNFLe1YiVOEylcaNpEutM26PVTCtOD919IMfD01CgbRouB42Dd9atjx1HseC15DgOZA==", 150 | "dev": true, 151 | "peerDependencies": { 152 | "ajv": "^5.0.0" 153 | } 154 | }, 155 | "node_modules/ansi-escapes": { 156 | "version": "3.2.0", 157 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", 158 | "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", 159 | "dev": true, 160 | "engines": { 161 | "node": ">=4" 162 | } 163 | }, 164 | "node_modules/ansi-regex": { 165 | "version": "2.1.1", 166 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 167 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", 168 | "dev": true, 169 | "engines": { 170 | "node": ">=0.10.0" 171 | } 172 | }, 173 | "node_modules/ansi-styles": { 174 | "version": "2.2.1", 175 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", 176 | "integrity": "sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==", 177 | "dev": true, 178 | "engines": { 179 | "node": ">=0.10.0" 180 | } 181 | }, 182 | "node_modules/babel-code-frame": { 183 | "version": "6.26.0", 184 | "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", 185 | "integrity": "sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==", 186 | "dev": true, 187 | "dependencies": { 188 | "chalk": "^1.1.3", 189 | "esutils": "^2.0.2", 190 | "js-tokens": "^3.0.2" 191 | } 192 | }, 193 | "node_modules/babel-code-frame/node_modules/chalk": { 194 | "version": "1.1.3", 195 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", 196 | "integrity": "sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==", 197 | "dev": true, 198 | "dependencies": { 199 | "ansi-styles": "^2.2.1", 200 | "escape-string-regexp": "^1.0.2", 201 | "has-ansi": "^2.0.0", 202 | "strip-ansi": "^3.0.0", 203 | "supports-color": "^2.0.0" 204 | }, 205 | "engines": { 206 | "node": ">=0.10.0" 207 | } 208 | }, 209 | "node_modules/babel-code-frame/node_modules/esutils": { 210 | "version": "2.0.3", 211 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 212 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 213 | "dev": true, 214 | "engines": { 215 | "node": ">=0.10.0" 216 | } 217 | }, 218 | "node_modules/babel-code-frame/node_modules/supports-color": { 219 | "version": "2.0.0", 220 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", 221 | "integrity": "sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==", 222 | "dev": true, 223 | "engines": { 224 | "node": ">=0.8.0" 225 | } 226 | }, 227 | "node_modules/balanced-match": { 228 | "version": "1.0.0", 229 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 230 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 231 | "dev": true 232 | }, 233 | "node_modules/brace-expansion": { 234 | "version": "1.1.11", 235 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 236 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 237 | "dev": true, 238 | "dependencies": { 239 | "balanced-match": "^1.0.0", 240 | "concat-map": "0.0.1" 241 | } 242 | }, 243 | "node_modules/buffer-from": { 244 | "version": "1.1.1", 245 | "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", 246 | "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", 247 | "dev": true 248 | }, 249 | "node_modules/cacheable-lookup": { 250 | "version": "5.0.4", 251 | "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", 252 | "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", 253 | "engines": { 254 | "node": ">=10.6.0" 255 | } 256 | }, 257 | "node_modules/cacheable-request": { 258 | "version": "7.0.4", 259 | "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", 260 | "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", 261 | "dependencies": { 262 | "clone-response": "^1.0.2", 263 | "get-stream": "^5.1.0", 264 | "http-cache-semantics": "^4.0.0", 265 | "keyv": "^4.0.0", 266 | "lowercase-keys": "^2.0.0", 267 | "normalize-url": "^6.0.1", 268 | "responselike": "^2.0.0" 269 | }, 270 | "engines": { 271 | "node": ">=8" 272 | } 273 | }, 274 | "node_modules/caller-path": { 275 | "version": "0.1.0", 276 | "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", 277 | "integrity": "sha512-UJiE1otjXPF5/x+T3zTnSFiTOEmJoGTD9HmBoxnCUwho61a2eSNn/VwtwuIBDAo2SEOv1AJ7ARI5gCmohFLu/g==", 278 | "dev": true, 279 | "dependencies": { 280 | "callsites": "^0.2.0" 281 | }, 282 | "engines": { 283 | "node": ">=0.10.0" 284 | } 285 | }, 286 | "node_modules/callsites": { 287 | "version": "0.2.0", 288 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", 289 | "integrity": "sha512-Zv4Dns9IbXXmPkgRRUjAaJQgfN4xX5p6+RQFhWUqscdvvK2xK/ZL8b3IXIJsj+4sD+f24NwnWy2BY8AJ82JB0A==", 290 | "dev": true, 291 | "engines": { 292 | "node": ">=0.10.0" 293 | } 294 | }, 295 | "node_modules/chalk": { 296 | "version": "2.4.2", 297 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 298 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 299 | "dev": true, 300 | "dependencies": { 301 | "ansi-styles": "^3.2.1", 302 | "escape-string-regexp": "^1.0.5", 303 | "supports-color": "^5.3.0" 304 | }, 305 | "engines": { 306 | "node": ">=4" 307 | } 308 | }, 309 | "node_modules/chalk/node_modules/ansi-styles": { 310 | "version": "3.2.1", 311 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 312 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 313 | "dev": true, 314 | "dependencies": { 315 | "color-convert": "^1.9.0" 316 | }, 317 | "engines": { 318 | "node": ">=4" 319 | } 320 | }, 321 | "node_modules/chardet": { 322 | "version": "0.4.2", 323 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", 324 | "integrity": "sha512-j/Toj7f1z98Hh2cYo2BVr85EpIRWqUi7rtRSGxh/cqUjqrnJe9l9UE7IUGd2vQ2p+kSHLkSzObQPZPLUC6TQwg==", 325 | "dev": true 326 | }, 327 | "node_modules/circular-json": { 328 | "version": "0.3.3", 329 | "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", 330 | "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", 331 | "deprecated": "CircularJSON is in maintenance only, flatted is its successor.", 332 | "dev": true 333 | }, 334 | "node_modules/cli-cursor": { 335 | "version": "2.1.0", 336 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", 337 | "integrity": "sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==", 338 | "dev": true, 339 | "dependencies": { 340 | "restore-cursor": "^2.0.0" 341 | }, 342 | "engines": { 343 | "node": ">=4" 344 | } 345 | }, 346 | "node_modules/cli-width": { 347 | "version": "2.2.1", 348 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", 349 | "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", 350 | "dev": true 351 | }, 352 | "node_modules/clone-response": { 353 | "version": "1.0.3", 354 | "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", 355 | "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", 356 | "dependencies": { 357 | "mimic-response": "^1.0.0" 358 | }, 359 | "funding": { 360 | "url": "https://github.com/sponsors/sindresorhus" 361 | } 362 | }, 363 | "node_modules/co": { 364 | "version": "4.6.0", 365 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 366 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", 367 | "dev": true, 368 | "engines": { 369 | "iojs": ">= 1.0.0", 370 | "node": ">= 0.12.0" 371 | } 372 | }, 373 | "node_modules/color-convert": { 374 | "version": "1.9.3", 375 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 376 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 377 | "dev": true, 378 | "dependencies": { 379 | "color-name": "1.1.3" 380 | } 381 | }, 382 | "node_modules/color-name": { 383 | "version": "1.1.3", 384 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 385 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", 386 | "dev": true 387 | }, 388 | "node_modules/concat-map": { 389 | "version": "0.0.1", 390 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 391 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 392 | "dev": true 393 | }, 394 | "node_modules/concat-stream": { 395 | "version": "1.6.2", 396 | "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", 397 | "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", 398 | "dev": true, 399 | "engines": [ 400 | "node >= 0.8" 401 | ], 402 | "dependencies": { 403 | "buffer-from": "^1.0.0", 404 | "inherits": "^2.0.3", 405 | "readable-stream": "^2.2.2", 406 | "typedarray": "^0.0.6" 407 | } 408 | }, 409 | "node_modules/core-util-is": { 410 | "version": "1.0.2", 411 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 412 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", 413 | "dev": true 414 | }, 415 | "node_modules/cross-spawn": { 416 | "version": "5.1.0", 417 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", 418 | "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", 419 | "dev": true, 420 | "dependencies": { 421 | "lru-cache": "^4.0.1", 422 | "shebang-command": "^1.2.0", 423 | "which": "^1.2.9" 424 | } 425 | }, 426 | "node_modules/cross-spawn/node_modules/lru-cache": { 427 | "version": "4.1.5", 428 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", 429 | "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", 430 | "dev": true, 431 | "dependencies": { 432 | "pseudomap": "^1.0.2", 433 | "yallist": "^2.1.2" 434 | } 435 | }, 436 | "node_modules/debug": { 437 | "version": "3.2.7", 438 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", 439 | "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", 440 | "dev": true, 441 | "dependencies": { 442 | "ms": "^2.1.1" 443 | } 444 | }, 445 | "node_modules/decompress-response": { 446 | "version": "6.0.0", 447 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", 448 | "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", 449 | "dependencies": { 450 | "mimic-response": "^3.1.0" 451 | }, 452 | "engines": { 453 | "node": ">=10" 454 | }, 455 | "funding": { 456 | "url": "https://github.com/sponsors/sindresorhus" 457 | } 458 | }, 459 | "node_modules/decompress-response/node_modules/mimic-response": { 460 | "version": "3.1.0", 461 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", 462 | "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", 463 | "engines": { 464 | "node": ">=10" 465 | }, 466 | "funding": { 467 | "url": "https://github.com/sponsors/sindresorhus" 468 | } 469 | }, 470 | "node_modules/deep-equal": { 471 | "version": "0.2.2", 472 | "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-0.2.2.tgz", 473 | "integrity": "sha1-hLdFiW80xoTpjyzg5Cq69Du6AX0=", 474 | "dev": true 475 | }, 476 | "node_modules/deep-is": { 477 | "version": "0.1.4", 478 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", 479 | "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", 480 | "dev": true 481 | }, 482 | "node_modules/defer-to-connect": { 483 | "version": "2.0.1", 484 | "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", 485 | "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", 486 | "engines": { 487 | "node": ">=10" 488 | } 489 | }, 490 | "node_modules/end-of-stream": { 491 | "version": "1.4.1", 492 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", 493 | "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", 494 | "dependencies": { 495 | "once": "^1.4.0" 496 | } 497 | }, 498 | "node_modules/escape-string-regexp": { 499 | "version": "1.0.5", 500 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 501 | "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", 502 | "dev": true, 503 | "engines": { 504 | "node": ">=0.8.0" 505 | } 506 | }, 507 | "node_modules/eslint": { 508 | "version": "4.19.1", 509 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", 510 | "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", 511 | "dev": true, 512 | "dependencies": { 513 | "ajv": "^5.3.0", 514 | "babel-code-frame": "^6.22.0", 515 | "chalk": "^2.1.0", 516 | "concat-stream": "^1.6.0", 517 | "cross-spawn": "^5.1.0", 518 | "debug": "^3.1.0", 519 | "doctrine": "^2.1.0", 520 | "eslint-scope": "^3.7.1", 521 | "eslint-visitor-keys": "^1.0.0", 522 | "espree": "^3.5.4", 523 | "esquery": "^1.0.0", 524 | "esutils": "^2.0.2", 525 | "file-entry-cache": "^2.0.0", 526 | "functional-red-black-tree": "^1.0.1", 527 | "glob": "^7.1.2", 528 | "globals": "^11.0.1", 529 | "ignore": "^3.3.3", 530 | "imurmurhash": "^0.1.4", 531 | "inquirer": "^3.0.6", 532 | "is-resolvable": "^1.0.0", 533 | "js-yaml": "^3.9.1", 534 | "json-stable-stringify-without-jsonify": "^1.0.1", 535 | "levn": "^0.3.0", 536 | "lodash": "^4.17.4", 537 | "minimatch": "^3.0.2", 538 | "mkdirp": "^0.5.1", 539 | "natural-compare": "^1.4.0", 540 | "optionator": "^0.8.2", 541 | "path-is-inside": "^1.0.2", 542 | "pluralize": "^7.0.0", 543 | "progress": "^2.0.0", 544 | "regexpp": "^1.0.1", 545 | "require-uncached": "^1.0.3", 546 | "semver": "^5.3.0", 547 | "strip-ansi": "^4.0.0", 548 | "strip-json-comments": "~2.0.1", 549 | "table": "4.0.2", 550 | "text-table": "~0.2.0" 551 | }, 552 | "bin": { 553 | "eslint": "bin/eslint.js" 554 | }, 555 | "engines": { 556 | "node": ">=4" 557 | } 558 | }, 559 | "node_modules/eslint-scope": { 560 | "version": "3.7.3", 561 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.3.tgz", 562 | "integrity": "sha512-W+B0SvF4gamyCTmUc+uITPY0989iXVfKvhwtmJocTaYoc/3khEHmEmvfY/Gn9HA9VV75jrQECsHizkNw1b68FA==", 563 | "dev": true, 564 | "dependencies": { 565 | "esrecurse": "^4.1.0", 566 | "estraverse": "^4.1.1" 567 | }, 568 | "engines": { 569 | "node": ">=4.0.0" 570 | } 571 | }, 572 | "node_modules/eslint-visitor-keys": { 573 | "version": "1.3.0", 574 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", 575 | "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", 576 | "dev": true, 577 | "engines": { 578 | "node": ">=4" 579 | } 580 | }, 581 | "node_modules/eslint/node_modules/ansi-regex": { 582 | "version": "3.0.1", 583 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", 584 | "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", 585 | "dev": true, 586 | "engines": { 587 | "node": ">=4" 588 | } 589 | }, 590 | "node_modules/eslint/node_modules/doctrine": { 591 | "version": "2.1.0", 592 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", 593 | "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", 594 | "dev": true, 595 | "dependencies": { 596 | "esutils": "^2.0.2" 597 | }, 598 | "engines": { 599 | "node": ">=0.10.0" 600 | } 601 | }, 602 | "node_modules/eslint/node_modules/espree": { 603 | "version": "3.5.4", 604 | "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", 605 | "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", 606 | "dev": true, 607 | "dependencies": { 608 | "acorn": "^5.5.0", 609 | "acorn-jsx": "^3.0.0" 610 | }, 611 | "engines": { 612 | "node": ">=0.10.0" 613 | } 614 | }, 615 | "node_modules/eslint/node_modules/esutils": { 616 | "version": "2.0.3", 617 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 618 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", 619 | "dev": true, 620 | "engines": { 621 | "node": ">=0.10.0" 622 | } 623 | }, 624 | "node_modules/eslint/node_modules/glob": { 625 | "version": "7.2.3", 626 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 627 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 628 | "dev": true, 629 | "dependencies": { 630 | "fs.realpath": "^1.0.0", 631 | "inflight": "^1.0.4", 632 | "inherits": "2", 633 | "minimatch": "^3.1.1", 634 | "once": "^1.3.0", 635 | "path-is-absolute": "^1.0.0" 636 | }, 637 | "engines": { 638 | "node": "*" 639 | }, 640 | "funding": { 641 | "url": "https://github.com/sponsors/isaacs" 642 | } 643 | }, 644 | "node_modules/eslint/node_modules/minimatch": { 645 | "version": "3.1.2", 646 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 647 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 648 | "dev": true, 649 | "dependencies": { 650 | "brace-expansion": "^1.1.7" 651 | }, 652 | "engines": { 653 | "node": "*" 654 | } 655 | }, 656 | "node_modules/eslint/node_modules/strip-ansi": { 657 | "version": "4.0.0", 658 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 659 | "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", 660 | "dev": true, 661 | "dependencies": { 662 | "ansi-regex": "^3.0.0" 663 | }, 664 | "engines": { 665 | "node": ">=4" 666 | } 667 | }, 668 | "node_modules/esquery": { 669 | "version": "1.4.0", 670 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", 671 | "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", 672 | "dev": true, 673 | "dependencies": { 674 | "estraverse": "^5.1.0" 675 | }, 676 | "engines": { 677 | "node": ">=0.10" 678 | } 679 | }, 680 | "node_modules/esquery/node_modules/estraverse": { 681 | "version": "5.3.0", 682 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 683 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 684 | "dev": true, 685 | "engines": { 686 | "node": ">=4.0" 687 | } 688 | }, 689 | "node_modules/esrecurse": { 690 | "version": "4.3.0", 691 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", 692 | "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", 693 | "dev": true, 694 | "dependencies": { 695 | "estraverse": "^5.2.0" 696 | }, 697 | "engines": { 698 | "node": ">=4.0" 699 | } 700 | }, 701 | "node_modules/esrecurse/node_modules/estraverse": { 702 | "version": "5.3.0", 703 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", 704 | "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", 705 | "dev": true, 706 | "engines": { 707 | "node": ">=4.0" 708 | } 709 | }, 710 | "node_modules/estraverse": { 711 | "version": "4.3.0", 712 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 713 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 714 | "dev": true, 715 | "engines": { 716 | "node": ">=4.0" 717 | } 718 | }, 719 | "node_modules/external-editor": { 720 | "version": "2.2.0", 721 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", 722 | "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", 723 | "dev": true, 724 | "dependencies": { 725 | "chardet": "^0.4.0", 726 | "iconv-lite": "^0.4.17", 727 | "tmp": "^0.0.33" 728 | }, 729 | "engines": { 730 | "node": ">=0.12" 731 | } 732 | }, 733 | "node_modules/fast-deep-equal": { 734 | "version": "1.1.0", 735 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", 736 | "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", 737 | "dev": true 738 | }, 739 | "node_modules/fast-json-stable-stringify": { 740 | "version": "2.0.0", 741 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 742 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", 743 | "dev": true 744 | }, 745 | "node_modules/fast-levenshtein": { 746 | "version": "2.0.6", 747 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 748 | "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", 749 | "dev": true 750 | }, 751 | "node_modules/figures": { 752 | "version": "2.0.0", 753 | "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", 754 | "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==", 755 | "dev": true, 756 | "dependencies": { 757 | "escape-string-regexp": "^1.0.5" 758 | }, 759 | "engines": { 760 | "node": ">=4" 761 | } 762 | }, 763 | "node_modules/file-entry-cache": { 764 | "version": "2.0.0", 765 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", 766 | "integrity": "sha512-uXP/zGzxxFvFfcZGgBIwotm+Tdc55ddPAzF7iHshP4YGaXMww7rSF9peD9D1sui5ebONg5UobsZv+FfgEpGv/w==", 767 | "dev": true, 768 | "dependencies": { 769 | "flat-cache": "^1.2.1", 770 | "object-assign": "^4.0.1" 771 | }, 772 | "engines": { 773 | "node": ">=0.10.0" 774 | } 775 | }, 776 | "node_modules/file-entry-cache/node_modules/object-assign": { 777 | "version": "4.1.1", 778 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 779 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 780 | "dev": true, 781 | "engines": { 782 | "node": ">=0.10.0" 783 | } 784 | }, 785 | "node_modules/flat-cache": { 786 | "version": "1.3.4", 787 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", 788 | "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", 789 | "dev": true, 790 | "dependencies": { 791 | "circular-json": "^0.3.1", 792 | "graceful-fs": "^4.1.2", 793 | "rimraf": "~2.6.2", 794 | "write": "^0.2.1" 795 | }, 796 | "engines": { 797 | "node": ">=0.10.0" 798 | } 799 | }, 800 | "node_modules/flat-cache/node_modules/graceful-fs": { 801 | "version": "4.2.10", 802 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", 803 | "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", 804 | "dev": true 805 | }, 806 | "node_modules/fs.realpath": { 807 | "version": "1.0.0", 808 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 809 | "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", 810 | "dev": true 811 | }, 812 | "node_modules/functional-red-black-tree": { 813 | "version": "1.0.1", 814 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 815 | "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", 816 | "dev": true 817 | }, 818 | "node_modules/get-stream": { 819 | "version": "5.2.0", 820 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", 821 | "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", 822 | "dependencies": { 823 | "pump": "^3.0.0" 824 | }, 825 | "engines": { 826 | "node": ">=8" 827 | }, 828 | "funding": { 829 | "url": "https://github.com/sponsors/sindresorhus" 830 | } 831 | }, 832 | "node_modules/globals": { 833 | "version": "11.12.0", 834 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", 835 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", 836 | "dev": true, 837 | "engines": { 838 | "node": ">=4" 839 | } 840 | }, 841 | "node_modules/got": { 842 | "version": "11.8.6", 843 | "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", 844 | "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", 845 | "dependencies": { 846 | "@sindresorhus/is": "^4.0.0", 847 | "@szmarczak/http-timer": "^4.0.5", 848 | "@types/cacheable-request": "^6.0.1", 849 | "@types/responselike": "^1.0.0", 850 | "cacheable-lookup": "^5.0.3", 851 | "cacheable-request": "^7.0.2", 852 | "decompress-response": "^6.0.0", 853 | "http2-wrapper": "^1.0.0-beta.5.2", 854 | "lowercase-keys": "^2.0.0", 855 | "p-cancelable": "^2.0.0", 856 | "responselike": "^2.0.0" 857 | }, 858 | "engines": { 859 | "node": ">=10.19.0" 860 | }, 861 | "funding": { 862 | "url": "https://github.com/sindresorhus/got?sponsor=1" 863 | } 864 | }, 865 | "node_modules/has-ansi": { 866 | "version": "2.0.0", 867 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", 868 | "integrity": "sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==", 869 | "dev": true, 870 | "dependencies": { 871 | "ansi-regex": "^2.0.0" 872 | }, 873 | "engines": { 874 | "node": ">=0.10.0" 875 | } 876 | }, 877 | "node_modules/has-flag": { 878 | "version": "3.0.0", 879 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 880 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 881 | "dev": true, 882 | "engines": { 883 | "node": ">=4" 884 | } 885 | }, 886 | "node_modules/http-cache-semantics": { 887 | "version": "4.1.1", 888 | "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", 889 | "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" 890 | }, 891 | "node_modules/http2-wrapper": { 892 | "version": "1.0.3", 893 | "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", 894 | "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", 895 | "dependencies": { 896 | "quick-lru": "^5.1.1", 897 | "resolve-alpn": "^1.0.0" 898 | }, 899 | "engines": { 900 | "node": ">=10.19.0" 901 | } 902 | }, 903 | "node_modules/humanize-ms": { 904 | "version": "1.2.1", 905 | "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", 906 | "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", 907 | "dependencies": { 908 | "ms": "^2.0.0" 909 | } 910 | }, 911 | "node_modules/iconv-lite": { 912 | "version": "0.4.24", 913 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 914 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 915 | "dev": true, 916 | "dependencies": { 917 | "safer-buffer": ">= 2.1.2 < 3" 918 | }, 919 | "engines": { 920 | "node": ">=0.10.0" 921 | } 922 | }, 923 | "node_modules/ignore": { 924 | "version": "3.3.10", 925 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", 926 | "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", 927 | "dev": true 928 | }, 929 | "node_modules/imurmurhash": { 930 | "version": "0.1.4", 931 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 932 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 933 | "dev": true, 934 | "engines": { 935 | "node": ">=0.8.19" 936 | } 937 | }, 938 | "node_modules/inflight": { 939 | "version": "1.0.6", 940 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 941 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 942 | "dev": true, 943 | "dependencies": { 944 | "once": "^1.3.0", 945 | "wrappy": "1" 946 | } 947 | }, 948 | "node_modules/inherits": { 949 | "version": "2.0.3", 950 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 951 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 952 | "dev": true 953 | }, 954 | "node_modules/inquirer": { 955 | "version": "3.3.0", 956 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", 957 | "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", 958 | "dev": true, 959 | "dependencies": { 960 | "ansi-escapes": "^3.0.0", 961 | "chalk": "^2.0.0", 962 | "cli-cursor": "^2.1.0", 963 | "cli-width": "^2.0.0", 964 | "external-editor": "^2.0.4", 965 | "figures": "^2.0.0", 966 | "lodash": "^4.3.0", 967 | "mute-stream": "0.0.7", 968 | "run-async": "^2.2.0", 969 | "rx-lite": "^4.0.8", 970 | "rx-lite-aggregates": "^4.0.8", 971 | "string-width": "^2.1.0", 972 | "strip-ansi": "^4.0.0", 973 | "through": "^2.3.6" 974 | } 975 | }, 976 | "node_modules/inquirer/node_modules/ansi-regex": { 977 | "version": "3.0.1", 978 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", 979 | "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", 980 | "dev": true, 981 | "engines": { 982 | "node": ">=4" 983 | } 984 | }, 985 | "node_modules/inquirer/node_modules/is-fullwidth-code-point": { 986 | "version": "2.0.0", 987 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 988 | "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", 989 | "dev": true, 990 | "engines": { 991 | "node": ">=4" 992 | } 993 | }, 994 | "node_modules/inquirer/node_modules/string-width": { 995 | "version": "2.1.1", 996 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 997 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 998 | "dev": true, 999 | "dependencies": { 1000 | "is-fullwidth-code-point": "^2.0.0", 1001 | "strip-ansi": "^4.0.0" 1002 | }, 1003 | "engines": { 1004 | "node": ">=4" 1005 | } 1006 | }, 1007 | "node_modules/inquirer/node_modules/strip-ansi": { 1008 | "version": "4.0.0", 1009 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 1010 | "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", 1011 | "dev": true, 1012 | "dependencies": { 1013 | "ansi-regex": "^3.0.0" 1014 | }, 1015 | "engines": { 1016 | "node": ">=4" 1017 | } 1018 | }, 1019 | "node_modules/is-resolvable": { 1020 | "version": "1.1.0", 1021 | "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", 1022 | "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", 1023 | "dev": true 1024 | }, 1025 | "node_modules/isarray": { 1026 | "version": "1.0.0", 1027 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 1028 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", 1029 | "dev": true 1030 | }, 1031 | "node_modules/isexe": { 1032 | "version": "2.0.0", 1033 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1034 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 1035 | "dev": true 1036 | }, 1037 | "node_modules/js-tokens": { 1038 | "version": "3.0.2", 1039 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", 1040 | "integrity": "sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==", 1041 | "dev": true 1042 | }, 1043 | "node_modules/js-yaml": { 1044 | "version": "3.14.1", 1045 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", 1046 | "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", 1047 | "dev": true, 1048 | "dependencies": { 1049 | "argparse": "^1.0.7", 1050 | "esprima": "^4.0.0" 1051 | }, 1052 | "bin": { 1053 | "js-yaml": "bin/js-yaml.js" 1054 | } 1055 | }, 1056 | "node_modules/js-yaml/node_modules/argparse": { 1057 | "version": "1.0.10", 1058 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 1059 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 1060 | "dev": true, 1061 | "dependencies": { 1062 | "sprintf-js": "~1.0.2" 1063 | } 1064 | }, 1065 | "node_modules/js-yaml/node_modules/esprima": { 1066 | "version": "4.0.1", 1067 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 1068 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 1069 | "dev": true, 1070 | "bin": { 1071 | "esparse": "bin/esparse.js", 1072 | "esvalidate": "bin/esvalidate.js" 1073 | }, 1074 | "engines": { 1075 | "node": ">=4" 1076 | } 1077 | }, 1078 | "node_modules/json-buffer": { 1079 | "version": "3.0.1", 1080 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", 1081 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" 1082 | }, 1083 | "node_modules/json-schema-traverse": { 1084 | "version": "0.3.1", 1085 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", 1086 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", 1087 | "dev": true 1088 | }, 1089 | "node_modules/json-stable-stringify-without-jsonify": { 1090 | "version": "1.0.1", 1091 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 1092 | "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", 1093 | "dev": true 1094 | }, 1095 | "node_modules/keyv": { 1096 | "version": "4.5.3", 1097 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", 1098 | "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", 1099 | "dependencies": { 1100 | "json-buffer": "3.0.1" 1101 | } 1102 | }, 1103 | "node_modules/levn": { 1104 | "version": "0.3.0", 1105 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 1106 | "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", 1107 | "dev": true, 1108 | "dependencies": { 1109 | "prelude-ls": "~1.1.2", 1110 | "type-check": "~0.3.2" 1111 | }, 1112 | "engines": { 1113 | "node": ">= 0.8.0" 1114 | } 1115 | }, 1116 | "node_modules/lodash": { 1117 | "version": "4.17.21", 1118 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 1119 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 1120 | "dev": true 1121 | }, 1122 | "node_modules/lowercase-keys": { 1123 | "version": "2.0.0", 1124 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", 1125 | "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", 1126 | "engines": { 1127 | "node": ">=8" 1128 | } 1129 | }, 1130 | "node_modules/lru-cache": { 1131 | "version": "2.7.3", 1132 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", 1133 | "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", 1134 | "dev": true 1135 | }, 1136 | "node_modules/mimic-fn": { 1137 | "version": "1.2.0", 1138 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", 1139 | "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", 1140 | "dev": true, 1141 | "engines": { 1142 | "node": ">=4" 1143 | } 1144 | }, 1145 | "node_modules/mimic-response": { 1146 | "version": "1.0.1", 1147 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", 1148 | "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", 1149 | "engines": { 1150 | "node": ">=4" 1151 | } 1152 | }, 1153 | "node_modules/minimist": { 1154 | "version": "1.2.8", 1155 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", 1156 | "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", 1157 | "funding": { 1158 | "url": "https://github.com/sponsors/ljharb" 1159 | } 1160 | }, 1161 | "node_modules/mkdirp": { 1162 | "version": "0.5.1", 1163 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 1164 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 1165 | "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", 1166 | "dev": true, 1167 | "dependencies": { 1168 | "minimist": "0.0.8" 1169 | }, 1170 | "bin": { 1171 | "mkdirp": "bin/cmd.js" 1172 | } 1173 | }, 1174 | "node_modules/mkdirp/node_modules/minimist": { 1175 | "version": "0.0.8", 1176 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 1177 | "integrity": "sha512-miQKw5Hv4NS1Psg2517mV4e4dYNaO3++hjAvLOAzKqZ61rH8NS1SK+vbfBWZ5PY/Me/bEWhUwqMghEW5Fb9T7Q==", 1178 | "dev": true 1179 | }, 1180 | "node_modules/ms": { 1181 | "version": "2.1.1", 1182 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 1183 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" 1184 | }, 1185 | "node_modules/mute-stream": { 1186 | "version": "0.0.7", 1187 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", 1188 | "integrity": "sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==", 1189 | "dev": true 1190 | }, 1191 | "node_modules/natural-compare": { 1192 | "version": "1.4.0", 1193 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1194 | "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", 1195 | "dev": true 1196 | }, 1197 | "node_modules/normalize-url": { 1198 | "version": "6.1.0", 1199 | "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", 1200 | "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", 1201 | "engines": { 1202 | "node": ">=10" 1203 | }, 1204 | "funding": { 1205 | "url": "https://github.com/sponsors/sindresorhus" 1206 | } 1207 | }, 1208 | "node_modules/object-inspect": { 1209 | "version": "0.4.0", 1210 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-0.4.0.tgz", 1211 | "integrity": "sha1-9RV8EWwUVbJDsG7pdwM5LFrYn+w=", 1212 | "dev": true 1213 | }, 1214 | "node_modules/once": { 1215 | "version": "1.4.0", 1216 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1217 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1218 | "dependencies": { 1219 | "wrappy": "1" 1220 | } 1221 | }, 1222 | "node_modules/onetime": { 1223 | "version": "2.0.1", 1224 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", 1225 | "integrity": "sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==", 1226 | "dev": true, 1227 | "dependencies": { 1228 | "mimic-fn": "^1.0.0" 1229 | }, 1230 | "engines": { 1231 | "node": ">=4" 1232 | } 1233 | }, 1234 | "node_modules/optionator": { 1235 | "version": "0.8.3", 1236 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", 1237 | "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", 1238 | "dev": true, 1239 | "dependencies": { 1240 | "deep-is": "~0.1.3", 1241 | "fast-levenshtein": "~2.0.6", 1242 | "levn": "~0.3.0", 1243 | "prelude-ls": "~1.1.2", 1244 | "type-check": "~0.3.2", 1245 | "word-wrap": "~1.2.3" 1246 | }, 1247 | "engines": { 1248 | "node": ">= 0.8.0" 1249 | } 1250 | }, 1251 | "node_modules/os-tmpdir": { 1252 | "version": "1.0.2", 1253 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 1254 | "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", 1255 | "dev": true, 1256 | "engines": { 1257 | "node": ">=0.10.0" 1258 | } 1259 | }, 1260 | "node_modules/p-cancelable": { 1261 | "version": "2.1.1", 1262 | "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", 1263 | "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", 1264 | "engines": { 1265 | "node": ">=8" 1266 | } 1267 | }, 1268 | "node_modules/parallel-stream": { 1269 | "version": "1.1.2", 1270 | "resolved": "https://registry.npmjs.org/parallel-stream/-/parallel-stream-1.1.2.tgz", 1271 | "integrity": "sha1-EsGWM455sk5OqIdCmDVMoazcZBs=" 1272 | }, 1273 | "node_modules/path-is-absolute": { 1274 | "version": "1.0.1", 1275 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1276 | "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", 1277 | "dev": true, 1278 | "engines": { 1279 | "node": ">=0.10.0" 1280 | } 1281 | }, 1282 | "node_modules/path-is-inside": { 1283 | "version": "1.0.2", 1284 | "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", 1285 | "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", 1286 | "dev": true 1287 | }, 1288 | "node_modules/pluralize": { 1289 | "version": "7.0.0", 1290 | "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", 1291 | "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", 1292 | "dev": true, 1293 | "engines": { 1294 | "node": ">=4" 1295 | } 1296 | }, 1297 | "node_modules/prelude-ls": { 1298 | "version": "1.1.2", 1299 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 1300 | "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", 1301 | "dev": true, 1302 | "engines": { 1303 | "node": ">= 0.8.0" 1304 | } 1305 | }, 1306 | "node_modules/process-nextick-args": { 1307 | "version": "2.0.0", 1308 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", 1309 | "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", 1310 | "dev": true 1311 | }, 1312 | "node_modules/progress": { 1313 | "version": "2.0.3", 1314 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 1315 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 1316 | "dev": true, 1317 | "engines": { 1318 | "node": ">=0.4.0" 1319 | } 1320 | }, 1321 | "node_modules/pseudomap": { 1322 | "version": "1.0.2", 1323 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 1324 | "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", 1325 | "dev": true 1326 | }, 1327 | "node_modules/pump": { 1328 | "version": "3.0.0", 1329 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 1330 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 1331 | "dependencies": { 1332 | "end-of-stream": "^1.1.0", 1333 | "once": "^1.3.1" 1334 | } 1335 | }, 1336 | "node_modules/quick-lru": { 1337 | "version": "5.1.1", 1338 | "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", 1339 | "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", 1340 | "engines": { 1341 | "node": ">=10" 1342 | }, 1343 | "funding": { 1344 | "url": "https://github.com/sponsors/sindresorhus" 1345 | } 1346 | }, 1347 | "node_modules/readable-stream": { 1348 | "version": "2.3.6", 1349 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", 1350 | "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", 1351 | "dev": true, 1352 | "dependencies": { 1353 | "core-util-is": "~1.0.0", 1354 | "inherits": "~2.0.3", 1355 | "isarray": "~1.0.0", 1356 | "process-nextick-args": "~2.0.0", 1357 | "safe-buffer": "~5.1.1", 1358 | "string_decoder": "~1.1.1", 1359 | "util-deprecate": "~1.0.1" 1360 | } 1361 | }, 1362 | "node_modules/regexpp": { 1363 | "version": "1.1.0", 1364 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", 1365 | "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", 1366 | "dev": true, 1367 | "engines": { 1368 | "node": ">=4.0.0" 1369 | } 1370 | }, 1371 | "node_modules/require-uncached": { 1372 | "version": "1.0.3", 1373 | "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", 1374 | "integrity": "sha512-Xct+41K3twrbBHdxAgMoOS+cNcoqIjfM2/VxBF4LL2hVph7YsF8VSKyQ3BDFZwEVbok9yeDl2le/qo0S77WG2w==", 1375 | "dev": true, 1376 | "dependencies": { 1377 | "caller-path": "^0.1.0", 1378 | "resolve-from": "^1.0.0" 1379 | }, 1380 | "engines": { 1381 | "node": ">=0.10.0" 1382 | } 1383 | }, 1384 | "node_modules/resolve-alpn": { 1385 | "version": "1.2.1", 1386 | "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", 1387 | "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" 1388 | }, 1389 | "node_modules/resolve-from": { 1390 | "version": "1.0.1", 1391 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", 1392 | "integrity": "sha512-kT10v4dhrlLNcnO084hEjvXCI1wUG9qZLoz2RogxqDQQYy7IxjI/iMUkOtQTNEh6rzHxvdQWHsJyel1pKOVCxg==", 1393 | "dev": true, 1394 | "engines": { 1395 | "node": ">=0.10.0" 1396 | } 1397 | }, 1398 | "node_modules/responselike": { 1399 | "version": "2.0.1", 1400 | "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", 1401 | "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", 1402 | "dependencies": { 1403 | "lowercase-keys": "^2.0.0" 1404 | }, 1405 | "funding": { 1406 | "url": "https://github.com/sponsors/sindresorhus" 1407 | } 1408 | }, 1409 | "node_modules/restore-cursor": { 1410 | "version": "2.0.0", 1411 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", 1412 | "integrity": "sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==", 1413 | "dev": true, 1414 | "dependencies": { 1415 | "onetime": "^2.0.0", 1416 | "signal-exit": "^3.0.2" 1417 | }, 1418 | "engines": { 1419 | "node": ">=4" 1420 | } 1421 | }, 1422 | "node_modules/resumer": { 1423 | "version": "0.0.0", 1424 | "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", 1425 | "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", 1426 | "dev": true, 1427 | "dependencies": { 1428 | "through": "~2.3.4" 1429 | } 1430 | }, 1431 | "node_modules/rimraf": { 1432 | "version": "2.6.3", 1433 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 1434 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 1435 | "dev": true, 1436 | "dependencies": { 1437 | "glob": "^7.1.3" 1438 | }, 1439 | "bin": { 1440 | "rimraf": "bin.js" 1441 | } 1442 | }, 1443 | "node_modules/rimraf/node_modules/glob": { 1444 | "version": "7.2.3", 1445 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", 1446 | "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", 1447 | "dev": true, 1448 | "dependencies": { 1449 | "fs.realpath": "^1.0.0", 1450 | "inflight": "^1.0.4", 1451 | "inherits": "2", 1452 | "minimatch": "^3.1.1", 1453 | "once": "^1.3.0", 1454 | "path-is-absolute": "^1.0.0" 1455 | }, 1456 | "engines": { 1457 | "node": "*" 1458 | }, 1459 | "funding": { 1460 | "url": "https://github.com/sponsors/isaacs" 1461 | } 1462 | }, 1463 | "node_modules/rimraf/node_modules/minimatch": { 1464 | "version": "3.1.2", 1465 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", 1466 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", 1467 | "dev": true, 1468 | "dependencies": { 1469 | "brace-expansion": "^1.1.7" 1470 | }, 1471 | "engines": { 1472 | "node": "*" 1473 | } 1474 | }, 1475 | "node_modules/run-async": { 1476 | "version": "2.4.1", 1477 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", 1478 | "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", 1479 | "dev": true, 1480 | "engines": { 1481 | "node": ">=0.12.0" 1482 | } 1483 | }, 1484 | "node_modules/rx-lite": { 1485 | "version": "4.0.8", 1486 | "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", 1487 | "integrity": "sha512-Cun9QucwK6MIrp3mry/Y7hqD1oFqTYLQ4pGxaHTjIdaFDWRGGLikqp6u8LcWJnzpoALg9hap+JGk8sFIUuEGNA==", 1488 | "dev": true 1489 | }, 1490 | "node_modules/rx-lite-aggregates": { 1491 | "version": "4.0.8", 1492 | "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", 1493 | "integrity": "sha512-3xPNZGW93oCjiO7PtKxRK6iOVYBWBvtf9QHDfU23Oc+dLIQmAV//UnyXV/yihv81VS/UqoQPk4NegS8EFi55Hg==", 1494 | "dev": true, 1495 | "dependencies": { 1496 | "rx-lite": "*" 1497 | } 1498 | }, 1499 | "node_modules/safe-buffer": { 1500 | "version": "5.1.2", 1501 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 1502 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 1503 | "dev": true 1504 | }, 1505 | "node_modules/safer-buffer": { 1506 | "version": "2.1.2", 1507 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1508 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 1509 | "dev": true 1510 | }, 1511 | "node_modules/semver": { 1512 | "version": "5.7.1", 1513 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 1514 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 1515 | "dev": true, 1516 | "bin": { 1517 | "semver": "bin/semver" 1518 | } 1519 | }, 1520 | "node_modules/shebang-command": { 1521 | "version": "1.2.0", 1522 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 1523 | "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", 1524 | "dev": true, 1525 | "dependencies": { 1526 | "shebang-regex": "^1.0.0" 1527 | }, 1528 | "engines": { 1529 | "node": ">=0.10.0" 1530 | } 1531 | }, 1532 | "node_modules/shebang-regex": { 1533 | "version": "1.0.0", 1534 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 1535 | "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", 1536 | "dev": true, 1537 | "engines": { 1538 | "node": ">=0.10.0" 1539 | } 1540 | }, 1541 | "node_modules/sigmund": { 1542 | "version": "1.0.1", 1543 | "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", 1544 | "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", 1545 | "dev": true 1546 | }, 1547 | "node_modules/signal-exit": { 1548 | "version": "3.0.7", 1549 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", 1550 | "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", 1551 | "dev": true 1552 | }, 1553 | "node_modules/slice-ansi": { 1554 | "version": "1.0.0", 1555 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", 1556 | "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", 1557 | "dev": true, 1558 | "dependencies": { 1559 | "is-fullwidth-code-point": "^2.0.0" 1560 | }, 1561 | "engines": { 1562 | "node": ">=4" 1563 | } 1564 | }, 1565 | "node_modules/slice-ansi/node_modules/is-fullwidth-code-point": { 1566 | "version": "2.0.0", 1567 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1568 | "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", 1569 | "dev": true, 1570 | "engines": { 1571 | "node": ">=4" 1572 | } 1573 | }, 1574 | "node_modules/split": { 1575 | "version": "1.0.1", 1576 | "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", 1577 | "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", 1578 | "dependencies": { 1579 | "through": "2" 1580 | }, 1581 | "engines": { 1582 | "node": "*" 1583 | } 1584 | }, 1585 | "node_modules/sprintf-js": { 1586 | "version": "1.0.3", 1587 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 1588 | "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", 1589 | "dev": true 1590 | }, 1591 | "node_modules/string_decoder": { 1592 | "version": "1.1.1", 1593 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 1594 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 1595 | "dev": true, 1596 | "dependencies": { 1597 | "safe-buffer": "~5.1.0" 1598 | } 1599 | }, 1600 | "node_modules/strip-ansi": { 1601 | "version": "3.0.1", 1602 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 1603 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 1604 | "dev": true, 1605 | "dependencies": { 1606 | "ansi-regex": "^2.0.0" 1607 | }, 1608 | "engines": { 1609 | "node": ">=0.10.0" 1610 | } 1611 | }, 1612 | "node_modules/strip-json-comments": { 1613 | "version": "2.0.1", 1614 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 1615 | "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", 1616 | "dev": true, 1617 | "engines": { 1618 | "node": ">=0.10.0" 1619 | } 1620 | }, 1621 | "node_modules/supports-color": { 1622 | "version": "5.4.0", 1623 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", 1624 | "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", 1625 | "dev": true, 1626 | "dependencies": { 1627 | "has-flag": "^3.0.0" 1628 | }, 1629 | "engines": { 1630 | "node": ">=4" 1631 | } 1632 | }, 1633 | "node_modules/table": { 1634 | "version": "4.0.2", 1635 | "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", 1636 | "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", 1637 | "dev": true, 1638 | "dependencies": { 1639 | "ajv": "^5.2.3", 1640 | "ajv-keywords": "^2.1.0", 1641 | "chalk": "^2.1.0", 1642 | "lodash": "^4.17.4", 1643 | "slice-ansi": "1.0.0", 1644 | "string-width": "^2.1.1" 1645 | } 1646 | }, 1647 | "node_modules/table/node_modules/ansi-regex": { 1648 | "version": "3.0.1", 1649 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", 1650 | "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", 1651 | "dev": true, 1652 | "engines": { 1653 | "node": ">=4" 1654 | } 1655 | }, 1656 | "node_modules/table/node_modules/is-fullwidth-code-point": { 1657 | "version": "2.0.0", 1658 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1659 | "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", 1660 | "dev": true, 1661 | "engines": { 1662 | "node": ">=4" 1663 | } 1664 | }, 1665 | "node_modules/table/node_modules/string-width": { 1666 | "version": "2.1.1", 1667 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 1668 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 1669 | "dev": true, 1670 | "dependencies": { 1671 | "is-fullwidth-code-point": "^2.0.0", 1672 | "strip-ansi": "^4.0.0" 1673 | }, 1674 | "engines": { 1675 | "node": ">=4" 1676 | } 1677 | }, 1678 | "node_modules/table/node_modules/strip-ansi": { 1679 | "version": "4.0.0", 1680 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 1681 | "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", 1682 | "dev": true, 1683 | "dependencies": { 1684 | "ansi-regex": "^3.0.0" 1685 | }, 1686 | "engines": { 1687 | "node": ">=4" 1688 | } 1689 | }, 1690 | "node_modules/tape": { 1691 | "version": "3.5.0", 1692 | "resolved": "https://registry.npmjs.org/tape/-/tape-3.5.0.tgz", 1693 | "integrity": "sha1-rrsGE4gQStDLQHvoQnggSdZGJPg=", 1694 | "dev": true, 1695 | "dependencies": { 1696 | "deep-equal": "~0.2.0", 1697 | "defined": "~0.0.0", 1698 | "glob": "~3.2.9", 1699 | "inherits": "~2.0.1", 1700 | "object-inspect": "~0.4.0", 1701 | "resumer": "~0.0.0", 1702 | "through": "~2.3.4" 1703 | }, 1704 | "bin": { 1705 | "tape": "bin/tape" 1706 | } 1707 | }, 1708 | "node_modules/tape/node_modules/defined": { 1709 | "version": "0.0.0", 1710 | "resolved": "https://registry.npmjs.org/defined/-/defined-0.0.0.tgz", 1711 | "integrity": "sha1-817qfXBekzuvE7LwOz+D2SFAOz4=", 1712 | "dev": true 1713 | }, 1714 | "node_modules/tape/node_modules/glob": { 1715 | "version": "3.2.11", 1716 | "resolved": "https://registry.npmjs.org/glob/-/glob-3.2.11.tgz", 1717 | "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", 1718 | "dev": true, 1719 | "dependencies": { 1720 | "inherits": "2", 1721 | "minimatch": "0.3" 1722 | }, 1723 | "engines": { 1724 | "node": "*" 1725 | } 1726 | }, 1727 | "node_modules/tape/node_modules/minimatch": { 1728 | "version": "0.3.0", 1729 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.3.0.tgz", 1730 | "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", 1731 | "deprecated": "Please update to minimatch 3.0.2 or higher to avoid a RegExp DoS issue", 1732 | "dev": true, 1733 | "dependencies": { 1734 | "lru-cache": "2", 1735 | "sigmund": "~1.0.0" 1736 | }, 1737 | "engines": { 1738 | "node": "*" 1739 | } 1740 | }, 1741 | "node_modules/text-table": { 1742 | "version": "0.2.0", 1743 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 1744 | "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", 1745 | "dev": true 1746 | }, 1747 | "node_modules/through": { 1748 | "version": "2.3.8", 1749 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 1750 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" 1751 | }, 1752 | "node_modules/tmp": { 1753 | "version": "0.0.33", 1754 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 1755 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 1756 | "dev": true, 1757 | "dependencies": { 1758 | "os-tmpdir": "~1.0.2" 1759 | }, 1760 | "engines": { 1761 | "node": ">=0.6.0" 1762 | } 1763 | }, 1764 | "node_modules/type-check": { 1765 | "version": "0.3.2", 1766 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 1767 | "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", 1768 | "dev": true, 1769 | "dependencies": { 1770 | "prelude-ls": "~1.1.2" 1771 | }, 1772 | "engines": { 1773 | "node": ">= 0.8.0" 1774 | } 1775 | }, 1776 | "node_modules/typedarray": { 1777 | "version": "0.0.6", 1778 | "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", 1779 | "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", 1780 | "dev": true 1781 | }, 1782 | "node_modules/util-deprecate": { 1783 | "version": "1.0.2", 1784 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 1785 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", 1786 | "dev": true 1787 | }, 1788 | "node_modules/which": { 1789 | "version": "1.3.1", 1790 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 1791 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 1792 | "dev": true, 1793 | "dependencies": { 1794 | "isexe": "^2.0.0" 1795 | }, 1796 | "bin": { 1797 | "which": "bin/which" 1798 | } 1799 | }, 1800 | "node_modules/word-wrap": { 1801 | "version": "1.2.3", 1802 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 1803 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 1804 | "dev": true, 1805 | "engines": { 1806 | "node": ">=0.10.0" 1807 | } 1808 | }, 1809 | "node_modules/wrappy": { 1810 | "version": "1.0.2", 1811 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 1812 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 1813 | }, 1814 | "node_modules/write": { 1815 | "version": "0.2.1", 1816 | "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", 1817 | "integrity": "sha512-CJ17OoULEKXpA5pef3qLj5AxTJ6mSt7g84he2WIskKwqFO4T97d5V7Tadl0DYDk7qyUOQD5WlUlOMChaYrhxeA==", 1818 | "dev": true, 1819 | "dependencies": { 1820 | "mkdirp": "^0.5.1" 1821 | }, 1822 | "engines": { 1823 | "node": ">=0.10.0" 1824 | } 1825 | }, 1826 | "node_modules/yallist": { 1827 | "version": "2.1.2", 1828 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 1829 | "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", 1830 | "dev": true 1831 | } 1832 | } 1833 | } 1834 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "bin": { 3 | "sample": "./bin/sample", 4 | "pathreplay": "./bin/pathreplay", 5 | "generatepath": "./bin/generatepath" 6 | }, 7 | "engines": { 8 | "node": ">=18" 9 | }, 10 | "name": "@mapbox/aws-log-replay", 11 | "license": "BSD-2-Clause", 12 | "author": "Mapbox", 13 | "version": "4.1.0", 14 | "dependencies": { 15 | "agentkeepalive": "^3.5.1", 16 | "got": "^11.8.6", 17 | "minimist": "^1.2.8", 18 | "parallel-stream": "^1.1.2", 19 | "split": "^1.0.1" 20 | }, 21 | "scripts": { 22 | "test": "tape test/*.test.js", 23 | "pretest": "eslint test bin index.js" 24 | }, 25 | "devDependencies": { 26 | "eslint": "^4.19.1", 27 | "tape": "3.5.x" 28 | }, 29 | "main": "index.js", 30 | "readmeFilename": "README.md", 31 | "description": "Transform and replay CloudFront, ELB Classic, and ALB logs." 32 | } 33 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # aws-log-replay 2 | 3 | ``` 4 | npm i @mapbox/aws-log-replay 5 | ``` 6 | 7 | Transform and replay a stream of AWS CloudFront, ELB Classic, or ALB logs. You can use [s3scan](https://github.com/mapbox/s3scan) to easily stream logs into these tools. 8 | 9 | This project uses the AWS JavaScript SDK: you will need to [configure your own credentials](http://docs.aws.amazon.com/AWSJavaScriptSDK/guide/node-configuring.html). 10 | 11 | ## generatepath 12 | 13 | Takes different types of logs as input and streams an object to `stdout`. Format of the output: 14 | ```js 15 | { 16 | "path": "/a.json?option=1", 17 | "method": "GET", // can be GET or HEAD 18 | "referer": "Referer" // for 'cloudfront' type only 19 | } 20 | ``` 21 | Supported types include "cloudfront" for CloudFront logs and "lb" for ELB Classic or ALB logs. 22 | 23 | ```sh 24 | Usage: generatepath 25 | ``` 26 | 27 | ## pathreplay 28 | 29 | Makes replay requests to the `baseurl`. Expects paths to be piped to `stdin`. (Optional) Control concurrency of replay requests with `--concurrency` flag. Default is 100. 30 | 31 | ```sh 32 | Usage: pathreplay [--concurrency=] 33 | ``` 34 | 35 | ## sample 36 | 37 | Emits a repeatable set of input lines piped to `stdin` at a given sampling rate. The number of lines emitted will approach the specific rate over sufficiently large samples, but may diverge for small sample sizes. Sampling rates should be specified as a decimal number between zero and one. Optionally accepts a `filter` argument that restricts the sampled set to lines matching the specified regular expression. 38 | 39 | ```sh 40 | Usage: sample --rate= [--filter=] 41 | ``` 42 | -------------------------------------------------------------------------------- /test/GeneratePath.test.js: -------------------------------------------------------------------------------- 1 | var reader = require('../index.js'); 2 | var tape = require('tape'); 3 | 4 | tape('GeneratePath [cloudfront]', function(assert) { 5 | var data = []; 6 | var generatePath = reader.GeneratePath('cloudfront'); 7 | generatePath.on('data', function(d) { 8 | data.push(d); 9 | }); 10 | generatePath.on('end', function() { 11 | assert.deepEqual(data[0], { method: 'GET', path: '/a.json?option=1' }); 12 | assert.deepEqual(data[1], { method: 'GET', path: '/geocoding/v5/mapbox.places/2401%20Gw%20Loy%20Rd%20New%20Market%2C%20Tn%2037820.json?access_token=pk.abc.123' }); 13 | assert.equal(data.length, 2); 14 | assert.end(); 15 | }); 16 | generatePath.write('2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /a.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314\n'); 17 | generatePath.write('2016-04-14 02:40:16 DFW50 1771 108.223.176.206 GET d3eju24r2ptc5d.cloudfront.net /geocoding/v5/mapbox.places/2401%2520Gw%2520Loy%2520Rd%2520New%2520Market%252C%2520Tn%252037820.json 200 - Mozilla/5.0%2520(iPhone;%2520CPU%2520iPhone%2520OS%25209_2%2520like%2520Mac%2520OS%2520X)%2520AppleWebKit/601.1.46%2520(KHTML,%2520like%2520Gecko)%2520Mobile/13C75 access_token=pk.abc.123 - Miss TbuZW6a2aUgeR9kBenr30jytUpJW5tSuv20Xv3n-smuTCqSdBjGpZQ== a.tiles.mapbox.com http 451 1.954 - - - Miss\n'); 18 | generatePath.write('\n'); 19 | generatePath.end(); 20 | }); 21 | 22 | tape('GeneratePath with referer [cloudfront]', function(assert) { 23 | var data = []; 24 | var keepReferer = true; 25 | var generatePath = reader.GeneratePath('cloudfront', keepReferer); 26 | generatePath.on('data', function(d) { 27 | data.push(d); 28 | }); 29 | generatePath.on('end', function() { 30 | assert.deepEqual(data[0], { method: 'GET', path: '/a.json?option=1', referer: 'https://www.mapbox.com/' }); 31 | assert.deepEqual(data[1], { method: 'GET', path: '/geocoding/v5/mapbox.places/2401%20Gw%20Loy%20Rd%20New%20Market%2C%20Tn%2037820.json?access_token=pk.abc.123' }); 32 | assert.equal(data.length, 2); 33 | assert.end(); 34 | }); 35 | generatePath.write('2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /a.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314\n'); 36 | generatePath.write('2016-04-14 02:40:16 DFW50 1771 108.223.176.206 GET d3eju24r2ptc5d.cloudfront.net /geocoding/v5/mapbox.places/2401%2520Gw%2520Loy%2520Rd%2520New%2520Market%252C%2520Tn%252037820.json 200 - Mozilla/5.0%2520(iPhone;%2520CPU%2520iPhone%2520OS%25209_2%2520like%2520Mac%2520OS%2520X)%2520AppleWebKit/601.1.46%2520(KHTML,%2520like%2520Gecko)%2520Mobile/13C75 access_token=pk.abc.123 - Miss TbuZW6a2aUgeR9kBenr30jytUpJW5tSuv20Xv3n-smuTCqSdBjGpZQ== a.tiles.mapbox.com http 451 1.954 - - - Miss\n'); 37 | generatePath.write('\n'); 38 | generatePath.end(); 39 | }); 40 | 41 | tape('GeneratePath [elb]', function(assert) { 42 | var data = []; 43 | var generatePath = reader.GeneratePath('lb'); 44 | generatePath.on('data', function(d) { 45 | data.push(d); 46 | }); 47 | generatePath.on('end', function() { 48 | assert.deepEqual(data[0], { method: 'GET', path: '/a.json?option=1' }); 49 | assert.deepEqual(data[1], { method: 'GET', path: '/b.json?option=1&other=2' }); 50 | assert.deepEqual(data[2], { method: 'HEAD', path: '/ham/sam?iam' }); 51 | assert.deepEqual(data[3], { method: 'GET', path: '/v1/thing/my.id?time=2017-05-31T22:05:32.562Z' }); 52 | assert.equal(data.length, 4); 53 | assert.end(); 54 | }); 55 | generatePath.write('2016-02-01T19:04:59.488164Z eggs-VPC 000.000.000.00:00000 00.0.00.00:00 0.000024 0.006806 0.00002 304 304 0 0 "GET http://green-eggs.com:80/a.json?option=1 HTTP/1.1" "Amazon CloudFront" - -'); 56 | generatePath.write('2016-02-01T19:04:59.488164Z eggs-VPC 000.000.000.00:00000 00.0.00.00:00 0.000024 0.006806 0.00002 200 200 0 0 "GET http://green-eggs.com:666/b.json?option=1&other=2 HTTP/1.1" "Amazon CloudFront" - -'); 57 | generatePath.write('us-east-1.elb.amazonaws.com:666/ HTTP/1.1" "Amazon Route 53 Health Check Service; ref:000-000-0000; report http://green.eggs" ABCD-EFGH TLSv1.2'); 58 | generatePath.write('https 2016-09-25T07:15:01.253924Z app/api-green-eggs/1234 00.000.000.00:00000 00.0.0.000:00000 0.000 0.000 0.000 000 000 0000 000 "POST https://green.eggs.com:000/ham/sam?iam HTTP/1.1" "(null)/0.0.0/000 greeneggsandham/0.0" ABCDE-ABC-ABC000-ABC TLSv1 greeneggsandhamsamiam'); 59 | generatePath.write('https 2016-09-25T07:15:01.253924Z app/api-green-eggs/1234 00.000.000.00:00000 00.0.0.000:00000 0.000 0.000 0.000 000 000 0000 000 "HEAD https://green.eggs.com:000/ham/sam?iam HTTP/1.1" "(null)/0.0.0/000 greeneggsandham/0.0" ABCDE-ABC-ABC000-ABC TLSv1 greeneggsandhamsamiam'); 60 | generatePath.write('2016-02-01T19:04:59.488164Z eggs-VPC 000.000.000.00:00000 00.0.00.00:00 0.000024 0.006806 0.00002 304 304 0 0 "GET http://api.example.com:80/v1/thing/my.id?time=2017-05-31T22:05:32.562Z HTTP/1.1" "Amazon CloudFront" - -'); 61 | generatePath.write('\n'); 62 | generatePath.end(); 63 | }); 64 | -------------------------------------------------------------------------------- /test/RequestStream.test.js: -------------------------------------------------------------------------------- 1 | var reader = require('../index.js'); 2 | var tape = require('tape'); 3 | var http = require('http'); 4 | var server; 5 | var count = 0; 6 | 7 | tape('setup', function(assert) { 8 | server = http.createServer(function(req, res) { 9 | count++; 10 | if (/\/c\.json/.test(req.url)) { 11 | res.writeHead(404); 12 | } else { 13 | res.writeHead(200); 14 | res.write(JSON.stringify({ obj: req.url.split('/')[1].split('.')[0] })); 15 | } 16 | setTimeout(function() { 17 | res.end(); 18 | }, 1000); 19 | }); 20 | server.reset = function() { count = 0; }; 21 | server.listen(9999, assert.end); 22 | }); 23 | 24 | tape('RequestStream [concurrency]', function(assert) { 25 | var reqstream = reader.RequestStream({ 26 | baseurl: 'http://localhost:9999', 27 | hwm: 3 28 | }); 29 | reqstream.on('data', function() { 30 | }); 31 | reqstream.on('end', function() { 32 | assert.end(); 33 | }); 34 | var req = 0; 35 | var j = setInterval(function() { 36 | req = req + 3; 37 | assert.equal(req, count); 38 | }, 1000); 39 | for (var i = 0; i < 10; i++) { 40 | reqstream.write({ path: '/a.json?option=1\n' }); 41 | } 42 | setTimeout(function() { 43 | clearInterval(j); 44 | reqstream.end(); 45 | }, 3500); 46 | }); 47 | 48 | tape('RequestStream', function(assert) { 49 | var data = []; 50 | var reqstream = reader.RequestStream({ 51 | baseurl: 'http://localhost:9999' 52 | }); 53 | reqstream.on('data', function(d) { 54 | switch (d.statusCode) { 55 | case 200: 56 | assert.deepEqual(/http:\/\/localhost:9999\/(a|b)\.json/.test(d.url), true, 'data.url is object url'); 57 | data.push(JSON.parse(d.body)); 58 | break; 59 | case 404: 60 | assert.deepEqual(/http:\/\/localhost:9999\/c\.json/.test(d.url), true, 'data.url is object url'); 61 | break; 62 | default: 63 | assert.fail('Invalid statusCode ' + d.statusCode); 64 | return; 65 | } 66 | 67 | assert.deepEqual(Buffer.isBuffer(d.body), true, 'data.body is buffer'); 68 | assert.deepEqual(!isNaN(d.elapsedTime), true, 'data.elapsedTime is a number'); 69 | }); 70 | reqstream.on('end', function() { 71 | assert.deepEqual(data.length, 2, 'emits 2 objects'); 72 | assert.deepEqual(data.map(function(d) { return d.obj; }).sort(), ['a', 'b'], 'emits objects a, b'); 73 | assert.end(); 74 | }); 75 | reqstream.write({ path: '/a.json?option=1\n' }); 76 | reqstream.write({ path: '/b.json?option=2\n' }); 77 | reqstream.write({ path: '/c.json?option=2\n' }); 78 | reqstream.write({ path: '\n' }); 79 | reqstream.end(); 80 | }); 81 | 82 | tape('RequestStream whitespace utf8 characters', function(assert) { 83 | server.reset(); 84 | var logs = []; 85 | var reqstream = reader.RequestStream({ 86 | baseurl: 'http://localhost:9999', 87 | hwm: 3 88 | }); 89 | reqstream.on('data', function(d) { 90 | logs.push(d.url); 91 | }); 92 | reqstream.on('end', function() { 93 | assert.equal(count, 21); 94 | assert.deepEqual(logs, [ 95 | 'http://localhost:9999/a.json?q=12:30%20PM', 96 | 'http://localhost:9999/a.json?q=12:30%20PM', 97 | 'http://localhost:9999/a.json?q=12:30%C2%A0PM', 98 | 'http://localhost:9999/a.json?q=12:30%E2%80%AFPM', 99 | 'http://localhost:9999/a.json?q=12:30%E2%80%AFPM', 100 | 'http://localhost:9999/a.json?q=12:30%E1%9A%80PM', 101 | 'http://localhost:9999/a.json?q=12:30%E1%A0%8EPM', 102 | 'http://localhost:9999/a.json?q=12:30%E2%80%80PM', 103 | 'http://localhost:9999/a.json?q=12:30%E2%80%81PM', 104 | 'http://localhost:9999/a.json?q=12:30%E2%80%82PM', 105 | 'http://localhost:9999/a.json?q=12:30%E2%80%83PM', 106 | 'http://localhost:9999/a.json?q=12:30%E2%80%84PM', 107 | 'http://localhost:9999/a.json?q=12:30%E2%80%85PM', 108 | 'http://localhost:9999/a.json?q=12:30%E2%80%86PM', 109 | 'http://localhost:9999/a.json?q=12:30%E2%80%87PM', 110 | 'http://localhost:9999/a.json?q=12:30%E2%80%88PM', 111 | 'http://localhost:9999/a.json?q=12:30%E2%80%89PM', 112 | 'http://localhost:9999/a.json?q=12:30%E2%80%8APM', 113 | 'http://localhost:9999/a.json?q=12:30%E2%80%8BPM', 114 | 'http://localhost:9999/a.json?q=12:30%E2%81%9FPM', 115 | 'http://localhost:9999/a.json?q=12:30%EF%BB%BFPM' 116 | ]); 117 | assert.end(); 118 | }); 119 | 120 | // https://jkorpela.fi/chars/spaces.html 121 | reqstream.write({ path: '/a.json?q=12:30 PM\n' }); // space (visual) 122 | reqstream.write({ path: '/a.json?q=12:30\u0020PM\n' }); // space (utf8) 123 | reqstream.write({ path: '/a.json?q=12:30\u00A0PM\n' }); // no-break space 124 | reqstream.write({ path: '/a.json?q=12:30 PM\n' }); // narrow no-break space (visual) 125 | reqstream.write({ path: '/a.json?q=12:30\u202FPM\n' }); // narrow no-break space (utf8) 126 | reqstream.write({ path: '/a.json?q=12:30\u1680PM\n' }); // ogham space mark 127 | reqstream.write({ path: '/a.json?q=12:30\u180EPM\n' }); // mongolian vowel separator 128 | reqstream.write({ path: '/a.json?q=12:30\u2000PM\n' }); // en quad 129 | reqstream.write({ path: '/a.json?q=12:30\u2001PM\n' }); // em quad 130 | reqstream.write({ path: '/a.json?q=12:30\u2002PM\n' }); // en space 131 | reqstream.write({ path: '/a.json?q=12:30\u2003PM\n' }); // em space 132 | reqstream.write({ path: '/a.json?q=12:30\u2004PM\n' }); // three-per-em space 133 | reqstream.write({ path: '/a.json?q=12:30\u2005PM\n' }); // four-per-em space 134 | reqstream.write({ path: '/a.json?q=12:30\u2006PM\n' }); // six-per-em space 135 | reqstream.write({ path: '/a.json?q=12:30\u2007PM\n' }); // figure space 136 | reqstream.write({ path: '/a.json?q=12:30\u2008PM\n' }); // punctuation space 137 | reqstream.write({ path: '/a.json?q=12:30\u2009PM\n' }); // thin space 138 | reqstream.write({ path: '/a.json?q=12:30\u200APM\n' }); // hair space 139 | reqstream.write({ path: '/a.json?q=12:30\u200BPM\n' }); // zero width space 140 | reqstream.write({ path: '/a.json?q=12:30\u205FPM\n' }); // medium mathematical space 141 | reqstream.write({ path: '/a.json?q=12:30\uFEFFPM\n' }); // zero width no-break space 142 | reqstream.end(); 143 | }); 144 | 145 | tape('RequestStream close', function(assert) { 146 | server.reset(); 147 | var reqstream = reader.RequestStream({ 148 | baseurl: 'http://localhost:8888' // all requests ought to fail 149 | }); 150 | 151 | reqstream.on('error', function(err) { assert.ifError(err, 'should not fail'); }); 152 | reqstream.on('finish', function() { 153 | assert.equal(count, 0, 'no requests were made'); 154 | assert.end(); 155 | }); 156 | 157 | reqstream.close(); 158 | assert.ok(reqstream._closed, 'marked stream as closed'); 159 | reqstream.write({ path: '/a.json?option=1\n' }); 160 | reqstream.write({ path: '/b.json?option=2\n' }); 161 | reqstream.write({ path: '/c.json?option=2\n' }); 162 | reqstream.write({ path: '\n' }); 163 | reqstream.end(); 164 | }); 165 | 166 | tape('teardown', function(assert) { 167 | server.close(assert.end); 168 | }); 169 | -------------------------------------------------------------------------------- /test/SampleStream.test.js: -------------------------------------------------------------------------------- 1 | var reader = require('..'); 2 | var tape = require('tape'); 3 | var fs = require('fs'); 4 | var split = require('split'); 5 | var path = require('path'); 6 | 7 | function testFunc(r, f, expected, t) { 8 | var sample = reader.SampleStream({ rate: (r * 0.1), filter: f }); 9 | 10 | var splitStream = split(); 11 | splitStream.pipe(sample); 12 | 13 | var count = 0; 14 | sample.on('data', function() { 15 | count++; 16 | }); 17 | sample.on('finish', function() { 18 | t.equals(count, expected, 'got expected records (' + expected + ')'); 19 | t.end(); 20 | }); 21 | 22 | for (var k = 0; k < 1000; k++) { 23 | // each of these is 9 records long 24 | splitStream.write(fs.readFileSync(path.join(__dirname + '/fixtures/AAAAAAAAAAAAAA.2015-10-19-17.e5b6526a'), 'utf8')); 25 | } 26 | splitStream.end(); 27 | } 28 | 29 | var expectedUnfiltered = [949, 1879, 2820, 3728, 4592, 5449, 6323, 7220, 8136]; 30 | for (var rate = 1; rate < 10; rate++) { 31 | tape('unfiltered, sample rate ' + (rate * 0.1).toFixed(1), testFunc.bind(null, rate, false, expectedUnfiltered[rate - 1])); 32 | } 33 | 34 | var expectedFiltered = [299, 607, 904, 1218, 1509, 1788, 2085, 2384, 2716]; 35 | for (rate = 1; rate < 10; rate++) { 36 | tape('filtered, sample rate ' + (rate * 0.1).toFixed(1), testFunc.bind(null, rate, 'a.json', expectedFiltered[rate - 1])); 37 | } 38 | -------------------------------------------------------------------------------- /test/bin.test.js: -------------------------------------------------------------------------------- 1 | var exec = require('child_process').exec; 2 | var spawn = require('child_process').spawn; 3 | var tape = require('tape'); 4 | var http = require('http'); 5 | var server; 6 | 7 | tape('setup', function(assert) { 8 | server = http.createServer(function(req, res) { 9 | if (/\/c\.json/.test(req.url)) { 10 | res.writeHead(404); 11 | } else { 12 | res.writeHead(200); 13 | res.write(JSON.stringify({ obj: req.url.split('/')[1].split('.')[0] })); 14 | } 15 | res.end(); 16 | }); 17 | server.listen(9999, assert.end); 18 | }); 19 | 20 | tape('pathreplay: usage', function(assert) { 21 | exec(__dirname + '/../bin/pathreplay', { env: process.env }, function(err, stdout, stderr) { 22 | assert.equal(err.code, 1, 'exits 1'); 23 | assert.equal(stderr, 'Usage: pathreplay [--concurrency=]\n', 'shows usage'); 24 | assert.end(); 25 | }); 26 | }); 27 | 28 | tape('pathreplay', function(assert) { 29 | var child = spawn(__dirname + '/../bin/pathreplay', ['http://localhost:9999']); 30 | var data = []; 31 | child.stdout.on('data', function(d) { 32 | if (d.toString() != '\n') { 33 | data.push(d.toString()); 34 | } 35 | }); 36 | child.stderr.on('data', function(data) { 37 | assert.ifError(data); 38 | }); 39 | child.on('close', function(code) { 40 | assert.deepEqual(data.sort(), ['{"obj":"a"}\n', '{"obj":"b"}\n'], 'emits obj a, b'); 41 | assert.equal(code, 0, 'exits 0'); 42 | assert.end(); 43 | }); 44 | child.stdin.write(`${JSON.stringify({ path: '/a.json\n' })}\n`); 45 | child.stdin.write(`${JSON.stringify({ path: '/b.json\n' })}\n`); 46 | child.stdin.write(`${JSON.stringify({ path: '/c.json\n' })}`); 47 | child.stdin.end(); 48 | }); 49 | 50 | tape('pathreplay [bad args]', function(assert) { 51 | var child = spawn(__dirname + '/../bin/pathreplay', ['foobar', 'http://localhost:9999']); 52 | child.stderr.on('data', function(data) { 53 | assert.equal(data.toString(), 'Usage: pathreplay [--concurrency=]\n', 'Usage when args out of order'); 54 | assert.end(); 55 | }); 56 | }); 57 | 58 | tape('pathreplay [concurrency arg]', function(assert) { 59 | var child = spawn(__dirname + '/../bin/pathreplay', ['http://localhost:9999', '--concurrency=5']); 60 | var data = []; 61 | child.stdout.on('data', function(d) { 62 | data.push(d.toString()); 63 | }); 64 | child.stderr.on('data', function(data) { 65 | assert.ifError(data); 66 | }); 67 | child.on('close', function(code) { 68 | assert.deepEqual(data, ['{"obj":"a"}\n'], 'emits obj a'); 69 | assert.equal(code, 0, 'exits 0'); 70 | assert.end(); 71 | }); 72 | child.stdin.write(JSON.stringify({ path: '/a.json\n' })); 73 | child.stdin.end(); 74 | }); 75 | 76 | tape('teardown', function(assert) { 77 | server.close(assert.end); 78 | }); 79 | 80 | tape('generatepath: usage', function(assert) { 81 | exec(__dirname + '/../bin/generatepath', { env: process.env }, function(err, stdout, stderr) { 82 | assert.equal(err.code, 1, 'exits 1'); 83 | assert.equal(stderr, 'Usage: generatepath \n can be "cloudfront" or "lb"\n', 'shows usage'); 84 | assert.end(); 85 | }); 86 | }); 87 | 88 | tape('generatepath [cloudfront]', function(assert) { 89 | var child = spawn(__dirname + '/../bin/generatepath', ['cloudfront']); 90 | var data = []; 91 | child.stdout.on('data', function(d) { 92 | data.push(d.toString()); 93 | }); 94 | child.stderr.on('data', function(data) { 95 | assert.ifError(data); 96 | }); 97 | child.on('close', function(code) { 98 | assert.equal(data[0], '{ path: \'/a.json?option=1\', method: \'GET\' }\n'); 99 | assert.equal(data[1], '{ path: \'/b.json?option=2\', method: \'GET\' }\n'); 100 | assert.equal(data[2], '{ path: \'/c.json?option=2\', method: \'GET\' }\n'); 101 | assert.equal(code, 0, 'exits 0'); 102 | assert.end(); 103 | }); 104 | child.stdin.write('2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /a.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314\n'); 105 | child.stdin.write('2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /b.json 200 https://www.mapbox.com/ FakeAgent option=2 - Miss FAKE== example.com http 784 0.314\n'); 106 | child.stdin.write('2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /c.json 200 https://www.mapbox.com/ FakeAgent option=2 - Miss FAKE== example.com http 784 0.314\n'); 107 | child.stdin.write('\n'); 108 | child.stdin.end(); 109 | }); 110 | 111 | tape('generatepath [lb]', function(assert) { 112 | var child = spawn(__dirname + '/../bin/generatepath', ['lb']); 113 | var data = []; 114 | child.stdout.on('data', function(d) { 115 | data.push(d.toString()); 116 | }); 117 | child.stderr.on('data', function(data) { 118 | assert.ifError(data); 119 | }); 120 | child.on('close', function(code) { 121 | assert.equal(data[0], '{ path: \'/a.json?option=1\', method: \'GET\' }\n'); 122 | assert.equal(data[1], '{ path: \'/b.json?option=2\', method: \'HEAD\' }\n'); 123 | assert.equal(code, 0, 'exits 0'); 124 | assert.end(); 125 | }); 126 | child.stdin.write('2016-02-01T19:04:59.488164Z eggs-VPC 000.000.000.00:00000 00.0.00.00:00 0.000024 0.006806 0.00002 304 304 0 0 "GET http://green-eggs.com:80/a.json?option=1 HTTP/1.1" "Amazon CloudFront" - -\n'); 127 | child.stdin.write('2016-02-01T19:04:59.488164Z eggs-VPC 000.000.000.00:00000 00.0.00.00:00 0.000024 0.006806 0.00002 200 200 0 0 "HEAD http://green-eggs.com:80/b.json?option=2 HTTP/1.1" "Amazon CloudFront" - -\n'); 128 | child.stdin.write('\n'); 129 | child.stdin.end(); 130 | }); 131 | -------------------------------------------------------------------------------- /test/fixtures/AAAAAAAAAAAAAA.2015-10-19-17.e5b6526a: -------------------------------------------------------------------------------- 1 | 2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /a.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314 2 | 2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /b.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314 3 | 2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /c.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314 4 | 2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /a.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314 5 | 2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /b.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314 6 | 2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /c.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314 7 | 2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /a.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314 8 | 2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /b.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314 9 | 2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /c.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314 10 | 11 | -------------------------------------------------------------------------------- /test/fixtures/AAAAAAAAAAAAAA.2015-10-19-17.e5b6526a.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/aws-log-replay/251838b42e307be65aa40f110012b69529798645/test/fixtures/AAAAAAAAAAAAAA.2015-10-19-17.e5b6526a.gz -------------------------------------------------------------------------------- /test/fixtures/AAAAAAAAAAAAAA.2015-10-19-17.e5b6526b.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/aws-log-replay/251838b42e307be65aa40f110012b69529798645/test/fixtures/AAAAAAAAAAAAAA.2015-10-19-17.e5b6526b.gz -------------------------------------------------------------------------------- /test/fixtures/AAAAAAAAAAAAAA.2015-10-19-17.e5b6526c.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mapbox/aws-log-replay/251838b42e307be65aa40f110012b69529798645/test/fixtures/AAAAAAAAAAAAAA.2015-10-19-17.e5b6526c.gz -------------------------------------------------------------------------------- /test/fixtures/getObjectResponse.txt: -------------------------------------------------------------------------------- 1 | 2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /a.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314 2 | 2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /b.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314 3 | 2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /c.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314 4 | 2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /a.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314 5 | 2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /b.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314 6 | 2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /c.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314 7 | 2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /a.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314 8 | 2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /b.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314 9 | 2014-09-05 12:48:00 IAD53 33125 54.236.254.12 GET d3eju24r2ptc5d.cloudfront.net /c.json 200 https://www.mapbox.com/ FakeAgent option=1 - Miss FAKE== example.com http 784 0.314 --------------------------------------------------------------------------------