├── .editorconfig ├── .eslintrc ├── .gitattributes ├── .gitignore ├── .jshintrc ├── .travis.yml ├── README.md ├── appveyor.yml ├── common └── bufferdemo.png ├── index.js ├── lib ├── cache-entry.js └── metric.js ├── package.json ├── test.js └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | end_of_line = lf 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | trim_trailing_whitespace = false 13 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | env: 2 | node: true 3 | mocha: true 4 | rules: 5 | eqeqeq: 2 6 | block-scoped-var: 2 7 | quotes: 8 | - 2 9 | - single 10 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | coverage 2 | node_modules 3 | .DS_Store 4 | common/bufferdemo_fromcache.png 5 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "console", 4 | "it", 5 | "describe", 6 | "beforeEach", 7 | "afterEach", 8 | "before", 9 | "after", 10 | "-Promise" 11 | ], 12 | "expr": true, 13 | "proto": true, 14 | "strict": true, 15 | "indent": 2, 16 | "camelcase": true, 17 | "node": true, 18 | "browser": false, 19 | "boss": true, 20 | "curly": true, 21 | "latedef": "nofunc", 22 | "debug": false, 23 | "devel": false, 24 | "eqeqeq": true, 25 | "evil": true, 26 | "forin": false, 27 | "immed": false, 28 | "laxbreak": false, 29 | "newcap": true, 30 | "noarg": true, 31 | "noempty": false, 32 | "quotmark": true, 33 | "nonew": false, 34 | "nomen": false, 35 | "onevar": false, 36 | "plusplus": false, 37 | "regexp": false, 38 | "undef": true, 39 | "unused": true, 40 | "sub": true, 41 | "trailing": true, 42 | "white": false, 43 | "eqnull": true, 44 | "esnext": true 45 | } 46 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '8' 4 | - '10' 5 | - '12' 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # async-disk-cache [![Build status](https://ci.appveyor.com/api/projects/status/lfliompah66m611x?svg=true)](https://ci.appveyor.com/project/embercli/async-disk-cache) [![Build Status](https://travis-ci.org/stefanpenner/async-disk-cache.svg)](https://travis-ci.org/stefanpenner/async-disk-cache) 2 | 3 | An async disk cache. inspired by [jgable/cache-swap](https://github.com/jgable/cache-swap) 4 | 5 | A sync sibling version is also available: [stefanpenner/sync-disk-cache](https://github.com/stefanpenner/sync-disk-cache/) 6 | 7 | By default, this will usge `TMPDIR//` for storage, but this can be changed by setting the `$TMPDIR` environment variable. 8 | 9 | ## Example 10 | 11 | ```js 12 | var Cache = require('async-disk-cache'); 13 | var cache = new Cache('my-cache'); 14 | // 'my-cache' also serves as the global key for the cache. 15 | // if you have multiple programs with this same `cache-key` they will share the 16 | // same backing store. This by design. 17 | 18 | // checking 19 | cache.has('foo').then(function(wasFooFound) { 20 | 21 | }); 22 | 23 | // retrieving (cache hit) 24 | cache.get('foo').then(function(cacheEntry) { 25 | cacheEntry === { 26 | isCached: true, 27 | key: 'foo', 28 | value: 'content of foo' 29 | } 30 | }); 31 | 32 | // retrieving (cache miss) 33 | cache.get('foo').then(function(cacheEntry) { 34 | cacheEntry === { 35 | isCached: false, 36 | key: 'foo', 37 | value: undefined 38 | } 39 | }); 40 | 41 | // setting 42 | cache.set('foo', 'content of foo').then(function() { 43 | // foo was set 44 | }); 45 | 46 | // clearing one entry from the cache 47 | cache.remove('foo').then(function() { 48 | // foo was removed 49 | }) 50 | 51 | // clearing the whole cache 52 | cache.clear().then(function() { 53 | // cache was cleared 54 | }) 55 | ``` 56 | 57 | Enable compression: 58 | 59 | ```js 60 | var Cache = require('async-disk-cache'); 61 | var cache = new Cache('my-cache', { 62 | compression: 'gzip' | 'deflate' | 'deflateRaw', // basically just what nodes zlib's ships with 63 | supportBuffer: 'true' | 'false' // add support for file caching (default `false`) 64 | }) 65 | ``` 66 | 67 | ## HELP!...my TMP dir is growing unbounded! 68 | 69 | ### description 70 | In general most OS distributions come with cron like tasks, which purge unused files in `$TMPDIR`. For example, ubuntu typically uses `tmpreaper` and macOS uses various tasks in `/etc/periodic/*`. 71 | 72 | ## options 73 | 74 | If your OS distribution does not provide such a cleanup mechanism: 75 | 76 | a) We stronglly recommend utilizing one, as other sync-disk-cache is not alone in rely on this behavior 77 | b) If that is not possible, we recommend changing your `$TMPDIR` to something project specific and manually purging it. 78 | 79 | ## License 80 | 81 | Licensed under the MIT License, Copyright 2015 Stefan Penner 82 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | shallow_clone: true 2 | 3 | version: '{build}' 4 | 5 | environment: 6 | matrix: 7 | - nodejs_version: '8' 8 | - nodejs_version: '10' 9 | - nodejs_version: '12' 10 | 11 | 12 | install: 13 | - ps: Install-Product node $env:nodejs_version 14 | - npm install 15 | 16 | build: off 17 | 18 | test_script: 19 | - ps: 'npm run test:dot #PowerShell' 20 | - cmd: npm run test:dot 21 | 22 | cache: 23 | - node_modules 24 | -------------------------------------------------------------------------------- /common/bufferdemo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stefanpenner/async-disk-cache/75e28eaa3930ba7b678b1787e01ce2e1ab7b598f/common/bufferdemo.png -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const RSVP = require('rsvp'); 5 | const fs = require('fs'); 6 | const readFile = RSVP.denodeify(fs.readFile); 7 | const writeFile = RSVP.denodeify(fs.writeFile); 8 | const renameFile = RSVP.denodeify(fs.rename); 9 | const chmod = RSVP.denodeify(fs.chmod); 10 | const mkdirp = RSVP.denodeify(require('mkdirp')); 11 | const rimraf = RSVP.denodeify(require('rimraf')); 12 | const unlink = RSVP.denodeify(fs.unlink); 13 | const os = require('os'); 14 | const debug = require('debug')('async-disk-cache'); 15 | const zlib = require('zlib'); 16 | const heimdall = require('heimdalljs'); 17 | const crypto = require('crypto'); 18 | 19 | const CacheEntry = require('./lib/cache-entry'); 20 | const Metric = require('./lib/metric'); 21 | 22 | if (!heimdall.hasMonitor('async-disk-cache')) { 23 | heimdall.registerMonitor('async-disk-cache', function AsyncDiskCacheSchema() {}); 24 | } 25 | 26 | const username = require('username-sync')(); 27 | const tmpdir = path.join(os.tmpdir(), username); 28 | 29 | /* 30 | * @private 31 | * 32 | * Defines a function on the given object at the given property name. Wraps 33 | * the function with metric recording for heimdalljs. 34 | * 35 | * @method defineFunction 36 | * @param Object obj the object on which to define the function 37 | * @param String name the name to use for the function 38 | * @param Function fn 39 | * @returns Void 40 | */ 41 | function defineFunction(obj, name, fn) { 42 | obj[name] = function() { 43 | const stats = heimdall.statsFor('async-disk-cache'); 44 | const metrics = stats[name] = stats[name] || new Metric(); 45 | 46 | metrics.start(); 47 | 48 | let result; 49 | let didError = true; 50 | 51 | try { 52 | result = fn.apply(this, arguments); 53 | didError = false; 54 | } finally { 55 | if (didError) { 56 | metrics.stop(); 57 | } 58 | } 59 | 60 | if (typeof result.finally === 'function') { 61 | return result.finally(() => metrics.stop()); 62 | } 63 | 64 | metrics.stop(); 65 | return result; 66 | }; 67 | } 68 | 69 | /* 70 | * @private 71 | * @method processFile 72 | * @param String filePath the path of the cached file 73 | * @returns CacheEntry an object representing that cache entry 74 | */ 75 | function processFile(decompress, filePath) { 76 | return async (fileStream) => { 77 | let value = await decompress(fileStream); 78 | 79 | // is Buffer or string? >:D 80 | if (!this.supportBuffer || require('istextorbinary').isTextSync(false, value)) { 81 | debug('convert to string'); 82 | value = value.toString(); 83 | } else { 84 | debug('keep data as Buffer'); 85 | } 86 | 87 | return new CacheEntry(true, filePath, value); 88 | }; 89 | } 90 | 91 | /* 92 | * @private 93 | * 94 | * When we encounter a rejection with reason of ENOENT, we actually know this 95 | * should be a cache miss, so the rejection is handled as the CacheEntry.MISS 96 | * singleton is the result. 97 | * 98 | * But if we encounter anything else, we must assume a legitimate failure an 99 | * re-throw 100 | * 101 | * @method handleENOENT 102 | * @param Error reason 103 | * @returns CacheEntry returns the CacheEntry miss singleton 104 | */ 105 | function handleENOENT(reason) { 106 | if (reason && reason.code === 'ENOENT') { 107 | return CacheEntry.MISS; 108 | } 109 | throw reason; 110 | } 111 | 112 | const COMPRESSIONS = { 113 | deflate: { 114 | in: RSVP.denodeify(zlib.deflate), 115 | out: RSVP.denodeify(zlib.inflate) 116 | }, 117 | 118 | deflateRaw: { 119 | in: RSVP.denodeify(zlib.deflateRaw), 120 | out: RSVP.denodeify(zlib.inflateRaw) 121 | }, 122 | 123 | gzip: { 124 | in: RSVP.denodeify(zlib.gzip), 125 | out: RSVP.denodeify(zlib.gunzip) 126 | }, 127 | }; 128 | /* 129 | * 130 | * @class Cache 131 | * @param {String} key the global key that represents this cache in its final location 132 | * @param {String} options optional string path to the location for the 133 | * cache. If omitted the system tmpdir is used 134 | */ 135 | class Cache { 136 | constructor(key, _) { 137 | const options = _ || {}; 138 | this.tmpdir = options.location|| tmpdir; 139 | this.compression = options.compression || false; 140 | this.supportBuffer = options.supportBuffer || false; 141 | this.key = key || 'default-disk-cache'; 142 | this.root = path.join(this.tmpdir, 'if-you-need-to-delete-this-open-an-issue-async-disk-cache', this.key); 143 | 144 | debug('new Cache { root: %s, compression: %s }', this.root, this.compression); 145 | } 146 | } 147 | 148 | /* 149 | * @public 150 | * 151 | * @method clear 152 | * @returns {Promise} - fulfills when the cache has been cleared 153 | * - rejects when a failured occured during cache clear 154 | */ 155 | defineFunction(Cache.prototype, 'clear', function() { 156 | debug('clear: %s', this.root); 157 | 158 | return rimraf( 159 | path.join(this.root) 160 | ); 161 | }); 162 | 163 | /* 164 | * @public 165 | * 166 | * @method has 167 | * @param {String} key the key to check existence of 168 | * @return {Promise} - fulfills with either true | false depending if the key was found or not 169 | * - rejects when a failured occured when checking existence of the key 170 | */ 171 | defineFunction(Cache.prototype, 'has', function(key) { 172 | const filePath = this.pathFor(key); 173 | debug('has: %s', filePath); 174 | return new RSVP.Promise(resolve => fs.exists(filePath, resolve)); 175 | }); 176 | 177 | /* 178 | * @public 179 | * 180 | * @method set 181 | * @param {String} key they key to retrieve 182 | * @return {Promise} - fulfills with either the cache entry, or a cache miss entry 183 | * - rejects when a failure occured looking retrieving the key 184 | */ 185 | defineFunction(Cache.prototype, 'get', function(key) { 186 | const filePath = this.pathFor(key); 187 | debug('get: %s', filePath); 188 | 189 | return readFile(filePath). 190 | then(processFile.call(this, this.decompress.bind(this), filePath), handleENOENT); 191 | }); 192 | 193 | /* 194 | * @public 195 | * 196 | * @method set 197 | * @param {String} key the key we wish to store 198 | * @param {String} value the value we wish the key to be stored with 199 | * @returns {Promise#fulfilled} if the value was coõstored as the key 200 | * @returns {Promise#rejected} when a failure occured persisting the key 201 | */ 202 | 203 | 204 | defineFunction(Cache.prototype, 'set', function(key, value) { 205 | // use RSVP to preserve public API as node 8 does not yet have Promise.prototype.finally 206 | 207 | return new RSVP.Promise(resolve => { 208 | resolve((async () => { 209 | const filePath = this.pathFor(key); 210 | debug('set : %s', filePath); 211 | const cache = this; 212 | 213 | await writeP(filePath, await cache.compress(value)); 214 | return filePath; 215 | })()); 216 | }); 217 | }); 218 | 219 | const MAX_DIGITS = Math.pow(10, (Number.MAX_SAFE_INTEGER + '').length); 220 | 221 | async function writeP(filePath, content) { 222 | const base = path.dirname(filePath); 223 | const random = Math.random() * MAX_DIGITS; 224 | const tmpfile = filePath + '.tmp.' + random; 225 | 226 | try { 227 | await writeFile(tmpfile, content) 228 | } catch(reason) { 229 | if (reason && reason.code === 'ENOENT') { 230 | await mkdirp(base, { mode: '0700' }); 231 | await writeFile(tmpfile, content); 232 | } else { 233 | throw reason; 234 | } 235 | } 236 | 237 | await renameFile(tmpfile, filePath); 238 | await chmod(filePath, '600'); 239 | } 240 | 241 | /* 242 | * @public 243 | * 244 | * @method remove 245 | * @param {String} key the key to remove from the cache 246 | * @returns {Promise#fulfilled} if the removal was successful 247 | * @returns {Promise#rejection} if something went wrong while removing the key 248 | */ 249 | defineFunction(Cache.prototype, 'remove', function(key) { 250 | // use RSVP to preserve public API as node 8 does not yet have Promise.prototype.finally 251 | return new RSVP.Promise(resolve => { 252 | resolve((async () => { 253 | const filePath = this.pathFor(key); 254 | debug('remove : %s', filePath); 255 | 256 | try { 257 | await unlink(filePath); 258 | } catch(e) { 259 | await handleENOENT(e); 260 | } 261 | })()); 262 | }); 263 | }); 264 | 265 | /* 266 | * @public 267 | * 268 | * @method pathFor 269 | * @param {String} key the key to generate the final path for 270 | * @returns the path where the key's value may reside 271 | */ 272 | defineFunction(Cache.prototype, 'pathFor', function(key) { 273 | return path.join(this.root, crypto.createHash('sha1').update(key).digest('hex')); 274 | }); 275 | 276 | /* 277 | * @public 278 | * 279 | * @method decompress 280 | * @param {String} compressedValue 281 | * @returns decompressedValue 282 | */ 283 | defineFunction(Cache.prototype, 'decompress', function(value) { 284 | if (!this.compression) { 285 | return value; 286 | } 287 | 288 | return COMPRESSIONS[this.compression].out(value); 289 | }); 290 | 291 | /* 292 | * @public 293 | * 294 | * @method compress 295 | * @param {String} value 296 | * @returns compressedValue 297 | */ 298 | defineFunction(Cache.prototype, 'compress', function(value) { 299 | if (!this.compression) { 300 | return value; 301 | } 302 | return COMPRESSIONS[this.compression].in(value); 303 | }); 304 | 305 | module.exports = Cache; 306 | -------------------------------------------------------------------------------- /lib/cache-entry.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = class CacheEntry { 4 | constructor(isCached, key, value) { 5 | this.isCached = isCached; 6 | this.key = key; 7 | this.value = value; 8 | } 9 | }; 10 | 11 | module.exports.MISS = new module.exports(false); 12 | 13 | -------------------------------------------------------------------------------- /lib/metric.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = class Metric { 4 | constructor() { 5 | this.count = 0; 6 | this.time = 0; 7 | this.running = 0; 8 | this.startTime = undefined; 9 | } 10 | 11 | start() { 12 | this.startTime = process.hrtime(); 13 | this.count++; 14 | this.running++; 15 | } 16 | 17 | stop() { 18 | this.running--; 19 | 20 | // Since we're only recording time once after all running locks are released, 21 | // we're only collecting "wall clock" time and not "cost" time. 22 | if (this.running > 0) { 23 | return; 24 | } else if (this.running < 0) { 25 | throw new Error('Called stop more times than start was called'); 26 | } 27 | 28 | let change = process.hrtime(this.startTime); 29 | 30 | this.time += change[0] * 1e9 + change[1]; 31 | this.startTime = undefined; 32 | } 33 | 34 | toJSON() { 35 | return { 36 | count: this.count, 37 | time: this.time 38 | }; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "async-disk-cache", 3 | "version": "2.1.0", 4 | "description": "Async disk cache", 5 | "files": [ 6 | "index.js", 7 | "lib/" 8 | ], 9 | "scripts": { 10 | "test": "mocha test.js", 11 | "test:debug": "mocha debug test.js", 12 | "test:dot": "mocha test.js --reporter dot", 13 | "coverage": "istanbul cover _mocha" 14 | }, 15 | "repository": "stefanpenner/async-disk-cache", 16 | "keywords": [ 17 | "cache", 18 | "temp", 19 | "file" 20 | ], 21 | "author": "Stefan Penner ", 22 | "license": "MIT", 23 | "dependencies": { 24 | "debug": "^4.1.1", 25 | "heimdalljs": "^0.2.3", 26 | "istextorbinary": "^2.5.1", 27 | "mkdirp": "^0.5.0", 28 | "rimraf": "^3.0.0", 29 | "rsvp": "^4.8.5", 30 | "username-sync": "^1.0.2" 31 | }, 32 | "devDependencies": { 33 | "chai": "^4.2.0", 34 | "istanbul": "^0.4.4", 35 | "mocha": "^6.2.2", 36 | "stat-mode": "^0.3.0" 37 | }, 38 | "engines": { 39 | "node": "8.* || >= 10.*" 40 | }, 41 | "jscsConfig": { 42 | "preset": "google", 43 | "disallowMultipleVarDecl": true, 44 | "maximumLineLength": 80, 45 | "requireBlocksOnNewline": true, 46 | "validateLineBreaks": "LF" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const Cache = require('./'); 5 | const Metric = require('./lib/metric'); 6 | const fs = require('fs'); 7 | const chai = require('chai'); 8 | const expect = chai.expect; 9 | const RSVP = require('rsvp'); 10 | const Mode = require('stat-mode'); 11 | const crypto = require('crypto'); 12 | const heimdall = require('heimdalljs'); 13 | 14 | const MODE = process.platform === 'win32' ? '-rw-rw-rw-' : '-rw-------'; 15 | 16 | describe('cache', function() { 17 | let cache; 18 | const key = 'path/to/file.js'; 19 | const value = 'Some test value'; 20 | const longKey = 'GET|https://api.example.com/lorem/ipsum/dolor/sit/amet/consectetur/adipiscing/elit?donec=in&consequat=nibh&mauris=condimentum&turpis=at&lacus=finibus&ut=rutrum&lorem=dictum&morbi=dictum&ac=lectus&et=porttitor&donec=vel&dolor=ex&cras=aliquam&risus=in&tellus=mollis&elementum=pellentesque&lobortis=a&ex=nec&egestas=nunc&nec=feugiat&ante=integer&sit=amet&nibh=id&nisi=vulputate&condimentum=aliquam&lacinia=dignissim'; 21 | const keyHash = crypto.createHash('sha1').update(key).digest('hex'); 22 | const longKeyHash = crypto.createHash('sha1').update(longKey).digest('hex'); 23 | 24 | beforeEach(function() { 25 | cache = new Cache(); 26 | }); 27 | 28 | afterEach(function() { 29 | return cache.clear(); 30 | }); 31 | 32 | it('has expected default root', function() { 33 | let os = require('os'); 34 | let tmpdir = os.tmpdir(); 35 | let username = require('username-sync')(); 36 | let descriptiveName = 'if-you-need-to-delete-this-open-an-issue-async-disk-cache'; 37 | let defaultKey = 'default-disk-cache'; 38 | 39 | expect(cache.root).to.eql(path.join(tmpdir, username, descriptiveName, defaultKey)); 40 | }); 41 | 42 | it('pathFor', function() { 43 | expect(cache.pathFor(key)).to.be.equal(path.join(cache.root, keyHash)); 44 | expect(cache.pathFor(longKey)).to.be.equal(path.join(cache.root, longKeyHash)); 45 | }); 46 | 47 | it('set', async function() { 48 | let filePath = await cache.set(key, value); 49 | // credit @jgable 50 | let mode = new Mode(fs.statSync(filePath)); 51 | 52 | expect(mode.toString()).to.equal(MODE); 53 | 54 | expect(fs.readFileSync(filePath).toString()).equal(value); 55 | }); 56 | 57 | it('get (doesn\'t exist)', async function() { 58 | expect((await cache.get(key)).isCached).be.false; 59 | }); 60 | 61 | it('get (does exist)', async function() { 62 | let filePath = await cache.set(key, value); 63 | let details = await cache.get(key); 64 | expect(details.isCached).be.true; 65 | expect(details.value).equal(value); 66 | expect(details.key).equal(filePath); 67 | }); 68 | 69 | it('has (doesn\'t exist)', async function() { 70 | expect(await cache.has(key)).be.false; 71 | }); 72 | 73 | it('has (does exist)', async function() { 74 | await cache.set(key, value); 75 | expect(await cache.has(key)).be.true; 76 | }); 77 | 78 | it('has (does exist) (long key)', async function() { 79 | await cache.set(longKey, value) 80 | expect(await cache.has(longKey)).be.true; 81 | }); 82 | 83 | it('remove', async function() { 84 | await cache.set(key, value) 85 | expect(await cache.has(key)).be.true; 86 | 87 | await cache.remove(key); 88 | expect(await cache.has(key)).be.false; 89 | }); 90 | 91 | it('handles concurrent operations', async function() { 92 | await RSVP.Promise.all([ 93 | cache.get(key).then(details => expect(details.isCached).be.false), 94 | cache.get(key).then(details => expect(details.isCached).be.false) 95 | ]); 96 | }); 97 | 98 | it('properly stops metrics when an error occurs', function() { 99 | expect(() => cache.pathFor()).to.throw(); 100 | expect(heimdall.statsFor('async-disk-cache').pathFor.startTime).to.be.undefined; 101 | }); 102 | }); 103 | 104 | const zlib = require('zlib'); 105 | const inflate = RSVP.denodeify(zlib.inflate); 106 | const gunzip = RSVP.denodeify(zlib.gunzip); 107 | const inflateRaw = RSVP.denodeify(zlib.inflateRaw); 108 | 109 | describe('cache compress: [ deflate ]', function() { 110 | let cache; 111 | let key = 'path/to/file.js'; 112 | let value = 'Some test value'; 113 | 114 | beforeEach(function() { 115 | cache = new Cache('my-testing-cache', { 116 | compression: 'deflate' 117 | }); 118 | }); 119 | 120 | afterEach(function() { 121 | return cache.clear(); 122 | }); 123 | 124 | it('set', async function() { 125 | let filePath = await cache.set(key, value); 126 | let mode = new Mode(fs.statSync(filePath)); 127 | 128 | expect(mode.toString()).to.equal(MODE); 129 | 130 | let result = await inflate(fs.readFileSync(filePath)); 131 | result = result.toString(); 132 | expect(result).equal(value); 133 | 134 | let detail = await cache.get(key); 135 | expect(detail.value).equal(value); 136 | }); 137 | }); 138 | 139 | describe('cache compress: [ gzip ]', function() { 140 | let cache; 141 | let key = 'path/to/file.js'; 142 | let value = 'Some test value'; 143 | 144 | beforeEach(function() { 145 | cache = new Cache('my-testing-cache', { 146 | compression: 'gzip' 147 | }); 148 | }); 149 | 150 | afterEach(function() { 151 | return cache.clear(); 152 | }); 153 | 154 | it('set', async function() { 155 | let filePath = await cache.set(key, value); 156 | let result = await gunzip(fs.readFileSync(filePath)); 157 | result = result.toString(); 158 | 159 | expect(result).equal(value); 160 | 161 | let detail = await cache.get(key); 162 | expect(detail.value).equal(value); 163 | }); 164 | }); 165 | 166 | describe('cache compress: [ deflateRaw ]', function() { 167 | let cache; 168 | let key = 'path/to/file.js'; 169 | let value = 'Some test value'; 170 | 171 | beforeEach(function() { 172 | cache = new Cache('my-testing-cache', { 173 | compression: 'deflateRaw' 174 | }); 175 | }); 176 | 177 | afterEach(function() { 178 | return cache.clear(); 179 | }); 180 | 181 | it('set', async function() { 182 | let filePath = await cache.set(key, value); 183 | let mode = new Mode(fs.statSync(filePath)); 184 | 185 | expect(mode.toString()).to.equal(MODE); 186 | 187 | let result = await inflateRaw(fs.readFileSync(filePath)); 188 | result = result.toString(); 189 | expect(result).equal(value); 190 | 191 | let detail = await cache.get(key); 192 | expect(detail.value).equal(value); 193 | }); 194 | }); 195 | 196 | describe('buffer support', function() { 197 | let key = 'buffer_fixed'; 198 | let value = fs.readFileSync('./common/bufferdemo.png'); 199 | let cache = new Cache('my-testing-cache', { supportBuffer: true }); 200 | 201 | it('set', async function() { 202 | // set file to cache 203 | await cache.set(key, value) 204 | // get file from cache 205 | const cacheEntry = await cache.get(key); 206 | 207 | fs.writeFileSync('./common/bufferdemo_fromcache.png', cacheEntry.value); 208 | 209 | let oldFile = fs.readFileSync('./common/bufferdemo.png'); 210 | let newFile = fs.readFileSync('./common/bufferdemo_fromcache.png'); 211 | 212 | if (oldFile.toString('binary') !== newFile.toString('binary')) { 213 | throw new Error('Files didn\'t match!'); 214 | } 215 | }); 216 | }); 217 | 218 | describe('buffer support disabled', function() { 219 | let key = 'buffer_fixed'; 220 | let value = fs.readFileSync('./common/bufferdemo.png'); 221 | let cache = new Cache('my-testing-cache'); 222 | 223 | it('set', async function() { 224 | await cache.set(key, value); 225 | 226 | // get file from cache 227 | const cacheEntry = await cache.get(key); 228 | 229 | fs.writeFileSync('./common/bufferdemo_fromcache.png', cacheEntry.value); 230 | 231 | let oldFile = fs.readFileSync('./common/bufferdemo.png'); 232 | let newFile = fs.readFileSync('./common/bufferdemo_fromcache.png'); 233 | 234 | if (oldFile.toString('binary') !== newFile.toString('binary')) { 235 | 236 | } else { 237 | throw new Error('Files still matches, looks like nodejs community has fixed Buffer -> to string -> to buffer conversion bug. Applaud!'); 238 | } 239 | }); 240 | }); 241 | 242 | describe('metric', function() { 243 | it('throws error if stop called more than start', function() { 244 | const metric = new Metric(); 245 | expect(() => { 246 | metric.stop(); 247 | }).to.throw('Called stop more times than start was called'); 248 | }); 249 | 250 | it('can safely call start and stop multiple times', function() { 251 | const metric = new Metric(); 252 | 253 | metric.start(); 254 | metric.start(); 255 | metric.stop(); 256 | metric.start(); 257 | metric.stop(); 258 | metric.stop(); 259 | 260 | const json = metric.toJSON(); 261 | expect(json.count).to.equal(3); 262 | expect(json.time).to.be.greaterThan(0); 263 | }); 264 | }); 265 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | abbrev@1: 6 | version "1.1.1" 7 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" 8 | integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== 9 | 10 | abbrev@1.0.x: 11 | version "1.0.9" 12 | resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" 13 | integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= 14 | 15 | amdefine@>=0.0.4: 16 | version "1.0.1" 17 | resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" 18 | integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= 19 | 20 | ansi-colors@3.2.3: 21 | version "3.2.3" 22 | resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" 23 | integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== 24 | 25 | ansi-regex@^3.0.0: 26 | version "3.0.0" 27 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" 28 | integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= 29 | 30 | ansi-regex@^4.1.0: 31 | version "4.1.0" 32 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" 33 | integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== 34 | 35 | ansi-styles@^3.2.0, ansi-styles@^3.2.1: 36 | version "3.2.1" 37 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 38 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 39 | dependencies: 40 | color-convert "^1.9.0" 41 | 42 | argparse@^1.0.7: 43 | version "1.0.10" 44 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" 45 | integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== 46 | dependencies: 47 | sprintf-js "~1.0.2" 48 | 49 | assertion-error@^1.1.0: 50 | version "1.1.0" 51 | resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" 52 | integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== 53 | 54 | async@1.x: 55 | version "1.5.2" 56 | resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" 57 | integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= 58 | 59 | balanced-match@^1.0.0: 60 | version "1.0.0" 61 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 62 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 63 | 64 | binaryextensions@^2.1.2: 65 | version "2.1.2" 66 | resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.1.2.tgz#c83c3d74233ba7674e4f313cb2a2b70f54e94b7c" 67 | integrity sha512-xVNN69YGDghOqCCtA6FI7avYrr02mTJjOgB0/f1VPD3pJC8QEvjTKWc4epDx8AqxxA75NI0QpVM2gPJXUbE4Tg== 68 | 69 | brace-expansion@^1.1.7: 70 | version "1.1.11" 71 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 72 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 73 | dependencies: 74 | balanced-match "^1.0.0" 75 | concat-map "0.0.1" 76 | 77 | browser-stdout@1.3.1: 78 | version "1.3.1" 79 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" 80 | integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== 81 | 82 | camelcase@^5.0.0: 83 | version "5.3.1" 84 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" 85 | integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== 86 | 87 | chai@^4.2.0: 88 | version "4.2.0" 89 | resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" 90 | integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== 91 | dependencies: 92 | assertion-error "^1.1.0" 93 | check-error "^1.0.2" 94 | deep-eql "^3.0.1" 95 | get-func-name "^2.0.0" 96 | pathval "^1.1.0" 97 | type-detect "^4.0.5" 98 | 99 | chalk@^2.0.1: 100 | version "2.4.2" 101 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 102 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== 103 | dependencies: 104 | ansi-styles "^3.2.1" 105 | escape-string-regexp "^1.0.5" 106 | supports-color "^5.3.0" 107 | 108 | check-error@^1.0.2: 109 | version "1.0.2" 110 | resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" 111 | integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= 112 | 113 | cliui@^5.0.0: 114 | version "5.0.0" 115 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" 116 | integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== 117 | dependencies: 118 | string-width "^3.1.0" 119 | strip-ansi "^5.2.0" 120 | wrap-ansi "^5.1.0" 121 | 122 | color-convert@^1.9.0: 123 | version "1.9.3" 124 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 125 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 126 | dependencies: 127 | color-name "1.1.3" 128 | 129 | color-name@1.1.3: 130 | version "1.1.3" 131 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 132 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 133 | 134 | commander@~2.20.3: 135 | version "2.20.3" 136 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" 137 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== 138 | 139 | concat-map@0.0.1: 140 | version "0.0.1" 141 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 142 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 143 | 144 | debug@3.2.6: 145 | version "3.2.6" 146 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" 147 | integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== 148 | dependencies: 149 | ms "^2.1.1" 150 | 151 | debug@^4.1.1: 152 | version "4.1.1" 153 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" 154 | integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== 155 | dependencies: 156 | ms "^2.1.1" 157 | 158 | decamelize@^1.2.0: 159 | version "1.2.0" 160 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 161 | integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= 162 | 163 | deep-eql@^3.0.1: 164 | version "3.0.1" 165 | resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" 166 | integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== 167 | dependencies: 168 | type-detect "^4.0.0" 169 | 170 | deep-is@~0.1.3: 171 | version "0.1.3" 172 | resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" 173 | integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= 174 | 175 | define-properties@^1.1.2, define-properties@^1.1.3: 176 | version "1.1.3" 177 | resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" 178 | integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== 179 | dependencies: 180 | object-keys "^1.0.12" 181 | 182 | diff@3.5.0: 183 | version "3.5.0" 184 | resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" 185 | integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== 186 | 187 | editions@^2.1.3: 188 | version "2.2.0" 189 | resolved "https://registry.yarnpkg.com/editions/-/editions-2.2.0.tgz#dacd0c2a9441ebef592bba316a6264febb337f35" 190 | integrity sha512-RYg3iEA2BDLCNVe8PUkD+ox5vAKxB9XS/mAhx1bdxGCF0CpX077C0pyTA9t5D6idCYA3avl5/XDHKPsHFrygfw== 191 | dependencies: 192 | errlop "^1.1.2" 193 | semver "^6.3.0" 194 | 195 | emoji-regex@^7.0.1: 196 | version "7.0.3" 197 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" 198 | integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== 199 | 200 | errlop@^1.1.2: 201 | version "1.1.2" 202 | resolved "https://registry.yarnpkg.com/errlop/-/errlop-1.1.2.tgz#a99a48f37aa264d614e342ffdbbaa49eec9220e0" 203 | integrity sha512-djkRp+urJ+SmqDBd7F6LUgm4Be1TTYBxia2bhjNdFBuBDQtJDHExD2VbxR6eyst3h1TZy3qPRCdqb6FBoFttTA== 204 | dependencies: 205 | editions "^2.1.3" 206 | 207 | es-abstract@^1.5.1: 208 | version "1.16.0" 209 | resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.16.0.tgz#d3a26dc9c3283ac9750dca569586e976d9dcc06d" 210 | integrity sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg== 211 | dependencies: 212 | es-to-primitive "^1.2.0" 213 | function-bind "^1.1.1" 214 | has "^1.0.3" 215 | has-symbols "^1.0.0" 216 | is-callable "^1.1.4" 217 | is-regex "^1.0.4" 218 | object-inspect "^1.6.0" 219 | object-keys "^1.1.1" 220 | string.prototype.trimleft "^2.1.0" 221 | string.prototype.trimright "^2.1.0" 222 | 223 | es-to-primitive@^1.2.0: 224 | version "1.2.0" 225 | resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" 226 | integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== 227 | dependencies: 228 | is-callable "^1.1.4" 229 | is-date-object "^1.0.1" 230 | is-symbol "^1.0.2" 231 | 232 | escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: 233 | version "1.0.5" 234 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 235 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= 236 | 237 | escodegen@1.8.x: 238 | version "1.8.1" 239 | resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" 240 | integrity sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= 241 | dependencies: 242 | esprima "^2.7.1" 243 | estraverse "^1.9.1" 244 | esutils "^2.0.2" 245 | optionator "^0.8.1" 246 | optionalDependencies: 247 | source-map "~0.2.0" 248 | 249 | esprima@2.7.x, esprima@^2.7.1: 250 | version "2.7.3" 251 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" 252 | integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= 253 | 254 | esprima@^4.0.0: 255 | version "4.0.1" 256 | resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" 257 | integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 258 | 259 | estraverse@^1.9.1: 260 | version "1.9.3" 261 | resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" 262 | integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= 263 | 264 | esutils@^2.0.2: 265 | version "2.0.3" 266 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" 267 | integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== 268 | 269 | fast-levenshtein@~2.0.4: 270 | version "2.0.6" 271 | resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" 272 | integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= 273 | 274 | find-up@3.0.0, find-up@^3.0.0: 275 | version "3.0.0" 276 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" 277 | integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== 278 | dependencies: 279 | locate-path "^3.0.0" 280 | 281 | flat@^4.1.0: 282 | version "4.1.0" 283 | resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.0.tgz#090bec8b05e39cba309747f1d588f04dbaf98db2" 284 | integrity sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw== 285 | dependencies: 286 | is-buffer "~2.0.3" 287 | 288 | fs.realpath@^1.0.0: 289 | version "1.0.0" 290 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 291 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 292 | 293 | function-bind@^1.1.1: 294 | version "1.1.1" 295 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 296 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 297 | 298 | get-caller-file@^2.0.1: 299 | version "2.0.5" 300 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 301 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 302 | 303 | get-func-name@^2.0.0: 304 | version "2.0.0" 305 | resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" 306 | integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= 307 | 308 | glob@7.1.3: 309 | version "7.1.3" 310 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" 311 | integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== 312 | dependencies: 313 | fs.realpath "^1.0.0" 314 | inflight "^1.0.4" 315 | inherits "2" 316 | minimatch "^3.0.4" 317 | once "^1.3.0" 318 | path-is-absolute "^1.0.0" 319 | 320 | glob@^5.0.15: 321 | version "5.0.15" 322 | resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" 323 | integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= 324 | dependencies: 325 | inflight "^1.0.4" 326 | inherits "2" 327 | minimatch "2 || 3" 328 | once "^1.3.0" 329 | path-is-absolute "^1.0.0" 330 | 331 | glob@^7.1.3: 332 | version "7.1.5" 333 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.5.tgz#6714c69bee20f3c3e64c4dd905553e532b40cdc0" 334 | integrity sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ== 335 | dependencies: 336 | fs.realpath "^1.0.0" 337 | inflight "^1.0.4" 338 | inherits "2" 339 | minimatch "^3.0.4" 340 | once "^1.3.0" 341 | path-is-absolute "^1.0.0" 342 | 343 | growl@1.10.5: 344 | version "1.10.5" 345 | resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" 346 | integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== 347 | 348 | handlebars@^4.0.1: 349 | version "4.5.1" 350 | resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.1.tgz#8a01c382c180272260d07f2d1aa3ae745715c7ba" 351 | integrity sha512-C29UoFzHe9yM61lOsIlCE5/mQVGrnIOrOq7maQl76L7tYPCgC1og0Ajt6uWnX4ZTxBPnjw+CUvawphwCfJgUnA== 352 | dependencies: 353 | neo-async "^2.6.0" 354 | optimist "^0.6.1" 355 | source-map "^0.6.1" 356 | optionalDependencies: 357 | uglify-js "^3.1.4" 358 | 359 | has-flag@^1.0.0: 360 | version "1.0.0" 361 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" 362 | integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= 363 | 364 | has-flag@^3.0.0: 365 | version "3.0.0" 366 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 367 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= 368 | 369 | has-symbols@^1.0.0: 370 | version "1.0.0" 371 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" 372 | integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= 373 | 374 | has@^1.0.1, has@^1.0.3: 375 | version "1.0.3" 376 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" 377 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 378 | dependencies: 379 | function-bind "^1.1.1" 380 | 381 | he@1.2.0: 382 | version "1.2.0" 383 | resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" 384 | integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== 385 | 386 | heimdalljs@^0.2.3: 387 | version "0.2.6" 388 | resolved "https://registry.yarnpkg.com/heimdalljs/-/heimdalljs-0.2.6.tgz#b0eebabc412813aeb9542f9cc622cb58dbdcd9fe" 389 | integrity sha512-o9bd30+5vLBvBtzCPwwGqpry2+n0Hi6H1+qwt6y+0kwRHGGF8TFIhJPmnuM0xO97zaKrDZMwO/V56fAnn8m/tA== 390 | dependencies: 391 | rsvp "~3.2.1" 392 | 393 | inflight@^1.0.4: 394 | version "1.0.6" 395 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 396 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 397 | dependencies: 398 | once "^1.3.0" 399 | wrappy "1" 400 | 401 | inherits@2: 402 | version "2.0.4" 403 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 404 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 405 | 406 | is-buffer@~2.0.3: 407 | version "2.0.4" 408 | resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" 409 | integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== 410 | 411 | is-callable@^1.1.4: 412 | version "1.1.4" 413 | resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" 414 | integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== 415 | 416 | is-date-object@^1.0.1: 417 | version "1.0.1" 418 | resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" 419 | integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= 420 | 421 | is-fullwidth-code-point@^2.0.0: 422 | version "2.0.0" 423 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 424 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= 425 | 426 | is-regex@^1.0.4: 427 | version "1.0.4" 428 | resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" 429 | integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= 430 | dependencies: 431 | has "^1.0.1" 432 | 433 | is-symbol@^1.0.2: 434 | version "1.0.2" 435 | resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" 436 | integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== 437 | dependencies: 438 | has-symbols "^1.0.0" 439 | 440 | isexe@^2.0.0: 441 | version "2.0.0" 442 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 443 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 444 | 445 | istanbul@^0.4.4: 446 | version "0.4.5" 447 | resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" 448 | integrity sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs= 449 | dependencies: 450 | abbrev "1.0.x" 451 | async "1.x" 452 | escodegen "1.8.x" 453 | esprima "2.7.x" 454 | glob "^5.0.15" 455 | handlebars "^4.0.1" 456 | js-yaml "3.x" 457 | mkdirp "0.5.x" 458 | nopt "3.x" 459 | once "1.x" 460 | resolve "1.1.x" 461 | supports-color "^3.1.0" 462 | which "^1.1.1" 463 | wordwrap "^1.0.0" 464 | 465 | istextorbinary@^2.5.1: 466 | version "2.5.1" 467 | resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-2.5.1.tgz#14a33824cf6b9d5d7743eac1be2bd2c310d0ccbd" 468 | integrity sha512-pv/JNPWnfpwGjPx7JrtWTwsWsxkrK3fNzcEVnt92YKEIErps4Fsk49+qzCe9iQF2hjqK8Naqf8P9kzoeCuQI1g== 469 | dependencies: 470 | binaryextensions "^2.1.2" 471 | editions "^2.1.3" 472 | textextensions "^2.4.0" 473 | 474 | js-yaml@3.13.1, js-yaml@3.x: 475 | version "3.13.1" 476 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" 477 | integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== 478 | dependencies: 479 | argparse "^1.0.7" 480 | esprima "^4.0.0" 481 | 482 | levn@~0.3.0: 483 | version "0.3.0" 484 | resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" 485 | integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= 486 | dependencies: 487 | prelude-ls "~1.1.2" 488 | type-check "~0.3.2" 489 | 490 | locate-path@^3.0.0: 491 | version "3.0.0" 492 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" 493 | integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== 494 | dependencies: 495 | p-locate "^3.0.0" 496 | path-exists "^3.0.0" 497 | 498 | lodash@^4.17.15: 499 | version "4.17.15" 500 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" 501 | integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== 502 | 503 | log-symbols@2.2.0: 504 | version "2.2.0" 505 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" 506 | integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== 507 | dependencies: 508 | chalk "^2.0.1" 509 | 510 | "minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.4: 511 | version "3.0.4" 512 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 513 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 514 | dependencies: 515 | brace-expansion "^1.1.7" 516 | 517 | minimist@0.0.8: 518 | version "0.0.8" 519 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 520 | integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= 521 | 522 | minimist@~0.0.1: 523 | version "0.0.10" 524 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" 525 | integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= 526 | 527 | mkdirp@0.5.1, mkdirp@0.5.x, mkdirp@^0.5.0: 528 | version "0.5.1" 529 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 530 | integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= 531 | dependencies: 532 | minimist "0.0.8" 533 | 534 | mocha@^6.2.2: 535 | version "6.2.2" 536 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.2.2.tgz#5d8987e28940caf8957a7d7664b910dc5b2fea20" 537 | integrity sha512-FgDS9Re79yU1xz5d+C4rv1G7QagNGHZ+iXF81hO8zY35YZZcLEsJVfFolfsqKFWunATEvNzMK0r/CwWd/szO9A== 538 | dependencies: 539 | ansi-colors "3.2.3" 540 | browser-stdout "1.3.1" 541 | debug "3.2.6" 542 | diff "3.5.0" 543 | escape-string-regexp "1.0.5" 544 | find-up "3.0.0" 545 | glob "7.1.3" 546 | growl "1.10.5" 547 | he "1.2.0" 548 | js-yaml "3.13.1" 549 | log-symbols "2.2.0" 550 | minimatch "3.0.4" 551 | mkdirp "0.5.1" 552 | ms "2.1.1" 553 | node-environment-flags "1.0.5" 554 | object.assign "4.1.0" 555 | strip-json-comments "2.0.1" 556 | supports-color "6.0.0" 557 | which "1.3.1" 558 | wide-align "1.1.3" 559 | yargs "13.3.0" 560 | yargs-parser "13.1.1" 561 | yargs-unparser "1.6.0" 562 | 563 | ms@2.1.1: 564 | version "2.1.1" 565 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" 566 | integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== 567 | 568 | ms@^2.1.1: 569 | version "2.1.2" 570 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 571 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 572 | 573 | neo-async@^2.6.0: 574 | version "2.6.1" 575 | resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" 576 | integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== 577 | 578 | node-environment-flags@1.0.5: 579 | version "1.0.5" 580 | resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.5.tgz#fa930275f5bf5dae188d6192b24b4c8bbac3d76a" 581 | integrity sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ== 582 | dependencies: 583 | object.getownpropertydescriptors "^2.0.3" 584 | semver "^5.7.0" 585 | 586 | nopt@3.x: 587 | version "3.0.6" 588 | resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" 589 | integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= 590 | dependencies: 591 | abbrev "1" 592 | 593 | object-inspect@^1.6.0: 594 | version "1.6.0" 595 | resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" 596 | integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ== 597 | 598 | object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: 599 | version "1.1.1" 600 | resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" 601 | integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== 602 | 603 | object.assign@4.1.0: 604 | version "4.1.0" 605 | resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" 606 | integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== 607 | dependencies: 608 | define-properties "^1.1.2" 609 | function-bind "^1.1.1" 610 | has-symbols "^1.0.0" 611 | object-keys "^1.0.11" 612 | 613 | object.getownpropertydescriptors@^2.0.3: 614 | version "2.0.3" 615 | resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" 616 | integrity sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY= 617 | dependencies: 618 | define-properties "^1.1.2" 619 | es-abstract "^1.5.1" 620 | 621 | once@1.x, once@^1.3.0: 622 | version "1.4.0" 623 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 624 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 625 | dependencies: 626 | wrappy "1" 627 | 628 | optimist@^0.6.1: 629 | version "0.6.1" 630 | resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" 631 | integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= 632 | dependencies: 633 | minimist "~0.0.1" 634 | wordwrap "~0.0.2" 635 | 636 | optionator@^0.8.1: 637 | version "0.8.2" 638 | resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" 639 | integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= 640 | dependencies: 641 | deep-is "~0.1.3" 642 | fast-levenshtein "~2.0.4" 643 | levn "~0.3.0" 644 | prelude-ls "~1.1.2" 645 | type-check "~0.3.2" 646 | wordwrap "~1.0.0" 647 | 648 | p-limit@^2.0.0: 649 | version "2.2.1" 650 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" 651 | integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== 652 | dependencies: 653 | p-try "^2.0.0" 654 | 655 | p-locate@^3.0.0: 656 | version "3.0.0" 657 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" 658 | integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== 659 | dependencies: 660 | p-limit "^2.0.0" 661 | 662 | p-try@^2.0.0: 663 | version "2.2.0" 664 | resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" 665 | integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== 666 | 667 | path-exists@^3.0.0: 668 | version "3.0.0" 669 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" 670 | integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= 671 | 672 | path-is-absolute@^1.0.0: 673 | version "1.0.1" 674 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 675 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 676 | 677 | pathval@^1.1.0: 678 | version "1.1.0" 679 | resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" 680 | integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= 681 | 682 | prelude-ls@~1.1.2: 683 | version "1.1.2" 684 | resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" 685 | integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= 686 | 687 | require-directory@^2.1.1: 688 | version "2.1.1" 689 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 690 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= 691 | 692 | require-main-filename@^2.0.0: 693 | version "2.0.0" 694 | resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" 695 | integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== 696 | 697 | resolve@1.1.x: 698 | version "1.1.7" 699 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" 700 | integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= 701 | 702 | rimraf@^3.0.0: 703 | version "3.0.0" 704 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.0.tgz#614176d4b3010b75e5c390eb0ee96f6dc0cebb9b" 705 | integrity sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg== 706 | dependencies: 707 | glob "^7.1.3" 708 | 709 | rsvp@^4.8.5: 710 | version "4.8.5" 711 | resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" 712 | integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== 713 | 714 | rsvp@~3.2.1: 715 | version "3.2.1" 716 | resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.2.1.tgz#07cb4a5df25add9e826ebc67dcc9fd89db27d84a" 717 | integrity sha1-B8tKXfJa3Z6Cbrxn3Mn9idsn2Eo= 718 | 719 | semver@^5.7.0: 720 | version "5.7.1" 721 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" 722 | integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== 723 | 724 | semver@^6.3.0: 725 | version "6.3.0" 726 | resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" 727 | integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== 728 | 729 | set-blocking@^2.0.0: 730 | version "2.0.0" 731 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 732 | integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= 733 | 734 | source-map@^0.6.1, source-map@~0.6.1: 735 | version "0.6.1" 736 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 737 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 738 | 739 | source-map@~0.2.0: 740 | version "0.2.0" 741 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" 742 | integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50= 743 | dependencies: 744 | amdefine ">=0.0.4" 745 | 746 | sprintf-js@~1.0.2: 747 | version "1.0.3" 748 | resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" 749 | integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= 750 | 751 | stat-mode@^0.3.0: 752 | version "0.3.0" 753 | resolved "https://registry.yarnpkg.com/stat-mode/-/stat-mode-0.3.0.tgz#69283b081f851582b328d2a4ace5f591ce52f54b" 754 | integrity sha512-QjMLR0A3WwFY2aZdV0okfFEJB5TRjkggXZjxP3A1RsWsNHNu3YPv8btmtc6iCFZ0Rul3FE93OYogvhOUClU+ng== 755 | 756 | "string-width@^1.0.2 || 2": 757 | version "2.1.1" 758 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" 759 | integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== 760 | dependencies: 761 | is-fullwidth-code-point "^2.0.0" 762 | strip-ansi "^4.0.0" 763 | 764 | string-width@^3.0.0, string-width@^3.1.0: 765 | version "3.1.0" 766 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" 767 | integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== 768 | dependencies: 769 | emoji-regex "^7.0.1" 770 | is-fullwidth-code-point "^2.0.0" 771 | strip-ansi "^5.1.0" 772 | 773 | string.prototype.trimleft@^2.1.0: 774 | version "2.1.0" 775 | resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz#6cc47f0d7eb8d62b0f3701611715a3954591d634" 776 | integrity sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw== 777 | dependencies: 778 | define-properties "^1.1.3" 779 | function-bind "^1.1.1" 780 | 781 | string.prototype.trimright@^2.1.0: 782 | version "2.1.0" 783 | resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz#669d164be9df9b6f7559fa8e89945b168a5a6c58" 784 | integrity sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg== 785 | dependencies: 786 | define-properties "^1.1.3" 787 | function-bind "^1.1.1" 788 | 789 | strip-ansi@^4.0.0: 790 | version "4.0.0" 791 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" 792 | integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= 793 | dependencies: 794 | ansi-regex "^3.0.0" 795 | 796 | strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: 797 | version "5.2.0" 798 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" 799 | integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== 800 | dependencies: 801 | ansi-regex "^4.1.0" 802 | 803 | strip-json-comments@2.0.1: 804 | version "2.0.1" 805 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" 806 | integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= 807 | 808 | supports-color@6.0.0: 809 | version "6.0.0" 810 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" 811 | integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== 812 | dependencies: 813 | has-flag "^3.0.0" 814 | 815 | supports-color@^3.1.0: 816 | version "3.2.3" 817 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" 818 | integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= 819 | dependencies: 820 | has-flag "^1.0.0" 821 | 822 | supports-color@^5.3.0: 823 | version "5.5.0" 824 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" 825 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== 826 | dependencies: 827 | has-flag "^3.0.0" 828 | 829 | textextensions@^2.4.0: 830 | version "2.5.0" 831 | resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.5.0.tgz#e21d3831dafa37513dd80666dff541414e314293" 832 | integrity sha512-1IkVr355eHcomgK7fgj1Xsokturx6L5S2JRT5WcRdA6v5shk9sxWuO/w/VbpQexwkXJMQIa/j1dBi3oo7+HhcA== 833 | 834 | type-check@~0.3.2: 835 | version "0.3.2" 836 | resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" 837 | integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= 838 | dependencies: 839 | prelude-ls "~1.1.2" 840 | 841 | type-detect@^4.0.0, type-detect@^4.0.5: 842 | version "4.0.8" 843 | resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" 844 | integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== 845 | 846 | uglify-js@^3.1.4: 847 | version "3.6.5" 848 | resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.5.tgz#b0ee796d2ae7e25672e04f65629b997cd4b30bd6" 849 | integrity sha512-7L3W+Npia1OCr5Blp4/Vw83tK1mu5gnoIURtT1fUVfQ3Kf8WStWV6NJz0fdoBJZls0KlweruRTLVe6XLafmy5g== 850 | dependencies: 851 | commander "~2.20.3" 852 | source-map "~0.6.1" 853 | 854 | username-sync@^1.0.2: 855 | version "1.0.2" 856 | resolved "https://registry.yarnpkg.com/username-sync/-/username-sync-1.0.2.tgz#0a3697909fb7b5768d29e2921f573acfdd427592" 857 | integrity sha512-ayNkOJdoNSGNDBE46Nkc+l6IXmeugbzahZLSMkwvgRWv5y5ZqNY2IrzcgmkR4z32sj1W3tM3TuTUMqkqBzO+RA== 858 | 859 | which-module@^2.0.0: 860 | version "2.0.0" 861 | resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" 862 | integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= 863 | 864 | which@1.3.1, which@^1.1.1: 865 | version "1.3.1" 866 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" 867 | integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== 868 | dependencies: 869 | isexe "^2.0.0" 870 | 871 | wide-align@1.1.3: 872 | version "1.1.3" 873 | resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" 874 | integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== 875 | dependencies: 876 | string-width "^1.0.2 || 2" 877 | 878 | wordwrap@^1.0.0, wordwrap@~1.0.0: 879 | version "1.0.0" 880 | resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" 881 | integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= 882 | 883 | wordwrap@~0.0.2: 884 | version "0.0.3" 885 | resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" 886 | integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= 887 | 888 | wrap-ansi@^5.1.0: 889 | version "5.1.0" 890 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" 891 | integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== 892 | dependencies: 893 | ansi-styles "^3.2.0" 894 | string-width "^3.0.0" 895 | strip-ansi "^5.0.0" 896 | 897 | wrappy@1: 898 | version "1.0.2" 899 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 900 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 901 | 902 | y18n@^4.0.0: 903 | version "4.0.0" 904 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" 905 | integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== 906 | 907 | yargs-parser@13.1.1, yargs-parser@^13.1.1: 908 | version "13.1.1" 909 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" 910 | integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== 911 | dependencies: 912 | camelcase "^5.0.0" 913 | decamelize "^1.2.0" 914 | 915 | yargs-unparser@1.6.0: 916 | version "1.6.0" 917 | resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f" 918 | integrity sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw== 919 | dependencies: 920 | flat "^4.1.0" 921 | lodash "^4.17.15" 922 | yargs "^13.3.0" 923 | 924 | yargs@13.3.0, yargs@^13.3.0: 925 | version "13.3.0" 926 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" 927 | integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== 928 | dependencies: 929 | cliui "^5.0.0" 930 | find-up "^3.0.0" 931 | get-caller-file "^2.0.1" 932 | require-directory "^2.1.1" 933 | require-main-filename "^2.0.0" 934 | set-blocking "^2.0.0" 935 | string-width "^3.0.0" 936 | which-module "^2.0.0" 937 | y18n "^4.0.0" 938 | yargs-parser "^13.1.1" 939 | --------------------------------------------------------------------------------