From 2222883d1d13da1c10b4df2e6439ed645e7805be Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Tue, 25 Jul 2017 16:24:50 +0200 Subject: [PATCH 01/35] Replace deprecated fs-promise with fs-extra --- file-cache.js | 2 +- file-cache.js.flow | 2 +- file-cache.js.map | 2 +- index.js | 2 +- index.js.flow | 2 +- index.js.map | 2 +- package-lock.json | 62 ++++++++++------------------------------------ package.json | 2 +- 8 files changed, 20 insertions(+), 56 deletions(-) diff --git a/file-cache.js b/file-cache.js index 7e46b3d..de6c2c4 100644 --- a/file-cache.js +++ b/file-cache.js @@ -1,2 +1,2 @@ -'use strict';var _regenerator=require('babel-runtime/regenerator');var _regenerator2=_interopRequireDefault(_regenerator);var _asyncToGenerator2=require('babel-runtime/helpers/asyncToGenerator');var _asyncToGenerator3=_interopRequireDefault(_asyncToGenerator2);var _getPrototypeOf=require('babel-runtime/core-js/object/get-prototype-of');var _getPrototypeOf2=_interopRequireDefault(_getPrototypeOf);var _possibleConstructorReturn2=require('babel-runtime/helpers/possibleConstructorReturn');var _possibleConstructorReturn3=_interopRequireDefault(_possibleConstructorReturn2);var _inherits2=require('babel-runtime/helpers/inherits');var _inherits3=_interopRequireDefault(_inherits2);var _classCallCheck2=require('babel-runtime/helpers/classCallCheck');var _classCallCheck3=_interopRequireDefault(_classCallCheck2);var _createClass2=require('babel-runtime/helpers/createClass');var _createClass3=_interopRequireDefault(_createClass2);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}var crypto=require('crypto');var EventEmitter=require('events').EventEmitter;var fs=require('fs-promise');var path=require('path');var FileCacheStore=function(){function FileCacheStore(){(0,_classCallCheck3.default)(this,FileCacheStore);this._contents={};}(0,_createClass3.default)(FileCacheStore,[{key:'store',value:function store(value){this._contents=value;return this;}},{key:'set',value:function set(key,value){this._contents[key]=value;return this;}},{key:'contents',get:function get(){return this._contents;}}]);return FileCacheStore;}();var FileCache=function(_EventEmitter){(0,_inherits3.default)(FileCache,_EventEmitter);function FileCache(filePath,cacheName,cacheDir){(0,_classCallCheck3.default)(this,FileCache);var _this=(0,_possibleConstructorReturn3.default)(this,(FileCache.__proto__||(0,_getPrototypeOf2.default)(FileCache)).call(this));_this.filePath=filePath;_this.cacheName=cacheName;_this.cacheDir=cacheDir;_this.isCleaning=false;return _this;}(0,_createClass3.default)(FileCache,[{key:'_fileExists',value:function _fileExists(path){try{fs.statSync(path);return true;}catch(err){return false;}}},{key:'get',value:function get(){if(this._fileExists(this.filePath)){var eventResult=new FileCacheStore();var file=fs.readFileSync(this.filePath,'utf8');var hash=crypto.createHash('sha1').update(file,'utf8').digest('hex');if(!this.cacheDir){this.emit('change',eventResult,file,hash);return eventResult.contents;}var cachePath=path.join(this.cacheDir,this.cacheName,hash);if(this._fileExists(cachePath)){return fs.readJsonSync(cachePath,{throws:false});}fs.ensureDirSync(path.dirname(cachePath));this.emit('change',eventResult,file,hash);fs.writeJsonSync(cachePath,eventResult.contents);return eventResult.contents;}return null;}},{key:'clearCache',value:function(){var _ref=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(){return _regenerator2.default.wrap(function _callee$(_context){while(1){switch(_context.prev=_context.next){case 0:if(this.cacheDir){_context.next=2;break;}return _context.abrupt('return');case 2:return _context.abrupt('return',fs.emptyDir(path.join(this.cacheDir,this.cacheName)));case 3:case'end':return _context.stop();}}},_callee,this);}));function clearCache(){return _ref.apply(this,arguments);}return clearCache;}()},{key:'clearCacheSync',value:function clearCacheSync(){if(!this.cacheDir){return;}return fs.emptyDirSync(path.join(this.cacheDir,this.cacheName));}}]);return FileCache;}(EventEmitter);module.exports=FileCache; +'use strict';var _regenerator=require('babel-runtime/regenerator');var _regenerator2=_interopRequireDefault(_regenerator);var _asyncToGenerator2=require('babel-runtime/helpers/asyncToGenerator');var _asyncToGenerator3=_interopRequireDefault(_asyncToGenerator2);var _getPrototypeOf=require('babel-runtime/core-js/object/get-prototype-of');var _getPrototypeOf2=_interopRequireDefault(_getPrototypeOf);var _possibleConstructorReturn2=require('babel-runtime/helpers/possibleConstructorReturn');var _possibleConstructorReturn3=_interopRequireDefault(_possibleConstructorReturn2);var _inherits2=require('babel-runtime/helpers/inherits');var _inherits3=_interopRequireDefault(_inherits2);var _classCallCheck2=require('babel-runtime/helpers/classCallCheck');var _classCallCheck3=_interopRequireDefault(_classCallCheck2);var _createClass2=require('babel-runtime/helpers/createClass');var _createClass3=_interopRequireDefault(_createClass2);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}var crypto=require('crypto');var EventEmitter=require('events').EventEmitter;var fs=require('fs-extra');var path=require('path');var FileCacheStore=function(){function FileCacheStore(){(0,_classCallCheck3.default)(this,FileCacheStore);this._contents={};}(0,_createClass3.default)(FileCacheStore,[{key:'store',value:function store(value){this._contents=value;return this;}},{key:'set',value:function set(key,value){this._contents[key]=value;return this;}},{key:'contents',get:function get(){return this._contents;}}]);return FileCacheStore;}();var FileCache=function(_EventEmitter){(0,_inherits3.default)(FileCache,_EventEmitter);function FileCache(filePath,cacheName,cacheDir){(0,_classCallCheck3.default)(this,FileCache);var _this=(0,_possibleConstructorReturn3.default)(this,(FileCache.__proto__||(0,_getPrototypeOf2.default)(FileCache)).call(this));_this.filePath=filePath;_this.cacheName=cacheName;_this.cacheDir=cacheDir;_this.isCleaning=false;return _this;}(0,_createClass3.default)(FileCache,[{key:'_fileExists',value:function _fileExists(path){try{fs.statSync(path);return true;}catch(err){return false;}}},{key:'get',value:function get(){if(this._fileExists(this.filePath)){var eventResult=new FileCacheStore();var file=fs.readFileSync(this.filePath,'utf8');var hash=crypto.createHash('sha1').update(file,'utf8').digest('hex');if(!this.cacheDir){this.emit('change',eventResult,file,hash);return eventResult.contents;}var cachePath=path.join(this.cacheDir,this.cacheName,hash);if(this._fileExists(cachePath)){return fs.readJsonSync(cachePath,{throws:false});}fs.ensureDirSync(path.dirname(cachePath));this.emit('change',eventResult,file,hash);fs.writeJsonSync(cachePath,eventResult.contents);return eventResult.contents;}return null;}},{key:'clearCache',value:function(){var _ref=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(){return _regenerator2.default.wrap(function _callee$(_context){while(1){switch(_context.prev=_context.next){case 0:if(this.cacheDir){_context.next=2;break;}return _context.abrupt('return');case 2:return _context.abrupt('return',fs.emptyDir(path.join(this.cacheDir,this.cacheName)));case 3:case'end':return _context.stop();}}},_callee,this);}));function clearCache(){return _ref.apply(this,arguments);}return clearCache;}()},{key:'clearCacheSync',value:function clearCacheSync(){if(!this.cacheDir){return;}return fs.emptyDirSync(path.join(this.cacheDir,this.cacheName));}}]);return FileCache;}(EventEmitter);module.exports=FileCache; //# sourceMappingURL=file-cache.js.map diff --git a/file-cache.js.flow b/file-cache.js.flow index 9959602..b03c05c 100644 --- a/file-cache.js.flow +++ b/file-cache.js.flow @@ -2,7 +2,7 @@ const crypto = require('crypto'); const EventEmitter = require('events').EventEmitter; -const fs = require('fs-promise'); +const fs = require('fs-extra'); const path = require('path'); /** diff --git a/file-cache.js.map b/file-cache.js.map index 7d63673..6f83ab3 100644 --- a/file-cache.js.map +++ b/file-cache.js.map @@ -1 +1 @@ -{"version":3,"sources":["file-cache.js.flow"],"names":["crypto","require","EventEmitter","fs","path","FileCacheStore","_contents","value","key","FileCache","filePath","cacheName","cacheDir","isCleaning","statSync","err","_fileExists","eventResult","file","readFileSync","hash","createHash","update","digest","emit","contents","cachePath","join","readJsonSync","throws","ensureDirSync","dirname","writeJsonSync","emptyDir","emptyDirSync","module","exports"],"mappings":"s/BAEA,GAAMA,QAASC,QAAQ,QAAR,CAAf,CACA,GAAMC,cAAeD,QAAQ,QAAR,EAAkBC,YAAvC,CACA,GAAMC,IAAKF,QAAQ,YAAR,CAAX,CACA,GAAMG,MAAOH,QAAQ,MAAR,CAAb,C,GAMMI,e,YAWF,yBAAc,mDACV,KAAKC,SAAL,CAAiB,EAAjB,CACH,C,4EAeKC,K,CAA6C,CAC/C,KAAKD,SAAL,CAAiBC,KAAjB,CACA,MAAO,KAAP,CACH,C,gCAQGC,G,CAAUD,K,CAA4B,CACtC,KAAKD,SAAL,CAAeE,GAAf,EAAsBD,KAAtB,CACA,MAAO,KAAP,CACH,C,oCAvBc,CACX,MAAO,MAAKD,SAAZ,CACH,C,iCA2BCG,U,yEAaF,mBAAYC,QAAZ,CAA8BC,SAA9B,CAAiDC,QAAjD,CAAmE,gLAG/D,MAAKF,QAAL,CAAgBA,QAAhB,CACA,MAAKC,SAAL,CAAiBA,SAAjB,CACA,MAAKC,QAAL,CAAgBA,QAAhB,CACA,MAAKC,UAAL,CAAkB,KAAlB,CAN+D,aAOlE,C,mFAOWT,I,CAAuB,CAC/B,GAAI,CACAD,GAAGW,QAAH,CAAYV,IAAZ,EACA,MAAO,KAAP,CACH,CAAC,MAAOW,GAAP,CAAY,CACV,MAAO,MAAP,CACH,CACJ,C,iCAMgC,CAC7B,GAAI,KAAKC,WAAL,CAAiB,KAAKN,QAAtB,CAAJ,CAAqC,CAEjC,GAAIO,aAAc,GAAIZ,eAAJ,EAAlB,CAGA,GAAIa,MAAOf,GAAGgB,YAAH,CAAgB,KAAKT,QAArB,CAA+B,MAA/B,CAAX,CAGA,GAAIU,MAAOpB,OAAOqB,UAAP,CAAkB,MAAlB,EAA0BC,MAA1B,CAAiCJ,IAAjC,CAAuC,MAAvC,EAA+CK,MAA/C,CAAsD,KAAtD,CAAX,CAGA,GAAI,CAAC,KAAKX,QAAV,CAAoB,CAChB,KAAKY,IAAL,CAAU,QAAV,CAAoBP,WAApB,CAAiCC,IAAjC,CAAuCE,IAAvC,EACA,MAAOH,aAAYQ,QAAnB,CACH,CAGD,GAAIC,WAAYtB,KAAKuB,IAAL,CAAU,KAAKf,QAAf,CAAyB,KAAKD,SAA9B,CAAyCS,IAAzC,CAAhB,CAGA,GAAI,KAAKJ,WAAL,CAAiBU,SAAjB,CAAJ,CAAiC,CAC7B,MAAOvB,IAAGyB,YAAH,CAAgBF,SAAhB,CAA2B,CAACG,OAAQ,KAAT,CAA3B,CAAP,CACH,CAGD1B,GAAG2B,aAAH,CAAiB1B,KAAK2B,OAAL,CAAaL,SAAb,CAAjB,EAGA,KAAKF,IAAL,CAAU,QAAV,CAAoBP,WAApB,CAAiCC,IAAjC,CAAuCE,IAAvC,EAGAjB,GAAG6B,aAAH,CAAiBN,SAAjB,CAA4BT,YAAYQ,QAAxC,EACA,MAAOR,aAAYQ,QAAnB,CACH,CAED,MAAO,KAAP,CACH,C,gPAQQ,KAAKb,Q,iGAIHT,GAAG8B,QAAH,CAAY7B,KAAKuB,IAAL,CAAU,KAAKf,QAAf,CAAyB,KAAKD,SAA9B,CAAZ,C,qMAOM,CACb,GAAI,CAAC,KAAKC,QAAV,CAAoB,CAChB,OACH,CAED,MAAOT,IAAG+B,YAAH,CAAgB9B,KAAKuB,IAAL,CAAU,KAAKf,QAAf,CAAyB,KAAKD,SAA9B,CAAhB,CAAP,CACH,C,uBAtGmBT,Y,EAyGxBiC,OAAOC,OAAP,CAAiB3B,SAAjB","file":"file-cache.js","sourcesContent":["// @flow\n\nconst crypto = require('crypto');\nconst EventEmitter = require('events').EventEmitter;\nconst fs = require('fs-promise');\nconst path = require('path');\n\n/**\n * FileCache\n * Simple in-memory key/value pair storage to store event listener results\n */\nclass FileCacheStore {\n /**\n * Cache contents\n * @type {Object|Array.}\n */\n _contents: Object|Array;\n\n /**\n * FileCacheStore constructor\n * @constructor\n */\n constructor() {\n this._contents = {};\n }\n\n /**\n * Get cache contents\n * @return {Object|Array.}\n */\n get contents() {\n return this._contents;\n }\n\n /**\n * Set cache contents to value\n * @param {Object|Arrray.} value\n * @return {FileCacheStore}\n */\n store(value: Object|Array): FileCacheStore {\n this._contents = value;\n return this;\n }\n\n /**\n * Set a cache value\n * @param {any} key Key\n * @param {any} value Value\n * @return {FileCacheStore}\n */\n set(key: any, value: any): FileCacheStore {\n this._contents[key] = value;\n return this;\n }\n}\n\n/**\n * FileCache\n */\nclass FileCache extends EventEmitter {\n filePath: string;\n cacheName: string;\n cacheDir: string;\n isCleaning: boolean;\n\n /**\n * FileCache constructor\n * @param {string} filePath File to process and check for changes\n * @param {string} cacheName Unique name for cache directory\n * @param {string} cacheDir Cache base directory\n * @constructor\n */\n constructor(filePath: string, cacheName: string, cacheDir: string) {\n super();\n\n this.filePath = filePath;\n this.cacheName = cacheName;\n this.cacheDir = cacheDir;\n this.isCleaning = false;\n }\n\n /**\n * Check if file exists\n * @param {string} path\n * @return {boolean}\n */\n _fileExists(path: string): boolean {\n try {\n fs.statSync(path);\n return true;\n } catch (err) {\n return false;\n }\n }\n\n /**\n * Get cached contents\n * @return {Object|Array.|null}\n */\n get(): Object|Array|null {\n if (this._fileExists(this.filePath)) {\n // Create simple in-memory store for event listener results\n let eventResult = new FileCacheStore();\n\n // Read file\n let file = fs.readFileSync(this.filePath, 'utf8');\n\n // Calculate file hash\n let hash = crypto.createHash('sha1').update(file, 'utf8').digest('hex');\n\n // Always call callback when cache dir is not set\n if (!this.cacheDir) {\n this.emit('change', eventResult, file, hash);\n return eventResult.contents;\n }\n\n // Get cache path\n let cachePath = path.join(this.cacheDir, this.cacheName, hash);\n\n // Return cached data if found\n if (this._fileExists(cachePath)) {\n return fs.readJsonSync(cachePath, {throws: false});\n }\n\n // Create cache directory if it doesn't exist\n fs.ensureDirSync(path.dirname(cachePath));\n\n // Get processed data\n this.emit('change', eventResult, file, hash);\n\n // Write cache\n fs.writeJsonSync(cachePath, eventResult.contents);\n return eventResult.contents;\n }\n\n return null;\n }\n\n /**\n * Clear cache\n * @async\n * @return {Promise}\n */\n async clearCache() {\n if (!this.cacheDir) {\n return;\n }\n\n return fs.emptyDir(path.join(this.cacheDir, this.cacheName));\n }\n\n /**\n * Clear cache synchronously\n * @return {void}\n */\n clearCacheSync() {\n if (!this.cacheDir) {\n return;\n }\n\n return fs.emptyDirSync(path.join(this.cacheDir, this.cacheName));\n }\n}\n\nmodule.exports = FileCache;\n"]} \ No newline at end of file +{"version":3,"sources":["file-cache.js.flow"],"names":["crypto","require","EventEmitter","fs","path","FileCacheStore","_contents","value","key","FileCache","filePath","cacheName","cacheDir","isCleaning","statSync","err","_fileExists","eventResult","file","readFileSync","hash","createHash","update","digest","emit","contents","cachePath","join","readJsonSync","throws","ensureDirSync","dirname","writeJsonSync","emptyDir","emptyDirSync","module","exports"],"mappings":"s/BAEA,GAAMA,QAASC,QAAQ,QAAR,CAAf,CACA,GAAMC,cAAeD,QAAQ,QAAR,EAAkBC,YAAvC,CACA,GAAMC,IAAKF,QAAQ,UAAR,CAAX,CACA,GAAMG,MAAOH,QAAQ,MAAR,CAAb,C,GAMMI,e,YAWF,yBAAc,mDACV,KAAKC,SAAL,CAAiB,EAAjB,CACH,C,4EAeKC,K,CAA6C,CAC/C,KAAKD,SAAL,CAAiBC,KAAjB,CACA,MAAO,KAAP,CACH,C,gCAQGC,G,CAAUD,K,CAA4B,CACtC,KAAKD,SAAL,CAAeE,GAAf,EAAsBD,KAAtB,CACA,MAAO,KAAP,CACH,C,oCAvBc,CACX,MAAO,MAAKD,SAAZ,CACH,C,iCA2BCG,U,yEAaF,mBAAYC,QAAZ,CAA8BC,SAA9B,CAAiDC,QAAjD,CAAmE,gLAG/D,MAAKF,QAAL,CAAgBA,QAAhB,CACA,MAAKC,SAAL,CAAiBA,SAAjB,CACA,MAAKC,QAAL,CAAgBA,QAAhB,CACA,MAAKC,UAAL,CAAkB,KAAlB,CAN+D,aAOlE,C,mFAOWT,I,CAAuB,CAC/B,GAAI,CACAD,GAAGW,QAAH,CAAYV,IAAZ,EACA,MAAO,KAAP,CACH,CAAC,MAAOW,GAAP,CAAY,CACV,MAAO,MAAP,CACH,CACJ,C,iCAMgC,CAC7B,GAAI,KAAKC,WAAL,CAAiB,KAAKN,QAAtB,CAAJ,CAAqC,CAEjC,GAAIO,aAAc,GAAIZ,eAAJ,EAAlB,CAGA,GAAIa,MAAOf,GAAGgB,YAAH,CAAgB,KAAKT,QAArB,CAA+B,MAA/B,CAAX,CAGA,GAAIU,MAAOpB,OAAOqB,UAAP,CAAkB,MAAlB,EAA0BC,MAA1B,CAAiCJ,IAAjC,CAAuC,MAAvC,EAA+CK,MAA/C,CAAsD,KAAtD,CAAX,CAGA,GAAI,CAAC,KAAKX,QAAV,CAAoB,CAChB,KAAKY,IAAL,CAAU,QAAV,CAAoBP,WAApB,CAAiCC,IAAjC,CAAuCE,IAAvC,EACA,MAAOH,aAAYQ,QAAnB,CACH,CAGD,GAAIC,WAAYtB,KAAKuB,IAAL,CAAU,KAAKf,QAAf,CAAyB,KAAKD,SAA9B,CAAyCS,IAAzC,CAAhB,CAGA,GAAI,KAAKJ,WAAL,CAAiBU,SAAjB,CAAJ,CAAiC,CAC7B,MAAOvB,IAAGyB,YAAH,CAAgBF,SAAhB,CAA2B,CAACG,OAAQ,KAAT,CAA3B,CAAP,CACH,CAGD1B,GAAG2B,aAAH,CAAiB1B,KAAK2B,OAAL,CAAaL,SAAb,CAAjB,EAGA,KAAKF,IAAL,CAAU,QAAV,CAAoBP,WAApB,CAAiCC,IAAjC,CAAuCE,IAAvC,EAGAjB,GAAG6B,aAAH,CAAiBN,SAAjB,CAA4BT,YAAYQ,QAAxC,EACA,MAAOR,aAAYQ,QAAnB,CACH,CAED,MAAO,KAAP,CACH,C,gPAQQ,KAAKb,Q,iGAIHT,GAAG8B,QAAH,CAAY7B,KAAKuB,IAAL,CAAU,KAAKf,QAAf,CAAyB,KAAKD,SAA9B,CAAZ,C,qMAOM,CACb,GAAI,CAAC,KAAKC,QAAV,CAAoB,CAChB,OACH,CAED,MAAOT,IAAG+B,YAAH,CAAgB9B,KAAKuB,IAAL,CAAU,KAAKf,QAAf,CAAyB,KAAKD,SAA9B,CAAhB,CAAP,CACH,C,uBAtGmBT,Y,EAyGxBiC,OAAOC,OAAP,CAAiB3B,SAAjB","file":"file-cache.js","sourcesContent":["// @flow\n\nconst crypto = require('crypto');\nconst EventEmitter = require('events').EventEmitter;\nconst fs = require('fs-extra');\nconst path = require('path');\n\n/**\n * FileCache\n * Simple in-memory key/value pair storage to store event listener results\n */\nclass FileCacheStore {\n /**\n * Cache contents\n * @type {Object|Array.}\n */\n _contents: Object|Array;\n\n /**\n * FileCacheStore constructor\n * @constructor\n */\n constructor() {\n this._contents = {};\n }\n\n /**\n * Get cache contents\n * @return {Object|Array.}\n */\n get contents() {\n return this._contents;\n }\n\n /**\n * Set cache contents to value\n * @param {Object|Arrray.} value\n * @return {FileCacheStore}\n */\n store(value: Object|Array): FileCacheStore {\n this._contents = value;\n return this;\n }\n\n /**\n * Set a cache value\n * @param {any} key Key\n * @param {any} value Value\n * @return {FileCacheStore}\n */\n set(key: any, value: any): FileCacheStore {\n this._contents[key] = value;\n return this;\n }\n}\n\n/**\n * FileCache\n */\nclass FileCache extends EventEmitter {\n filePath: string;\n cacheName: string;\n cacheDir: string;\n isCleaning: boolean;\n\n /**\n * FileCache constructor\n * @param {string} filePath File to process and check for changes\n * @param {string} cacheName Unique name for cache directory\n * @param {string} cacheDir Cache base directory\n * @constructor\n */\n constructor(filePath: string, cacheName: string, cacheDir: string) {\n super();\n\n this.filePath = filePath;\n this.cacheName = cacheName;\n this.cacheDir = cacheDir;\n this.isCleaning = false;\n }\n\n /**\n * Check if file exists\n * @param {string} path\n * @return {boolean}\n */\n _fileExists(path: string): boolean {\n try {\n fs.statSync(path);\n return true;\n } catch (err) {\n return false;\n }\n }\n\n /**\n * Get cached contents\n * @return {Object|Array.|null}\n */\n get(): Object|Array|null {\n if (this._fileExists(this.filePath)) {\n // Create simple in-memory store for event listener results\n let eventResult = new FileCacheStore();\n\n // Read file\n let file = fs.readFileSync(this.filePath, 'utf8');\n\n // Calculate file hash\n let hash = crypto.createHash('sha1').update(file, 'utf8').digest('hex');\n\n // Always call callback when cache dir is not set\n if (!this.cacheDir) {\n this.emit('change', eventResult, file, hash);\n return eventResult.contents;\n }\n\n // Get cache path\n let cachePath = path.join(this.cacheDir, this.cacheName, hash);\n\n // Return cached data if found\n if (this._fileExists(cachePath)) {\n return fs.readJsonSync(cachePath, {throws: false});\n }\n\n // Create cache directory if it doesn't exist\n fs.ensureDirSync(path.dirname(cachePath));\n\n // Get processed data\n this.emit('change', eventResult, file, hash);\n\n // Write cache\n fs.writeJsonSync(cachePath, eventResult.contents);\n return eventResult.contents;\n }\n\n return null;\n }\n\n /**\n * Clear cache\n * @async\n * @return {Promise}\n */\n async clearCache() {\n if (!this.cacheDir) {\n return;\n }\n\n return fs.emptyDir(path.join(this.cacheDir, this.cacheName));\n }\n\n /**\n * Clear cache synchronously\n * @return {void}\n */\n clearCacheSync() {\n if (!this.cacheDir) {\n return;\n }\n\n return fs.emptyDirSync(path.join(this.cacheDir, this.cacheName));\n }\n}\n\nmodule.exports = FileCache;\n"]} \ No newline at end of file diff --git a/index.js b/index.js index 24f016e..845c9d6 100644 --- a/index.js +++ b/index.js @@ -1,2 +1,2 @@ -'use strict';var _promise=require('babel-runtime/core-js/promise');var _promise2=_interopRequireDefault(_promise);var _regenerator=require('babel-runtime/regenerator');var _regenerator2=_interopRequireDefault(_regenerator);var _asyncToGenerator2=require('babel-runtime/helpers/asyncToGenerator');var _asyncToGenerator3=_interopRequireDefault(_asyncToGenerator2);var _stringify=require('babel-runtime/core-js/json/stringify');var _stringify2=_interopRequireDefault(_stringify);var _assign=require('babel-runtime/core-js/object/assign');var _assign2=_interopRequireDefault(_assign);var _classCallCheck2=require('babel-runtime/helpers/classCallCheck');var _classCallCheck3=_interopRequireDefault(_classCallCheck2);var _createClass2=require('babel-runtime/helpers/createClass');var _createClass3=_interopRequireDefault(_createClass2);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}var CacheConf=require('cache-conf');var Conf=require('conf');var fs=require('fs-promise');var Fuse=require('fuse.js');var got=require('got');var moment=require('moment');var notifier=require('node-notifier');var os=require('os');var path=require('path');var semver=require('semver');var FileCache=require('./file-cache');var updater=require('./updater');var Hugo=function(){function Hugo(){(0,_classCallCheck3.default)(this,Hugo);this._fuseDefaults={keys:['title'],threshold:0.4};this._options={useTmpCache:true,checkUpdates:true,updateSource:'packal',updateInterval:moment.duration(1,'days'),updateNotification:true,updateItem:true};this._outputBuffer={};this.config=new Conf({cwd:this.workflowMeta.data});this.cache=new CacheConf({configName:'cache',cwd:this.workflowMeta.cache,version:this.workflowMeta.version});}(0,_createClass3.default)(Hugo,[{key:'addItem',value:function addItem(item){if(!this._outputBuffer.items){this._outputBuffer.items=[];}if(!item.title){if(this.alfredMeta.debug===true){console.error('Item skipped, missing title.');}return this;}if(item.arg&&typeof item.arg==='object'){var arg=item.arg.arg;var variables=item.arg.variables||{};if(semver.gte(this.alfredMeta.version,'3.4.1')){delete item.arg;if(arg){item.arg=arg;}item.variables=(0,_assign2.default)({},item.variables,variables);}else{if(item.variables&&typeof item.variables==='object'){variables=(0,_assign2.default)({},variables,item.variables);delete item.variables;}item.arg=(0,_stringify2.default)({alfredworkflow:{arg:arg,variables:variables}});}}else if(item.variables&&typeof item.variables==='object'&&semver.lt(this.alfredMeta.version,'3.4.1')){item.arg=(0,_stringify2.default)({alfredworkflow:{arg:item.arg,variables:item.variables}});delete item.variables;}this._outputBuffer.items.push(item);return this;}},{key:'addItems',value:function addItems(items){var _this=this;items.map(function(item){_this.addItem(item);return item;});return this;}},{key:'addVariable',value:function addVariable(key,value){if(!this._outputBuffer.variables){this._outputBuffer.variables={};}this._outputBuffer.variables[key]=value;return this;}},{key:'addVariables',value:function addVariables(variables){if(!this._outputBuffer.variables){this._outputBuffer.variables=variables;return this;}this._outputBuffer.variables=(0,_assign2.default)({},this._outputBuffer.variables,variables);return this;}},{key:'getVariable',value:function getVariable(key){if(!this._outputBuffer.variables){return null;}return this._outputBuffer.variables[key]||null;}},{key:'getVariables',value:function getVariables(){return this._outputBuffer.variables||{};}},{key:'getItemVariable',value:function getItemVariable(item,key){if(semver.gte(this.alfredMeta.version,'3.4.1')){if(item.variables){return item.variables[key]||null;}}else if(item.arg){try{var arg={};var variables={};if(typeof item.arg==='string'){arg=JSON.parse(item.arg);}if(arg.alfredworkflow){variables=arg.alfredworkflow.variables||{};}return variables[key]||null;}catch(e){}}return null;}},{key:'getItemVariables',value:function getItemVariables(item){if(semver.gte(this.alfredMeta.version,'3.4.1')){return item.variables||{};}else if(item.arg){try{var arg={};if(typeof item.arg==='string'){arg=JSON.parse(item.arg);}if(arg.alfredworkflow){return arg.alfredworkflow.variables||{};}return arg.variables||{};}catch(e){}}return{};}},{key:'action',value:function action(keyword,callback){var query=process.argv[2];if(query&&callback&&query===keyword){query=process.argv[3]||'';callback(query);}return this;}},{key:'cacheFile',value:function cacheFile(filePath,cacheName){return new FileCache(filePath,cacheName,this.workflowMeta.cache);}},{key:'checkUpdates',value:function(){var _ref=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(){var _this2=this;return _regenerator2.default.wrap(function _callee$(_context){while(1){switch(_context.prev=_context.next){case 0:if(!(this._options.checkUpdates!==true||this._options.updateItem!==true&&this._options.updateNotification!==true)){_context.next=2;break;}return _context.abrupt('return');case 2:_context.next=4;return updater.checkUpdates(this._options.updateSource,this._options.updateInterval).catch(function(err){console.error(err);return;}).then(function(result){if(!result){return;}var current=_this2.workflowMeta.version;var latest=result.version;if(!semver.valid(current)){console.error(`Version ${current} is not a valid version number.`);return;}if(!semver.valid(latest)){console.error(`Could not determine latest version number.`);return;}if(semver.gt(latest,current)){if(result.checkedOnline===true&&_this2._options.updateNotification===true){_this2.notify({message:`Workflow version ${latest} available. Current version: ${current}.`});}if(_this2._options.updateItem===true){_this2.addItem({title:`Workflow update available!`,subtitle:`Version ${latest} is available. Current version: ${current}.`,icon:_this2.workflowMeta.icon,arg:result.url,variables:{task:'wfUpdate'}});}}});case 4:case'end':return _context.stop();}}},_callee,this);}));function checkUpdates(){return _ref.apply(this,arguments);}return checkUpdates;}()},{key:'clearCache',value:function(){var _ref2=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2(){return _regenerator2.default.wrap(function _callee2$(_context2){while(1){switch(_context2.prev=_context2.next){case 0:if(!this.workflowMeta.cache){_context2.next=2;break;}return _context2.abrupt('return',fs.emptyDir(this.workflowMeta.cache));case 2:case'end':return _context2.stop();}}},_callee2,this);}));function clearCache(){return _ref2.apply(this,arguments);}return clearCache;}()},{key:'clearCacheSync',value:function clearCacheSync(){if(this.workflowMeta.cache){return fs.emptyDirSync(this.workflowMeta.cache);}}},{key:'filterItems',value:function filterItems(query){var options=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};options=(0,_assign2.default)({},this._fuseDefaults,options);if(query.length===0){return this;}var fuse=new Fuse(this._outputBuffer.items,options);this._outputBuffer.items=fuse.search(query)||[];return this;}},{key:'options',value:function options(_options){var cacheDirChanged='useTmpCache'in _options&&_options.useTmpCache!==this._options.useTmpCache;if(_options.updateInterval&&!moment.isDuration(_options.updateInterval)){if(_options.updateInterval<1){delete _options.updateInterval;}else{_options.updateInterval=moment.duration(_options.updateInterval,'seconds')||moment.duration(1,'days');}}this._options=(0,_assign2.default)({},this._options,_options);if(cacheDirChanged){this.cache=new CacheConf({configName:'cache',cwd:this.workflowMeta.cache,version:this.workflowMeta.version});}return this;}},{key:'matches',value:function matches(candidates,query){var options=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};options=(0,_assign2.default)({},this._fuseDefaults,options);if(query.length===0){return candidates;}var fuse=new Fuse(candidates,options);return fuse.search(query)||[];}},{key:'notify',value:function(){var _ref3=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee3(options){var _this3=this;return _regenerator2.default.wrap(function _callee3$(_context3){while(1){switch(_context3.prev=_context3.next){case 0:return _context3.abrupt('return',new _promise2.default(function(resolve,reject){var defaults={title:('Alfred '+_this3.workflowMeta.name).trim(),sender:'com.runningwithcrayons.Alfred-3',contentImage:_this3.workflowMeta.icon};options=(0,_assign2.default)({},defaults,options);notifier.notify(options,function(err,response){if(err){reject(err);return;}resolve(response);});}));case 1:case'end':return _context3.stop();}}},_callee3,this);}));function notify(_x3){return _ref3.apply(this,arguments);}return notify;}()},{key:'rerun',value:function rerun(value){value=parseFloat(value);if(value&&value>0.1&&value<=5){this._rerun=value;}return this;}},{key:'feedback',value:function(){var _ref4=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee4(){var output;return _regenerator2.default.wrap(function _callee4$(_context4){while(1){switch(_context4.prev=_context4.next){case 0:if(this._rerun){this._outputBuffer.rerun=this._rerun;}if(!(this._options.checkUpdates===true)){_context4.next=4;break;}_context4.next=4;return this.checkUpdates().catch(function(){});case 4:output=this._outputBuffer;console.log((0,_stringify2.default)(output,null,'\t'));this._outputBuffer={};return _context4.abrupt('return',output);case 8:case'end':return _context4.stop();}}},_callee4,this);}));function feedback(){return _ref4.apply(this,arguments);}return feedback;}()},{key:'fetch',value:function(){var _ref5=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee5(url){var _this4=this;var options=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var cacheAge=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var cacheResult;return _regenerator2.default.wrap(function _callee5$(_context5){while(1){switch(_context5.prev=_context5.next){case 0:options=(0,_assign2.default)({},{json:true},options);if(!(cacheAge&&cacheAge>0)){_context5.next=5;break;}cacheResult=this.cache.get(url);if(!cacheResult){_context5.next=5;break;}return _context5.abrupt('return',cacheResult);case 5:return _context5.abrupt('return',got(url,options).then(function(response){if(cacheAge&&cacheAge>0){_this4.cache.set(url,response.body,{maxAge:cacheAge*1000});}return response.body;}));case 6:case'end':return _context5.stop();}}},_callee5,this);}));function fetch(_x6){return _ref5.apply(this,arguments);}return fetch;}()},{key:'alfredMeta',get:function get(){var version=process.env.alfred_version||'0.0.0';if(!semver.valid(version)){version+='.0';if(!semver.valid(version)&&process.env.alfred_debug==='1'){console.error(`Invalid Alfred version: ${version}`);version='0.0.0';}}var data={version:version,theme:process.env.alfred_theme,themeFile:'',themeBackground:process.env.alfred_theme_background,themeSelectionBackground:process.env.alfred_theme_selection_background,themeSubtext:parseFloat(process.env.alfred_theme_subtext),preferences:process.env.alfred_preferences,preferencesLocalHash:process.env.alfred_preferences_localhash,debug:process.env.alfred_debug==='1'};if(process.env.HOME&&data.theme){var homedir=process.env.HOME||'';var themeFile=path.resolve(homedir,'Library','Application Support','Alfred '+semver.major(version),'Alfred.alfredpreferences','themes',data.theme,'theme.json');try{fs.statSync(themeFile);data.themeFile=themeFile;}catch(e){if(process.env.alfred_debug==='1'){console.error(`Could not find theme file "${themeFile}"`);}}}return data;}},{key:'alfredTheme',get:function get(){var themeFile=this.alfredMeta.themeFile;if(!themeFile){return{};}return fs.readJsonSync(themeFile,{throws:false})||{};}},{key:'input',get:function get(){if(process.argv.length>3){return process.argv[3]||'';}return process.argv[2]||'';}},{key:'itemCount',get:function get(){if(this.outputBuffer&&this.outputBuffer.items){return this.outputBuffer.items.length;}return 0;}},{key:'outputBuffer',get:function get(){return this._outputBuffer;}},{key:'workflowMeta',get:function get(){var cacheDir=process.env.alfred_workflow_cache;var bundleId=process.env.alfred_workflow_bundleid;if(bundleId&&this._options.useTmpCache===true){cacheDir=path.resolve(path.join(os.tmpdir(),bundleId));}return{name:process.env.alfred_workflow_name,version:process.env.alfred_workflow_version,uid:process.env.alfred_workflow_uid,bundleId:bundleId,data:process.env.alfred_workflow_data,cache:cacheDir,icon:path.join(process.cwd(),'icon.png')};}}]);return Hugo;}();module.exports=new Hugo(); +'use strict';var _promise=require('babel-runtime/core-js/promise');var _promise2=_interopRequireDefault(_promise);var _regenerator=require('babel-runtime/regenerator');var _regenerator2=_interopRequireDefault(_regenerator);var _asyncToGenerator2=require('babel-runtime/helpers/asyncToGenerator');var _asyncToGenerator3=_interopRequireDefault(_asyncToGenerator2);var _stringify=require('babel-runtime/core-js/json/stringify');var _stringify2=_interopRequireDefault(_stringify);var _assign=require('babel-runtime/core-js/object/assign');var _assign2=_interopRequireDefault(_assign);var _classCallCheck2=require('babel-runtime/helpers/classCallCheck');var _classCallCheck3=_interopRequireDefault(_classCallCheck2);var _createClass2=require('babel-runtime/helpers/createClass');var _createClass3=_interopRequireDefault(_createClass2);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}var CacheConf=require('cache-conf');var Conf=require('conf');var fs=require('fs-extra');var Fuse=require('fuse.js');var got=require('got');var moment=require('moment');var notifier=require('node-notifier');var os=require('os');var path=require('path');var semver=require('semver');var FileCache=require('./file-cache');var updater=require('./updater');var Hugo=function(){function Hugo(){(0,_classCallCheck3.default)(this,Hugo);this._fuseDefaults={keys:['title'],threshold:0.4};this._options={useTmpCache:true,checkUpdates:true,updateSource:'packal',updateInterval:moment.duration(1,'days'),updateNotification:true,updateItem:true};this._outputBuffer={};this.config=new Conf({cwd:this.workflowMeta.data});this.cache=new CacheConf({configName:'cache',cwd:this.workflowMeta.cache,version:this.workflowMeta.version});}(0,_createClass3.default)(Hugo,[{key:'addItem',value:function addItem(item){if(!this._outputBuffer.items){this._outputBuffer.items=[];}if(!item.title){if(this.alfredMeta.debug===true){console.error('Item skipped, missing title.');}return this;}if(item.arg&&typeof item.arg==='object'){var arg=item.arg.arg;var variables=item.arg.variables||{};if(semver.gte(this.alfredMeta.version,'3.4.1')){delete item.arg;if(arg){item.arg=arg;}item.variables=(0,_assign2.default)({},item.variables,variables);}else{if(item.variables&&typeof item.variables==='object'){variables=(0,_assign2.default)({},variables,item.variables);delete item.variables;}item.arg=(0,_stringify2.default)({alfredworkflow:{arg:arg,variables:variables}});}}else if(item.variables&&typeof item.variables==='object'&&semver.lt(this.alfredMeta.version,'3.4.1')){item.arg=(0,_stringify2.default)({alfredworkflow:{arg:item.arg,variables:item.variables}});delete item.variables;}this._outputBuffer.items.push(item);return this;}},{key:'addItems',value:function addItems(items){var _this=this;items.map(function(item){_this.addItem(item);return item;});return this;}},{key:'addVariable',value:function addVariable(key,value){if(!this._outputBuffer.variables){this._outputBuffer.variables={};}this._outputBuffer.variables[key]=value;return this;}},{key:'addVariables',value:function addVariables(variables){if(!this._outputBuffer.variables){this._outputBuffer.variables=variables;return this;}this._outputBuffer.variables=(0,_assign2.default)({},this._outputBuffer.variables,variables);return this;}},{key:'getVariable',value:function getVariable(key){if(!this._outputBuffer.variables){return null;}return this._outputBuffer.variables[key]||null;}},{key:'getVariables',value:function getVariables(){return this._outputBuffer.variables||{};}},{key:'getItemVariable',value:function getItemVariable(item,key){if(semver.gte(this.alfredMeta.version,'3.4.1')){if(item.variables){return item.variables[key]||null;}}else if(item.arg){try{var arg={};var variables={};if(typeof item.arg==='string'){arg=JSON.parse(item.arg);}if(arg.alfredworkflow){variables=arg.alfredworkflow.variables||{};}return variables[key]||null;}catch(e){}}return null;}},{key:'getItemVariables',value:function getItemVariables(item){if(semver.gte(this.alfredMeta.version,'3.4.1')){return item.variables||{};}else if(item.arg){try{var arg={};if(typeof item.arg==='string'){arg=JSON.parse(item.arg);}if(arg.alfredworkflow){return arg.alfredworkflow.variables||{};}return arg.variables||{};}catch(e){}}return{};}},{key:'action',value:function action(keyword,callback){var query=process.argv[2];if(query&&callback&&query===keyword){query=process.argv[3]||'';callback(query);}return this;}},{key:'cacheFile',value:function cacheFile(filePath,cacheName){return new FileCache(filePath,cacheName,this.workflowMeta.cache);}},{key:'checkUpdates',value:function(){var _ref=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(){var _this2=this;return _regenerator2.default.wrap(function _callee$(_context){while(1){switch(_context.prev=_context.next){case 0:if(!(this._options.checkUpdates!==true||this._options.updateItem!==true&&this._options.updateNotification!==true)){_context.next=2;break;}return _context.abrupt('return');case 2:_context.next=4;return updater.checkUpdates(this._options.updateSource,this._options.updateInterval).catch(function(err){console.error(err);return;}).then(function(result){if(!result){return;}var current=_this2.workflowMeta.version;var latest=result.version;if(!semver.valid(current)){console.error(`Version ${current} is not a valid version number.`);return;}if(!semver.valid(latest)){console.error(`Could not determine latest version number.`);return;}if(semver.gt(latest,current)){if(result.checkedOnline===true&&_this2._options.updateNotification===true){_this2.notify({message:`Workflow version ${latest} available. Current version: ${current}.`});}if(_this2._options.updateItem===true){_this2.addItem({title:`Workflow update available!`,subtitle:`Version ${latest} is available. Current version: ${current}.`,icon:_this2.workflowMeta.icon,arg:result.url,variables:{task:'wfUpdate'}});}}});case 4:case'end':return _context.stop();}}},_callee,this);}));function checkUpdates(){return _ref.apply(this,arguments);}return checkUpdates;}()},{key:'clearCache',value:function(){var _ref2=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2(){return _regenerator2.default.wrap(function _callee2$(_context2){while(1){switch(_context2.prev=_context2.next){case 0:if(!this.workflowMeta.cache){_context2.next=2;break;}return _context2.abrupt('return',fs.emptyDir(this.workflowMeta.cache));case 2:case'end':return _context2.stop();}}},_callee2,this);}));function clearCache(){return _ref2.apply(this,arguments);}return clearCache;}()},{key:'clearCacheSync',value:function clearCacheSync(){if(this.workflowMeta.cache){return fs.emptyDirSync(this.workflowMeta.cache);}}},{key:'filterItems',value:function filterItems(query){var options=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};options=(0,_assign2.default)({},this._fuseDefaults,options);if(query.length===0){return this;}var fuse=new Fuse(this._outputBuffer.items,options);this._outputBuffer.items=fuse.search(query)||[];return this;}},{key:'options',value:function options(_options){var cacheDirChanged='useTmpCache'in _options&&_options.useTmpCache!==this._options.useTmpCache;if(_options.updateInterval&&!moment.isDuration(_options.updateInterval)){if(_options.updateInterval<1){delete _options.updateInterval;}else{_options.updateInterval=moment.duration(_options.updateInterval,'seconds')||moment.duration(1,'days');}}this._options=(0,_assign2.default)({},this._options,_options);if(cacheDirChanged){this.cache=new CacheConf({configName:'cache',cwd:this.workflowMeta.cache,version:this.workflowMeta.version});}return this;}},{key:'matches',value:function matches(candidates,query){var options=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};options=(0,_assign2.default)({},this._fuseDefaults,options);if(query.length===0){return candidates;}var fuse=new Fuse(candidates,options);return fuse.search(query)||[];}},{key:'notify',value:function(){var _ref3=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee3(options){var _this3=this;return _regenerator2.default.wrap(function _callee3$(_context3){while(1){switch(_context3.prev=_context3.next){case 0:return _context3.abrupt('return',new _promise2.default(function(resolve,reject){var defaults={title:('Alfred '+_this3.workflowMeta.name).trim(),sender:'com.runningwithcrayons.Alfred-3',contentImage:_this3.workflowMeta.icon};options=(0,_assign2.default)({},defaults,options);notifier.notify(options,function(err,response){if(err){reject(err);return;}resolve(response);});}));case 1:case'end':return _context3.stop();}}},_callee3,this);}));function notify(_x3){return _ref3.apply(this,arguments);}return notify;}()},{key:'rerun',value:function rerun(value){value=parseFloat(value);if(value&&value>0.1&&value<=5){this._rerun=value;}return this;}},{key:'feedback',value:function(){var _ref4=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee4(){var output;return _regenerator2.default.wrap(function _callee4$(_context4){while(1){switch(_context4.prev=_context4.next){case 0:if(this._rerun){this._outputBuffer.rerun=this._rerun;}if(!(this._options.checkUpdates===true)){_context4.next=4;break;}_context4.next=4;return this.checkUpdates().catch(function(){});case 4:output=this._outputBuffer;console.log((0,_stringify2.default)(output,null,'\t'));this._outputBuffer={};return _context4.abrupt('return',output);case 8:case'end':return _context4.stop();}}},_callee4,this);}));function feedback(){return _ref4.apply(this,arguments);}return feedback;}()},{key:'fetch',value:function(){var _ref5=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee5(url){var _this4=this;var options=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var cacheAge=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var cacheResult;return _regenerator2.default.wrap(function _callee5$(_context5){while(1){switch(_context5.prev=_context5.next){case 0:options=(0,_assign2.default)({},{json:true},options);if(!(cacheAge&&cacheAge>0)){_context5.next=5;break;}cacheResult=this.cache.get(url);if(!cacheResult){_context5.next=5;break;}return _context5.abrupt('return',cacheResult);case 5:return _context5.abrupt('return',got(url,options).then(function(response){if(cacheAge&&cacheAge>0){_this4.cache.set(url,response.body,{maxAge:cacheAge*1000});}return response.body;}));case 6:case'end':return _context5.stop();}}},_callee5,this);}));function fetch(_x6){return _ref5.apply(this,arguments);}return fetch;}()},{key:'alfredMeta',get:function get(){var version=process.env.alfred_version||'0.0.0';if(!semver.valid(version)){version+='.0';if(!semver.valid(version)&&process.env.alfred_debug==='1'){console.error(`Invalid Alfred version: ${version}`);version='0.0.0';}}var data={version:version,theme:process.env.alfred_theme,themeFile:'',themeBackground:process.env.alfred_theme_background,themeSelectionBackground:process.env.alfred_theme_selection_background,themeSubtext:parseFloat(process.env.alfred_theme_subtext),preferences:process.env.alfred_preferences,preferencesLocalHash:process.env.alfred_preferences_localhash,debug:process.env.alfred_debug==='1'};if(process.env.HOME&&data.theme){var homedir=process.env.HOME||'';var themeFile=path.resolve(homedir,'Library','Application Support','Alfred '+semver.major(version),'Alfred.alfredpreferences','themes',data.theme,'theme.json');try{fs.statSync(themeFile);data.themeFile=themeFile;}catch(e){if(process.env.alfred_debug==='1'){console.error(`Could not find theme file "${themeFile}"`);}}}return data;}},{key:'alfredTheme',get:function get(){var themeFile=this.alfredMeta.themeFile;if(!themeFile){return{};}return fs.readJsonSync(themeFile,{throws:false})||{};}},{key:'input',get:function get(){if(process.argv.length>3){return process.argv[3]||'';}return process.argv[2]||'';}},{key:'itemCount',get:function get(){if(this.outputBuffer&&this.outputBuffer.items){return this.outputBuffer.items.length;}return 0;}},{key:'outputBuffer',get:function get(){return this._outputBuffer;}},{key:'workflowMeta',get:function get(){var cacheDir=process.env.alfred_workflow_cache;var bundleId=process.env.alfred_workflow_bundleid;if(bundleId&&this._options.useTmpCache===true){cacheDir=path.resolve(path.join(os.tmpdir(),bundleId));}return{name:process.env.alfred_workflow_name,version:process.env.alfred_workflow_version,uid:process.env.alfred_workflow_uid,bundleId:bundleId,data:process.env.alfred_workflow_data,cache:cacheDir,icon:path.join(process.cwd(),'icon.png')};}}]);return Hugo;}();module.exports=new Hugo(); //# sourceMappingURL=index.js.map diff --git a/index.js.flow b/index.js.flow index afc6856..9d87a97 100644 --- a/index.js.flow +++ b/index.js.flow @@ -2,7 +2,7 @@ const CacheConf = require('cache-conf'); const Conf = require('conf'); -const fs = require('fs-promise'); +const fs = require('fs-extra'); const Fuse = require('fuse.js'); const got = require('got'); const moment = require('moment'); diff --git a/index.js.map b/index.js.map index 6dde097..396954c 100644 --- a/index.js.map +++ b/index.js.map @@ -1 +1 @@ -{"version":3,"sources":["index.js.flow"],"names":["CacheConf","require","Conf","fs","Fuse","got","moment","notifier","os","path","semver","FileCache","updater","Hugo","_fuseDefaults","keys","threshold","_options","useTmpCache","checkUpdates","updateSource","updateInterval","duration","updateNotification","updateItem","_outputBuffer","config","cwd","workflowMeta","data","cache","configName","version","item","items","title","alfredMeta","debug","console","error","arg","variables","gte","alfredworkflow","lt","push","map","addItem","key","value","JSON","parse","e","keyword","callback","query","process","argv","filePath","cacheName","catch","err","then","result","current","latest","valid","gt","checkedOnline","notify","message","subtitle","icon","url","task","emptyDir","emptyDirSync","options","length","fuse","search","cacheDirChanged","isDuration","candidates","resolve","reject","defaults","name","trim","sender","contentImage","response","parseFloat","_rerun","rerun","output","log","cacheAge","json","cacheResult","get","set","body","maxAge","env","alfred_version","alfred_debug","theme","alfred_theme","themeFile","themeBackground","alfred_theme_background","themeSelectionBackground","alfred_theme_selection_background","themeSubtext","alfred_theme_subtext","preferences","alfred_preferences","preferencesLocalHash","alfred_preferences_localhash","HOME","homedir","major","statSync","readJsonSync","throws","outputBuffer","cacheDir","alfred_workflow_cache","bundleId","alfred_workflow_bundleid","join","tmpdir","alfred_workflow_name","alfred_workflow_version","uid","alfred_workflow_uid","alfred_workflow_data","module","exports"],"mappings":"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","file":"index.js","sourcesContent":["// @flow\n\nconst CacheConf = require('cache-conf');\nconst Conf = require('conf');\nconst fs = require('fs-promise');\nconst Fuse = require('fuse.js');\nconst got = require('got');\nconst moment = require('moment');\nconst notifier = require('node-notifier');\nconst os = require('os');\nconst path = require('path');\nconst semver = require('semver');\n\nconst FileCache = require('./file-cache');\nconst updater = require('./updater');\n\n/**\n * Hugo\n */\nclass Hugo {\n /**\n * FuseJS defaults\n * @see https://github.com/krisk/fuse#options\n * @type {Object}\n */\n _fuseDefaults: Object;\n\n /**\n * Hugo options\n * @type {Object}\n */\n _options: Object;\n\n /**\n * Output buffer\n * @type {Object}\n */\n _outputBuffer: Object;\n\n /**\n * Refresh (rerun) interval in seconds\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json\n * @type {number|null}\n */\n _rerun: ?number;\n\n /**\n * Cache store\n * @see https://www.npmjs.com/package/cache-conf\n * @type {CacheConf}\n */\n cache: CacheConf;\n\n /**\n * Configuration store\n * @see https://www.npmjs.com/package/conf\n * @type {Conf}\n */\n config: Conf;\n\n /**\n * Hugo constructor\n * @constructor\n */\n constructor() {\n // Set defaults for FuseJS\n this._fuseDefaults = {\n keys: ['title'],\n threshold: 0.4\n };\n\n // Save options\n this._options = {\n useTmpCache: true,\n checkUpdates: true,\n updateSource: 'packal',\n updateInterval: moment.duration(1, 'days'),\n updateNotification: true,\n updateItem: true\n };\n\n // Initialize output buffer\n this._outputBuffer = {};\n\n // Configure config store\n this.config = new Conf({\n cwd: this.workflowMeta.data\n });\n\n // Configure cache store\n this.cache = new CacheConf({\n configName: 'cache',\n cwd: this.workflowMeta.cache,\n version: this.workflowMeta.version\n });\n }\n\n /**\n * Alfred metadata\n * @return {Object}\n */\n get alfredMeta(): Object {\n let version: string = process.env.alfred_version || '0.0.0';\n\n // Check Alfred version for missing patch version (e.g. 3.4 is invalid, should be 3.4.0)\n if (!semver.valid(version)) {\n version += '.0';\n\n // Check if adding .0 to the end makes a valid version string (eg. in case of 3.4)\n if (!semver.valid(version) && process.env.alfred_debug === '1') {\n console.error(`Invalid Alfred version: ${version}`);\n version = '0.0.0';\n }\n }\n\n // Gather environment information\n let data: Object = {\n version: version,\n theme: process.env.alfred_theme,\n themeFile: '',\n themeBackground: process.env.alfred_theme_background,\n themeSelectionBackground: process.env.alfred_theme_selection_background,\n themeSubtext: parseFloat(process.env.alfred_theme_subtext),\n preferences: process.env.alfred_preferences,\n preferencesLocalHash: process.env.alfred_preferences_localhash,\n debug: process.env.alfred_debug === '1'\n };\n\n // Find and load curent Alfred theme file\n if (process.env.HOME && data.theme) {\n let homedir: string = process.env.HOME || '';\n\n let themeFile = path.resolve(homedir, 'Library', 'Application Support', 'Alfred ' + semver.major(version),\n 'Alfred.alfredpreferences', 'themes', data.theme, 'theme.json');\n\n try {\n fs.statSync(themeFile);\n data.themeFile = themeFile;\n } catch (e) {\n if (process.env.alfred_debug === '1') {\n console.error(`Could not find theme file \"${themeFile}\"`);\n }\n }\n }\n\n return data;\n }\n\n /**\n * Alfred theme\n * @return {Object}\n */\n get alfredTheme(): Object {\n let themeFile = this.alfredMeta.themeFile;\n\n if (!themeFile) {\n return {};\n }\n\n return fs.readJsonSync(themeFile, {throws: false}) || {};\n }\n\n /**\n * Alfred user input\n * @return {string}\n */\n get input(): string {\n if (process.argv.length > 3) {\n return process.argv[3] || '';\n }\n return process.argv[2] || '';\n }\n\n /**\n * Number of Alfred items in the current output buffer\n * @return {number}\n */\n get itemCount(): number {\n if (this.outputBuffer && this.outputBuffer.items) {\n return this.outputBuffer.items.length;\n }\n\n return 0;\n }\n\n /**\n * Current output buffer\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json\n * @return {Object} Object to be output and interpreted by Alfred\n */\n get outputBuffer(): Object {\n return this._outputBuffer;\n }\n\n /**\n * Workflow metadata\n * @return {Object}\n */\n get workflowMeta(): Object {\n let cacheDir = process.env.alfred_workflow_cache;\n let bundleId = process.env.alfred_workflow_bundleid;\n\n if (bundleId && this._options.useTmpCache === true) {\n cacheDir = path.resolve(path.join(os.tmpdir(), bundleId));\n }\n\n return {\n name: process.env.alfred_workflow_name,\n version: process.env.alfred_workflow_version,\n uid: process.env.alfred_workflow_uid,\n bundleId: bundleId,\n data: process.env.alfred_workflow_data,\n cache: cacheDir,\n icon: path.join(process.cwd(), 'icon.png')\n };\n }\n\n /**\n * Add item to output buffer\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json\n * @param {Object} item Item to add\n * @return {Hugo}\n */\n addItem(item: Object): Hugo {\n if (!this._outputBuffer.items) {\n this._outputBuffer.items = [];\n }\n\n // Require item title\n if (!item.title) {\n if (this.alfredMeta.debug === true) {\n console.error('Item skipped, missing title.');\n }\n return this;\n }\n\n // Parse item variables\n if (item.arg && typeof item.arg === 'object') {\n let arg = item.arg.arg;\n let variables = item.arg.variables || {};\n\n if (semver.gte(this.alfredMeta.version, '3.4.1')) {\n // Delete item arg\n delete item.arg;\n\n // Only add arg when there is one\n if (arg) {\n item.arg = arg;\n }\n\n // Item variables\n item.variables = Object.assign({}, item.variables, variables);\n } else {\n // Merge item.variables (new style) with item.arg.variables (old style)\n if (item.variables && typeof item.variables === 'object') {\n variables = Object.assign({}, variables, item.variables);\n delete item.variables;\n }\n\n // Build item arg (old style)\n item.arg = JSON.stringify({\n alfredworkflow: {\n arg: arg,\n variables: variables\n }\n });\n }\n } else if (item.variables && typeof item.variables === 'object' && semver.lt(this.alfredMeta.version, '3.4.1')) {\n // Build item arg (old style) with new style item variables\n item.arg = JSON.stringify({\n alfredworkflow: {\n arg: item.arg,\n variables: item.variables\n }\n });\n\n delete item.variables;\n }\n\n // Add item to output buffer\n this._outputBuffer.items.push(item);\n\n return this;\n }\n\n /**\n * Add items to output buffer\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json\n * @param {Array.} items List of items to add\n * @return {Hugo}\n */\n addItems(items: Array): Hugo {\n items.map(item => {\n this.addItem(item);\n return item;\n });\n\n return this;\n }\n\n /**\n * Add session variable to output buffer\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json\n * @param {string} key Variable key\n * @param {string} value Variable value\n * @return {Hugo}\n */\n addVariable(key: string, value: string): Hugo {\n if (!this._outputBuffer.variables) {\n this._outputBuffer.variables = {};\n }\n\n this._outputBuffer.variables[key] = value;\n\n return this;\n }\n\n /**\n * Add session variables to output buffer\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json/\n * @param {Object} variables List of variables to add\n * @return {Hugo}\n */\n addVariables(variables: Object): Hugo {\n if (!this._outputBuffer.variables) {\n this._outputBuffer.variables = variables;\n return this;\n }\n\n this._outputBuffer.variables = Object.assign({}, this._outputBuffer.variables, variables);\n\n return this;\n }\n\n /**\n * Get session variable from output buffer\n * @param {string} key Variable key\n * @return {string|null} Variable value\n */\n getVariable(key: string): ?string {\n if (!this._outputBuffer.variables) {\n return null;\n }\n\n return this._outputBuffer.variables[key] || null;\n }\n\n /**\n * Get session variables from output buffer\n * @return {Object} Variables\n */\n getVariables(): Object {\n return this._outputBuffer.variables || {};\n }\n\n /**\n * Get item variable\n * @param {Object} item\n * @param {string} key Variable key\n * @return {string|null} Variable value\n */\n getItemVariable(item: Object, key: string): ?string {\n if (semver.gte(this.alfredMeta.version, '3.4.1')) {\n if (item.variables) {\n return item.variables[key] || null;\n }\n } else if (item.arg) {\n try {\n let arg = {};\n let variables = {};\n\n if (typeof item.arg === 'string') {\n arg = JSON.parse(item.arg);\n }\n\n if (arg.alfredworkflow) {\n variables = arg.alfredworkflow.variables || {};\n }\n\n return variables[key] || null;\n } catch (e) {}\n }\n\n return null;\n }\n\n /**\n * Get item variables\n *\n * As of Alfred 3.4.1 item variables are handled differently (properly). This method makes it easier to get the\n * variables of an item without having to deal with different versions.\n *\n * @param {Object} item\n * @return {Object} Item variables\n */\n getItemVariables(item: Object): Object {\n if (semver.gte(this.alfredMeta.version, '3.4.1')) {\n return item.variables || {};\n } else if (item.arg) {\n try {\n let arg = {};\n\n if (typeof item.arg === 'string') {\n arg = JSON.parse(item.arg);\n }\n\n if (arg.alfredworkflow) {\n return arg.alfredworkflow.variables || {};\n }\n\n return arg.variables || {};\n } catch (e) {}\n }\n\n return {};\n }\n\n /**\n * Run a callback when first script argument matches keyword. Callback will have third argument as query parameter.\n * @example node index.js myaction \"my query\"\n * @param {string} keyword Action name\n * @param {Function} callback Callback to execute when query matches action name\n * @return {Hugo}\n */\n action(keyword: string, callback: (query: string) => void): Hugo {\n let query: string = process.argv[2];\n\n if (query && callback && query === keyword) {\n query = process.argv[3] || '';\n callback(query);\n }\n\n return this;\n }\n\n /**\n * Cache processed data\n * This allows you to read and process the data once, then storing it in cache until the file has changed again.\n *\n * @param {string} filepath File path\n * @param {string} cacheName Cache name (must be unique for each file)\n * @return {FileCache}\n */\n cacheFile(filePath: string, cacheName: string): FileCache {\n return new FileCache(filePath, cacheName, this.workflowMeta.cache);\n }\n\n /**\n * Check for updates and notify the user\n * @async\n * @return {Promise}\n */\n async checkUpdates() {\n // No need to check if we're not showing anything, duh.\n if (this._options.checkUpdates !== true ||\n (this._options.updateItem !== true && this._options.updateNotification !== true)) {\n return;\n }\n\n await updater.checkUpdates(this._options.updateSource, this._options.updateInterval)\n .catch(err => {\n console.error(err);\n return;\n })\n .then(result => {\n if (!result) {\n return;\n }\n\n // Version information\n let current: string = this.workflowMeta.version;\n let latest: string = result.version;\n\n if (!semver.valid(current)) {\n console.error(`Version ${current} is not a valid version number.`);\n return;\n }\n\n if (!semver.valid(latest)) {\n console.error(`Could not determine latest version number.`);\n return;\n }\n\n // Display notification\n if (semver.gt(latest, current)) {\n if (result.checkedOnline === true && this._options.updateNotification === true) {\n this.notify({\n message: `Workflow version ${latest} available. Current version: ${current}.`\n });\n }\n if (this._options.updateItem === true) {\n this.addItem({\n title: `Workflow update available!`,\n subtitle: `Version ${latest} is available. Current version: ${current}.`,\n icon: this.workflowMeta.icon,\n arg: result.url,\n variables: {\n task: 'wfUpdate'\n }\n });\n }\n }\n });\n }\n\n /**\n * Clear cache\n * @async\n * @return {Promise}\n */\n async clearCache() {\n if (this.workflowMeta.cache) {\n return fs.emptyDir(this.workflowMeta.cache);\n }\n }\n\n /**\n * Clear cache (sync)\n * @return {void}\n */\n clearCacheSync() {\n if (this.workflowMeta.cache) {\n return fs.emptyDirSync(this.workflowMeta.cache);\n }\n }\n\n /**\n * Filter added items (output buffer) with fuse.js\n * @see http://fusejs.io\n * @param {string} query Search string\n * @param {Object} options fuse.js options\n * @return {Hugo}\n */\n filterItems(query: string, options: Object = {}): Hugo {\n options = Object.assign({}, this._fuseDefaults, options);\n\n if (query.length === 0) {\n return this;\n }\n\n // Create fuse.js fuzzy search object\n let fuse = new Fuse(this._outputBuffer.items, options);\n\n // Set output buffer to matching items\n this._outputBuffer.items = fuse.search(query) || [];\n\n return this;\n }\n\n /**\n * Set Hugo options\n * @param {Object} options Options to set\n * @return {Hugo}\n */\n options(options: Object): Hugo {\n let cacheDirChanged = 'useTmpCache' in options && options.useTmpCache !== this._options.useTmpCache;\n\n // Convert updateInterval to moment.Duration object\n if (options.updateInterval && !moment.isDuration(options.updateInterval)) {\n if (options.updateInterval < 1) {\n delete options.updateInterval;\n } else {\n options.updateInterval = moment.duration(options.updateInterval, 'seconds') || moment.duration(1, 'days');\n }\n }\n\n // Update options\n this._options = Object.assign({}, this._options, options);\n\n // Update cache dir\n if (cacheDirChanged) {\n this.cache = new CacheConf({\n configName: 'cache',\n cwd: this.workflowMeta.cache,\n version: this.workflowMeta.version\n });\n }\n\n return this;\n }\n\n /**\n * Filter list of candidates with fuse.js\n * @see http://fusejs.io\n * @param {Array.} candidates Input data\n * @param {string} query Search string\n * @param {Object} options fuse.js options\n * @return {Array.}\n */\n matches(candidates: Array, query: string, options: Object = {}): Array {\n options = Object.assign({}, this._fuseDefaults, options);\n\n if (query.length === 0) {\n return candidates;\n }\n\n // Create fuse.js fuzzy search object\n let fuse = new Fuse(candidates, options);\n\n // Return results\n return fuse.search(query) || [];\n }\n\n /**\n * Send a notification\n *\n * Notification title defaults to the Workflow name, or when not available to 'Alfred'. You can adjust all the options\n * that node-notifier supports. Please see their documentation for available options.\n *\n * @see https://github.com/mikaelbr/node-notifier\n * @param {Object} options Notification options\n * @return {Promise} Notifier response\n */\n async notify(options: Object) {\n return new Promise((resolve, reject) => {\n let defaults = {\n title: ('Alfred ' + this.workflowMeta.name).trim(),\n sender: 'com.runningwithcrayons.Alfred-3',\n contentImage: this.workflowMeta.icon\n };\n\n // Set options\n options = Object.assign({}, defaults, options);\n\n // Notify\n notifier.notify(options, (err, response) => {\n if (err) {\n reject(err);\n return;\n }\n\n resolve(response);\n });\n });\n }\n\n /**\n * Set rerun parameter\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json\n * @param {number} value Interval to rerun the script when idle\n * @return {Hugo}\n */\n rerun(value: number): Hugo {\n value = parseFloat(value);\n\n if (value && value > 0.1 && value <= 5) {\n this._rerun = value;\n }\n\n return this;\n }\n\n /**\n * Flush the output buffer so Alfred shows our items\n * @async\n */\n async feedback() {\n if (this._rerun) {\n this._outputBuffer.rerun = this._rerun;\n }\n\n // Check for updates\n if (this._options.checkUpdates === true) {\n await this.checkUpdates()\n .catch(() => {});\n }\n\n let output = this._outputBuffer;\n\n // Output JSON\n console.log(JSON.stringify(output, null, '\\t'));\n\n // Reset output buffer\n this._outputBuffer = {};\n\n return output;\n }\n\n /**\n * Fetch url and parse JSON. Useful for REST APIs.\n * @see https://www.npmjs.com/package/got\n * @param {string} url Url to request\n * @param {Object} options http.request options\n * @param {number|null} cacheAge Cache lifetime (in seconds), above 0 to enable or null to disable.\n * @return {Object|string}\n * @async\n */\n async fetch(url: string, options: Object = {}, cacheAge: ?number = null): Object|string {\n // Set default options\n options = Object.assign({}, {\n json: true\n }, options);\n\n // Check cache for a hit\n if (cacheAge && cacheAge > 0) {\n let cacheResult: Object|string|null = this.cache.get(url);\n\n if (cacheResult) {\n return cacheResult;\n }\n }\n\n // Do request\n return got(url, options)\n .then(response => {\n if (cacheAge && cacheAge > 0) {\n this.cache.set(url, response.body, {\n maxAge: cacheAge * 1000\n });\n }\n\n return response.body;\n });\n }\n}\n\nmodule.exports = new Hugo();\n"]} \ No newline at end of file +{"version":3,"sources":["index.js.flow"],"names":["CacheConf","require","Conf","fs","Fuse","got","moment","notifier","os","path","semver","FileCache","updater","Hugo","_fuseDefaults","keys","threshold","_options","useTmpCache","checkUpdates","updateSource","updateInterval","duration","updateNotification","updateItem","_outputBuffer","config","cwd","workflowMeta","data","cache","configName","version","item","items","title","alfredMeta","debug","console","error","arg","variables","gte","alfredworkflow","lt","push","map","addItem","key","value","JSON","parse","e","keyword","callback","query","process","argv","filePath","cacheName","catch","err","then","result","current","latest","valid","gt","checkedOnline","notify","message","subtitle","icon","url","task","emptyDir","emptyDirSync","options","length","fuse","search","cacheDirChanged","isDuration","candidates","resolve","reject","defaults","name","trim","sender","contentImage","response","parseFloat","_rerun","rerun","output","log","cacheAge","json","cacheResult","get","set","body","maxAge","env","alfred_version","alfred_debug","theme","alfred_theme","themeFile","themeBackground","alfred_theme_background","themeSelectionBackground","alfred_theme_selection_background","themeSubtext","alfred_theme_subtext","preferences","alfred_preferences","preferencesLocalHash","alfred_preferences_localhash","HOME","homedir","major","statSync","readJsonSync","throws","outputBuffer","cacheDir","alfred_workflow_cache","bundleId","alfred_workflow_bundleid","join","tmpdir","alfred_workflow_name","alfred_workflow_version","uid","alfred_workflow_uid","alfred_workflow_data","module","exports"],"mappings":"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","file":"index.js","sourcesContent":["// @flow\n\nconst CacheConf = require('cache-conf');\nconst Conf = require('conf');\nconst fs = require('fs-extra');\nconst Fuse = require('fuse.js');\nconst got = require('got');\nconst moment = require('moment');\nconst notifier = require('node-notifier');\nconst os = require('os');\nconst path = require('path');\nconst semver = require('semver');\n\nconst FileCache = require('./file-cache');\nconst updater = require('./updater');\n\n/**\n * Hugo\n */\nclass Hugo {\n /**\n * FuseJS defaults\n * @see https://github.com/krisk/fuse#options\n * @type {Object}\n */\n _fuseDefaults: Object;\n\n /**\n * Hugo options\n * @type {Object}\n */\n _options: Object;\n\n /**\n * Output buffer\n * @type {Object}\n */\n _outputBuffer: Object;\n\n /**\n * Refresh (rerun) interval in seconds\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json\n * @type {number|null}\n */\n _rerun: ?number;\n\n /**\n * Cache store\n * @see https://www.npmjs.com/package/cache-conf\n * @type {CacheConf}\n */\n cache: CacheConf;\n\n /**\n * Configuration store\n * @see https://www.npmjs.com/package/conf\n * @type {Conf}\n */\n config: Conf;\n\n /**\n * Hugo constructor\n * @constructor\n */\n constructor() {\n // Set defaults for FuseJS\n this._fuseDefaults = {\n keys: ['title'],\n threshold: 0.4\n };\n\n // Save options\n this._options = {\n useTmpCache: true,\n checkUpdates: true,\n updateSource: 'packal',\n updateInterval: moment.duration(1, 'days'),\n updateNotification: true,\n updateItem: true\n };\n\n // Initialize output buffer\n this._outputBuffer = {};\n\n // Configure config store\n this.config = new Conf({\n cwd: this.workflowMeta.data\n });\n\n // Configure cache store\n this.cache = new CacheConf({\n configName: 'cache',\n cwd: this.workflowMeta.cache,\n version: this.workflowMeta.version\n });\n }\n\n /**\n * Alfred metadata\n * @return {Object}\n */\n get alfredMeta(): Object {\n let version: string = process.env.alfred_version || '0.0.0';\n\n // Check Alfred version for missing patch version (e.g. 3.4 is invalid, should be 3.4.0)\n if (!semver.valid(version)) {\n version += '.0';\n\n // Check if adding .0 to the end makes a valid version string (eg. in case of 3.4)\n if (!semver.valid(version) && process.env.alfred_debug === '1') {\n console.error(`Invalid Alfred version: ${version}`);\n version = '0.0.0';\n }\n }\n\n // Gather environment information\n let data: Object = {\n version: version,\n theme: process.env.alfred_theme,\n themeFile: '',\n themeBackground: process.env.alfred_theme_background,\n themeSelectionBackground: process.env.alfred_theme_selection_background,\n themeSubtext: parseFloat(process.env.alfred_theme_subtext),\n preferences: process.env.alfred_preferences,\n preferencesLocalHash: process.env.alfred_preferences_localhash,\n debug: process.env.alfred_debug === '1'\n };\n\n // Find and load curent Alfred theme file\n if (process.env.HOME && data.theme) {\n let homedir: string = process.env.HOME || '';\n\n let themeFile = path.resolve(homedir, 'Library', 'Application Support', 'Alfred ' + semver.major(version),\n 'Alfred.alfredpreferences', 'themes', data.theme, 'theme.json');\n\n try {\n fs.statSync(themeFile);\n data.themeFile = themeFile;\n } catch (e) {\n if (process.env.alfred_debug === '1') {\n console.error(`Could not find theme file \"${themeFile}\"`);\n }\n }\n }\n\n return data;\n }\n\n /**\n * Alfred theme\n * @return {Object}\n */\n get alfredTheme(): Object {\n let themeFile = this.alfredMeta.themeFile;\n\n if (!themeFile) {\n return {};\n }\n\n return fs.readJsonSync(themeFile, {throws: false}) || {};\n }\n\n /**\n * Alfred user input\n * @return {string}\n */\n get input(): string {\n if (process.argv.length > 3) {\n return process.argv[3] || '';\n }\n return process.argv[2] || '';\n }\n\n /**\n * Number of Alfred items in the current output buffer\n * @return {number}\n */\n get itemCount(): number {\n if (this.outputBuffer && this.outputBuffer.items) {\n return this.outputBuffer.items.length;\n }\n\n return 0;\n }\n\n /**\n * Current output buffer\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json\n * @return {Object} Object to be output and interpreted by Alfred\n */\n get outputBuffer(): Object {\n return this._outputBuffer;\n }\n\n /**\n * Workflow metadata\n * @return {Object}\n */\n get workflowMeta(): Object {\n let cacheDir = process.env.alfred_workflow_cache;\n let bundleId = process.env.alfred_workflow_bundleid;\n\n if (bundleId && this._options.useTmpCache === true) {\n cacheDir = path.resolve(path.join(os.tmpdir(), bundleId));\n }\n\n return {\n name: process.env.alfred_workflow_name,\n version: process.env.alfred_workflow_version,\n uid: process.env.alfred_workflow_uid,\n bundleId: bundleId,\n data: process.env.alfred_workflow_data,\n cache: cacheDir,\n icon: path.join(process.cwd(), 'icon.png')\n };\n }\n\n /**\n * Add item to output buffer\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json\n * @param {Object} item Item to add\n * @return {Hugo}\n */\n addItem(item: Object): Hugo {\n if (!this._outputBuffer.items) {\n this._outputBuffer.items = [];\n }\n\n // Require item title\n if (!item.title) {\n if (this.alfredMeta.debug === true) {\n console.error('Item skipped, missing title.');\n }\n return this;\n }\n\n // Parse item variables\n if (item.arg && typeof item.arg === 'object') {\n let arg = item.arg.arg;\n let variables = item.arg.variables || {};\n\n if (semver.gte(this.alfredMeta.version, '3.4.1')) {\n // Delete item arg\n delete item.arg;\n\n // Only add arg when there is one\n if (arg) {\n item.arg = arg;\n }\n\n // Item variables\n item.variables = Object.assign({}, item.variables, variables);\n } else {\n // Merge item.variables (new style) with item.arg.variables (old style)\n if (item.variables && typeof item.variables === 'object') {\n variables = Object.assign({}, variables, item.variables);\n delete item.variables;\n }\n\n // Build item arg (old style)\n item.arg = JSON.stringify({\n alfredworkflow: {\n arg: arg,\n variables: variables\n }\n });\n }\n } else if (item.variables && typeof item.variables === 'object' && semver.lt(this.alfredMeta.version, '3.4.1')) {\n // Build item arg (old style) with new style item variables\n item.arg = JSON.stringify({\n alfredworkflow: {\n arg: item.arg,\n variables: item.variables\n }\n });\n\n delete item.variables;\n }\n\n // Add item to output buffer\n this._outputBuffer.items.push(item);\n\n return this;\n }\n\n /**\n * Add items to output buffer\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json\n * @param {Array.} items List of items to add\n * @return {Hugo}\n */\n addItems(items: Array): Hugo {\n items.map(item => {\n this.addItem(item);\n return item;\n });\n\n return this;\n }\n\n /**\n * Add session variable to output buffer\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json\n * @param {string} key Variable key\n * @param {string} value Variable value\n * @return {Hugo}\n */\n addVariable(key: string, value: string): Hugo {\n if (!this._outputBuffer.variables) {\n this._outputBuffer.variables = {};\n }\n\n this._outputBuffer.variables[key] = value;\n\n return this;\n }\n\n /**\n * Add session variables to output buffer\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json/\n * @param {Object} variables List of variables to add\n * @return {Hugo}\n */\n addVariables(variables: Object): Hugo {\n if (!this._outputBuffer.variables) {\n this._outputBuffer.variables = variables;\n return this;\n }\n\n this._outputBuffer.variables = Object.assign({}, this._outputBuffer.variables, variables);\n\n return this;\n }\n\n /**\n * Get session variable from output buffer\n * @param {string} key Variable key\n * @return {string|null} Variable value\n */\n getVariable(key: string): ?string {\n if (!this._outputBuffer.variables) {\n return null;\n }\n\n return this._outputBuffer.variables[key] || null;\n }\n\n /**\n * Get session variables from output buffer\n * @return {Object} Variables\n */\n getVariables(): Object {\n return this._outputBuffer.variables || {};\n }\n\n /**\n * Get item variable\n * @param {Object} item\n * @param {string} key Variable key\n * @return {string|null} Variable value\n */\n getItemVariable(item: Object, key: string): ?string {\n if (semver.gte(this.alfredMeta.version, '3.4.1')) {\n if (item.variables) {\n return item.variables[key] || null;\n }\n } else if (item.arg) {\n try {\n let arg = {};\n let variables = {};\n\n if (typeof item.arg === 'string') {\n arg = JSON.parse(item.arg);\n }\n\n if (arg.alfredworkflow) {\n variables = arg.alfredworkflow.variables || {};\n }\n\n return variables[key] || null;\n } catch (e) {}\n }\n\n return null;\n }\n\n /**\n * Get item variables\n *\n * As of Alfred 3.4.1 item variables are handled differently (properly). This method makes it easier to get the\n * variables of an item without having to deal with different versions.\n *\n * @param {Object} item\n * @return {Object} Item variables\n */\n getItemVariables(item: Object): Object {\n if (semver.gte(this.alfredMeta.version, '3.4.1')) {\n return item.variables || {};\n } else if (item.arg) {\n try {\n let arg = {};\n\n if (typeof item.arg === 'string') {\n arg = JSON.parse(item.arg);\n }\n\n if (arg.alfredworkflow) {\n return arg.alfredworkflow.variables || {};\n }\n\n return arg.variables || {};\n } catch (e) {}\n }\n\n return {};\n }\n\n /**\n * Run a callback when first script argument matches keyword. Callback will have third argument as query parameter.\n * @example node index.js myaction \"my query\"\n * @param {string} keyword Action name\n * @param {Function} callback Callback to execute when query matches action name\n * @return {Hugo}\n */\n action(keyword: string, callback: (query: string) => void): Hugo {\n let query: string = process.argv[2];\n\n if (query && callback && query === keyword) {\n query = process.argv[3] || '';\n callback(query);\n }\n\n return this;\n }\n\n /**\n * Cache processed data\n * This allows you to read and process the data once, then storing it in cache until the file has changed again.\n *\n * @param {string} filepath File path\n * @param {string} cacheName Cache name (must be unique for each file)\n * @return {FileCache}\n */\n cacheFile(filePath: string, cacheName: string): FileCache {\n return new FileCache(filePath, cacheName, this.workflowMeta.cache);\n }\n\n /**\n * Check for updates and notify the user\n * @async\n * @return {Promise}\n */\n async checkUpdates() {\n // No need to check if we're not showing anything, duh.\n if (this._options.checkUpdates !== true ||\n (this._options.updateItem !== true && this._options.updateNotification !== true)) {\n return;\n }\n\n await updater.checkUpdates(this._options.updateSource, this._options.updateInterval)\n .catch(err => {\n console.error(err);\n return;\n })\n .then(result => {\n if (!result) {\n return;\n }\n\n // Version information\n let current: string = this.workflowMeta.version;\n let latest: string = result.version;\n\n if (!semver.valid(current)) {\n console.error(`Version ${current} is not a valid version number.`);\n return;\n }\n\n if (!semver.valid(latest)) {\n console.error(`Could not determine latest version number.`);\n return;\n }\n\n // Display notification\n if (semver.gt(latest, current)) {\n if (result.checkedOnline === true && this._options.updateNotification === true) {\n this.notify({\n message: `Workflow version ${latest} available. Current version: ${current}.`\n });\n }\n if (this._options.updateItem === true) {\n this.addItem({\n title: `Workflow update available!`,\n subtitle: `Version ${latest} is available. Current version: ${current}.`,\n icon: this.workflowMeta.icon,\n arg: result.url,\n variables: {\n task: 'wfUpdate'\n }\n });\n }\n }\n });\n }\n\n /**\n * Clear cache\n * @async\n * @return {Promise}\n */\n async clearCache() {\n if (this.workflowMeta.cache) {\n return fs.emptyDir(this.workflowMeta.cache);\n }\n }\n\n /**\n * Clear cache (sync)\n * @return {void}\n */\n clearCacheSync() {\n if (this.workflowMeta.cache) {\n return fs.emptyDirSync(this.workflowMeta.cache);\n }\n }\n\n /**\n * Filter added items (output buffer) with fuse.js\n * @see http://fusejs.io\n * @param {string} query Search string\n * @param {Object} options fuse.js options\n * @return {Hugo}\n */\n filterItems(query: string, options: Object = {}): Hugo {\n options = Object.assign({}, this._fuseDefaults, options);\n\n if (query.length === 0) {\n return this;\n }\n\n // Create fuse.js fuzzy search object\n let fuse = new Fuse(this._outputBuffer.items, options);\n\n // Set output buffer to matching items\n this._outputBuffer.items = fuse.search(query) || [];\n\n return this;\n }\n\n /**\n * Set Hugo options\n * @param {Object} options Options to set\n * @return {Hugo}\n */\n options(options: Object): Hugo {\n let cacheDirChanged = 'useTmpCache' in options && options.useTmpCache !== this._options.useTmpCache;\n\n // Convert updateInterval to moment.Duration object\n if (options.updateInterval && !moment.isDuration(options.updateInterval)) {\n if (options.updateInterval < 1) {\n delete options.updateInterval;\n } else {\n options.updateInterval = moment.duration(options.updateInterval, 'seconds') || moment.duration(1, 'days');\n }\n }\n\n // Update options\n this._options = Object.assign({}, this._options, options);\n\n // Update cache dir\n if (cacheDirChanged) {\n this.cache = new CacheConf({\n configName: 'cache',\n cwd: this.workflowMeta.cache,\n version: this.workflowMeta.version\n });\n }\n\n return this;\n }\n\n /**\n * Filter list of candidates with fuse.js\n * @see http://fusejs.io\n * @param {Array.} candidates Input data\n * @param {string} query Search string\n * @param {Object} options fuse.js options\n * @return {Array.}\n */\n matches(candidates: Array, query: string, options: Object = {}): Array {\n options = Object.assign({}, this._fuseDefaults, options);\n\n if (query.length === 0) {\n return candidates;\n }\n\n // Create fuse.js fuzzy search object\n let fuse = new Fuse(candidates, options);\n\n // Return results\n return fuse.search(query) || [];\n }\n\n /**\n * Send a notification\n *\n * Notification title defaults to the Workflow name, or when not available to 'Alfred'. You can adjust all the options\n * that node-notifier supports. Please see their documentation for available options.\n *\n * @see https://github.com/mikaelbr/node-notifier\n * @param {Object} options Notification options\n * @return {Promise} Notifier response\n */\n async notify(options: Object) {\n return new Promise((resolve, reject) => {\n let defaults = {\n title: ('Alfred ' + this.workflowMeta.name).trim(),\n sender: 'com.runningwithcrayons.Alfred-3',\n contentImage: this.workflowMeta.icon\n };\n\n // Set options\n options = Object.assign({}, defaults, options);\n\n // Notify\n notifier.notify(options, (err, response) => {\n if (err) {\n reject(err);\n return;\n }\n\n resolve(response);\n });\n });\n }\n\n /**\n * Set rerun parameter\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json\n * @param {number} value Interval to rerun the script when idle\n * @return {Hugo}\n */\n rerun(value: number): Hugo {\n value = parseFloat(value);\n\n if (value && value > 0.1 && value <= 5) {\n this._rerun = value;\n }\n\n return this;\n }\n\n /**\n * Flush the output buffer so Alfred shows our items\n * @async\n */\n async feedback() {\n if (this._rerun) {\n this._outputBuffer.rerun = this._rerun;\n }\n\n // Check for updates\n if (this._options.checkUpdates === true) {\n await this.checkUpdates()\n .catch(() => {});\n }\n\n let output = this._outputBuffer;\n\n // Output JSON\n console.log(JSON.stringify(output, null, '\\t'));\n\n // Reset output buffer\n this._outputBuffer = {};\n\n return output;\n }\n\n /**\n * Fetch url and parse JSON. Useful for REST APIs.\n * @see https://www.npmjs.com/package/got\n * @param {string} url Url to request\n * @param {Object} options http.request options\n * @param {number|null} cacheAge Cache lifetime (in seconds), above 0 to enable or null to disable.\n * @return {Object|string}\n * @async\n */\n async fetch(url: string, options: Object = {}, cacheAge: ?number = null): Object|string {\n // Set default options\n options = Object.assign({}, {\n json: true\n }, options);\n\n // Check cache for a hit\n if (cacheAge && cacheAge > 0) {\n let cacheResult: Object|string|null = this.cache.get(url);\n\n if (cacheResult) {\n return cacheResult;\n }\n }\n\n // Do request\n return got(url, options)\n .then(response => {\n if (cacheAge && cacheAge > 0) {\n this.cache.set(url, response.body, {\n maxAge: cacheAge * 1000\n });\n }\n\n return response.body;\n });\n }\n}\n\nmodule.exports = new Hugo();\n"]} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d8e6c71..17c3f63 100644 --- a/package-lock.json +++ b/package-lock.json @@ -153,11 +153,6 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=" - }, "anymatch": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz", @@ -2482,23 +2477,13 @@ "dev": true }, "fs-extra": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", - "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.0.tgz", + "integrity": "sha1-QU+0yi0hcLoAFBWdOorsMwNBjZ4=", "requires": { "graceful-fs": "4.1.11", - "jsonfile": "2.4.0" - } - }, - "fs-promise": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/fs-promise/-/fs-promise-2.0.3.tgz", - "integrity": "sha1-9k5PhUvPaJqovdy6JokW2z20aFQ=", - "requires": { - "any-promise": "1.3.0", - "fs-extra": "2.1.2", - "mz": "2.6.0", - "thenify-all": "1.6.0" + "jsonfile": "3.0.1", + "universalify": "0.1.1" } }, "fs.realpath": { @@ -4475,9 +4460,9 @@ "dev": true }, "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", "requires": { "graceful-fs": "4.1.11" } @@ -4983,16 +4968,6 @@ "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", "dev": true }, - "mz": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.6.0.tgz", - "integrity": "sha1-yLhSHZWN8KTydoAl22nHGe5O8c4=", - "requires": { - "any-promise": "1.3.0", - "object-assign": "4.1.1", - "thenify-all": "1.6.0" - } - }, "nan": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz", @@ -6274,22 +6249,6 @@ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, - "thenify": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", - "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", - "requires": { - "any-promise": "1.3.0" - } - }, - "thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", - "requires": { - "thenify": "3.3.0" - } - }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -6461,6 +6420,11 @@ "uid2": "0.0.3" } }, + "universalify": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", + "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=" + }, "untildify": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/untildify/-/untildify-3.0.2.tgz", diff --git a/package.json b/package.json index a48a58b..1599ea8 100644 --- a/package.json +++ b/package.json @@ -53,7 +53,7 @@ "babel-runtime": "^6.23.0", "cache-conf": "^0.5.0", "conf": "^0.12.0", - "fs-promise": "^2.0.2", + "fs-extra": "^4.0.0", "fuse.js": "^2.6.2", "got": "^6.7.1", "latest-version": "^3.0.0", From 41738912be95eab4757043be0bf99c5e7330b825 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Tue, 4 Jun 2019 02:47:36 +0200 Subject: [PATCH 02/35] Rewrite in TypeScript --- .DS_Store | Bin 0 -> 6148 bytes .babelrc | 19 - .eslintrc | 24 - .flowconfig | 8 - .gitignore | 6 + .nycrc | 14 + .travis.yml | 20 - LICENSE | 2 +- README.md | 4 +- file-cache.js | 2 - file-cache.js.flow | 165 - file-cache.js.map | 1 - gulp/index.js | 32 - gulp/tasks/babel.js | 22 - gulp/tasks/eslint.js | 12 - gulp/tasks/watch.js | 8 - gulpfile.js | 13 - index.js | 2 - index.js.flow | 717 --- index.js.map | 1 - package-lock.json | 6791 ------------------------ package.json | 92 +- src/file-cache.ts | 61 + src/hugo.ts | 440 ++ src/index.ts | 3 + src/types.ts | 100 + src/updater.ts | 160 + src/utils.ts | 15 + test/actions.ts | 86 + test/feedback.ts | 70 + test/fetch.ts | 71 + {tests => test}/file-cache.js | 0 test/file-cache.ts | 86 + test/helpers/init.ts | 38 + test/helpers/mock.ts | 102 + test/helpers/types.ts | 7 + test/hugo.ts | 218 + test/matching.ts | 77 + test/meta/alfred.ts | 120 + test/meta/theme.ts | 34 + test/meta/workflow.ts | 80 + test/mocks/appcast-invalidversion.xml | 9 + test/mocks/appcast-noversion.xml | 8 + {tests => test}/mocks/appcast.xml | 2 +- test/output.ts | 106 + test/snapshots/feedback.ts.md | 42 + test/snapshots/feedback.ts.snap | Bin 0 -> 447 bytes test/snapshots/matching.ts.md | 55 + test/snapshots/matching.ts.snap | Bin 0 -> 451 bytes test/snapshots/output.ts.md | 102 + test/snapshots/output.ts.snap | Bin 0 -> 753 bytes test/updates/npm.ts | 273 + test/updates/packal.ts | 129 + test/updates/snapshots/updater.ts.md | 21 + test/updates/snapshots/updater.ts.snap | Bin 0 -> 440 bytes test/updates/updater.ts | 214 + tests/__snapshots__/cache.js.snap | 7 - tests/__snapshots__/file-cache.js.snap | 15 - tests/__snapshots__/output.js.snap | 15 - tests/_init.js | 26 - tests/cache.js | 135 - tests/fetch.js | 101 - tests/index.js | 31 - tests/matching.js | 145 - tests/output.js | 298 -- tests/updates.js | 171 - tsconfig.dist.json | 15 + tsconfig.json | 18 + tslint.json | 15 + updater.js | 2 - updater.js.flow | 157 - updater.js.map | 1 - yarn.lock | 4404 +++++++++++++++ 73 files changed, 7250 insertions(+), 8990 deletions(-) create mode 100644 .DS_Store delete mode 100644 .babelrc delete mode 100644 .eslintrc delete mode 100644 .flowconfig create mode 100644 .nycrc delete mode 100644 .travis.yml delete mode 100644 file-cache.js delete mode 100644 file-cache.js.flow delete mode 100644 file-cache.js.map delete mode 100644 gulp/index.js delete mode 100644 gulp/tasks/babel.js delete mode 100644 gulp/tasks/eslint.js delete mode 100644 gulp/tasks/watch.js delete mode 100644 gulpfile.js delete mode 100644 index.js delete mode 100644 index.js.flow delete mode 100644 index.js.map delete mode 100644 package-lock.json create mode 100644 src/file-cache.ts create mode 100644 src/hugo.ts create mode 100644 src/index.ts create mode 100644 src/types.ts create mode 100644 src/updater.ts create mode 100644 src/utils.ts create mode 100644 test/actions.ts create mode 100644 test/feedback.ts create mode 100644 test/fetch.ts rename {tests => test}/file-cache.js (100%) create mode 100644 test/file-cache.ts create mode 100644 test/helpers/init.ts create mode 100644 test/helpers/mock.ts create mode 100644 test/helpers/types.ts create mode 100644 test/hugo.ts create mode 100644 test/matching.ts create mode 100644 test/meta/alfred.ts create mode 100644 test/meta/theme.ts create mode 100644 test/meta/workflow.ts create mode 100644 test/mocks/appcast-invalidversion.xml create mode 100644 test/mocks/appcast-noversion.xml rename {tests => test}/mocks/appcast.xml (89%) create mode 100644 test/output.ts create mode 100644 test/snapshots/feedback.ts.md create mode 100644 test/snapshots/feedback.ts.snap create mode 100644 test/snapshots/matching.ts.md create mode 100644 test/snapshots/matching.ts.snap create mode 100644 test/snapshots/output.ts.md create mode 100644 test/snapshots/output.ts.snap create mode 100644 test/updates/npm.ts create mode 100644 test/updates/packal.ts create mode 100644 test/updates/snapshots/updater.ts.md create mode 100644 test/updates/snapshots/updater.ts.snap create mode 100644 test/updates/updater.ts delete mode 100644 tests/__snapshots__/cache.js.snap delete mode 100644 tests/__snapshots__/file-cache.js.snap delete mode 100644 tests/__snapshots__/output.js.snap delete mode 100644 tests/_init.js delete mode 100644 tests/cache.js delete mode 100644 tests/fetch.js delete mode 100644 tests/index.js delete mode 100644 tests/matching.js delete mode 100644 tests/output.js delete mode 100644 tests/updates.js create mode 100644 tsconfig.dist.json create mode 100644 tsconfig.json create mode 100644 tslint.json delete mode 100644 updater.js delete mode 100644 updater.js.flow delete mode 100644 updater.js.map create mode 100644 yarn.lock diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..9bc15b6920bb330e92f0d4c657fbdac720b62c04 GIT binary patch literal 6148 zcmeHKF-`+P47A~jlW0;>?icvMDhe;)10;klC`btsDIf);fE17d7b{SmbiBK`f{0Q;3S6rK{5~`|u@_E>@#(-4 zBLHwfI1KxkC4h|qU@x2!5rKJ9fl2imF+Ayrx612$Djo>oh|QuWr^%dyus_%ob2UvL`sLBSI3 k7#Qss2e#w;NXop%J)ZZ%DKY4X2OX%N0qP=?0{^YRH(q5Lx&QzG literal 0 HcmV?d00001 diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 4518eca..0000000 --- a/.babelrc +++ /dev/null @@ -1,19 +0,0 @@ -{ - "comments": false, - "compact": true, - "plugins": [ - "transform-class-properties", - "transform-runtime" - ], - "presets": [ - "flow", - [ - "env", - { - "targets": { - "node": 4 - } - } - ] - ] -} diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index e156333..0000000 --- a/.eslintrc +++ /dev/null @@ -1,24 +0,0 @@ -{ - "parser": "babel-eslint", - "extends": [ - "xo", - "plugin:ava/recommended" - ], - "env": { - "node": true - }, - "rules": { - "indent": [ - "error", - 4, - { - "SwitchCase": 1 - } - ], - "flowtype-errors/show-errors": 2 - }, - "plugins": [ - "flowtype-errors", - "ava" - ] -} diff --git a/.flowconfig b/.flowconfig deleted file mode 100644 index c5d1a06..0000000 --- a/.flowconfig +++ /dev/null @@ -1,8 +0,0 @@ -[ignore] - -[include] - -[libs] - -[options] -unsafe.enable_getters_and_setters=true diff --git a/.gitignore b/.gitignore index c2658d7..aba05ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,7 @@ node_modules/ +yarn-error.log + +/.nyc_output +/build +/coverage +/dist diff --git a/.nycrc b/.nycrc new file mode 100644 index 0000000..e8a68b2 --- /dev/null +++ b/.nycrc @@ -0,0 +1,14 @@ +{ + "extension": [ + ".js", + ".ts" + ], + "include": ["src/**/*.ts", "build/src/**/*.js"], + "reporter": [ + "text", + "html" + ], + "cache": true, + "sourceMap": true, + "instrument": true +} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a8f76a7..0000000 --- a/.travis.yml +++ /dev/null @@ -1,20 +0,0 @@ -language: node_js -node_js: - - "7" - - "6" - - "4" -env: - - CXX=g++-4.8 -addons: - apt: - sources: - - ubuntu-toolchain-r-test - packages: - - g++-4.8 - -before_install: - - npm install -g npm@latest - -before_script: - - npm install -g gulp - - npm run build diff --git a/LICENSE b/LICENSE index a4a052f..0df0230 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2017, Cloudstek All rights reserved. +Copyright (c) 2017-2019, Cloudstek All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/README.md b/README.md index 81c1646..5e925c4 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,8 @@ ## Prerequisites -* NodeJS 4 or higher -* Alfred 3 with [paid powerpack addon](https://www.alfredapp.com/powerpack/buy/) +* NodeJS 8 or higher +* Alfred 3.4.1+ with [paid powerpack addon](https://www.alfredapp.com/powerpack/buy/) ## Installing diff --git a/file-cache.js b/file-cache.js deleted file mode 100644 index de6c2c4..0000000 --- a/file-cache.js +++ /dev/null @@ -1,2 +0,0 @@ -'use strict';var _regenerator=require('babel-runtime/regenerator');var _regenerator2=_interopRequireDefault(_regenerator);var _asyncToGenerator2=require('babel-runtime/helpers/asyncToGenerator');var _asyncToGenerator3=_interopRequireDefault(_asyncToGenerator2);var _getPrototypeOf=require('babel-runtime/core-js/object/get-prototype-of');var _getPrototypeOf2=_interopRequireDefault(_getPrototypeOf);var _possibleConstructorReturn2=require('babel-runtime/helpers/possibleConstructorReturn');var _possibleConstructorReturn3=_interopRequireDefault(_possibleConstructorReturn2);var _inherits2=require('babel-runtime/helpers/inherits');var _inherits3=_interopRequireDefault(_inherits2);var _classCallCheck2=require('babel-runtime/helpers/classCallCheck');var _classCallCheck3=_interopRequireDefault(_classCallCheck2);var _createClass2=require('babel-runtime/helpers/createClass');var _createClass3=_interopRequireDefault(_createClass2);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}var crypto=require('crypto');var EventEmitter=require('events').EventEmitter;var fs=require('fs-extra');var path=require('path');var FileCacheStore=function(){function FileCacheStore(){(0,_classCallCheck3.default)(this,FileCacheStore);this._contents={};}(0,_createClass3.default)(FileCacheStore,[{key:'store',value:function store(value){this._contents=value;return this;}},{key:'set',value:function set(key,value){this._contents[key]=value;return this;}},{key:'contents',get:function get(){return this._contents;}}]);return FileCacheStore;}();var FileCache=function(_EventEmitter){(0,_inherits3.default)(FileCache,_EventEmitter);function FileCache(filePath,cacheName,cacheDir){(0,_classCallCheck3.default)(this,FileCache);var _this=(0,_possibleConstructorReturn3.default)(this,(FileCache.__proto__||(0,_getPrototypeOf2.default)(FileCache)).call(this));_this.filePath=filePath;_this.cacheName=cacheName;_this.cacheDir=cacheDir;_this.isCleaning=false;return _this;}(0,_createClass3.default)(FileCache,[{key:'_fileExists',value:function _fileExists(path){try{fs.statSync(path);return true;}catch(err){return false;}}},{key:'get',value:function get(){if(this._fileExists(this.filePath)){var eventResult=new FileCacheStore();var file=fs.readFileSync(this.filePath,'utf8');var hash=crypto.createHash('sha1').update(file,'utf8').digest('hex');if(!this.cacheDir){this.emit('change',eventResult,file,hash);return eventResult.contents;}var cachePath=path.join(this.cacheDir,this.cacheName,hash);if(this._fileExists(cachePath)){return fs.readJsonSync(cachePath,{throws:false});}fs.ensureDirSync(path.dirname(cachePath));this.emit('change',eventResult,file,hash);fs.writeJsonSync(cachePath,eventResult.contents);return eventResult.contents;}return null;}},{key:'clearCache',value:function(){var _ref=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(){return _regenerator2.default.wrap(function _callee$(_context){while(1){switch(_context.prev=_context.next){case 0:if(this.cacheDir){_context.next=2;break;}return _context.abrupt('return');case 2:return _context.abrupt('return',fs.emptyDir(path.join(this.cacheDir,this.cacheName)));case 3:case'end':return _context.stop();}}},_callee,this);}));function clearCache(){return _ref.apply(this,arguments);}return clearCache;}()},{key:'clearCacheSync',value:function clearCacheSync(){if(!this.cacheDir){return;}return fs.emptyDirSync(path.join(this.cacheDir,this.cacheName));}}]);return FileCache;}(EventEmitter);module.exports=FileCache; -//# sourceMappingURL=file-cache.js.map diff --git a/file-cache.js.flow b/file-cache.js.flow deleted file mode 100644 index b03c05c..0000000 --- a/file-cache.js.flow +++ /dev/null @@ -1,165 +0,0 @@ -// @flow - -const crypto = require('crypto'); -const EventEmitter = require('events').EventEmitter; -const fs = require('fs-extra'); -const path = require('path'); - -/** - * FileCache - * Simple in-memory key/value pair storage to store event listener results - */ -class FileCacheStore { - /** - * Cache contents - * @type {Object|Array.} - */ - _contents: Object|Array; - - /** - * FileCacheStore constructor - * @constructor - */ - constructor() { - this._contents = {}; - } - - /** - * Get cache contents - * @return {Object|Array.} - */ - get contents() { - return this._contents; - } - - /** - * Set cache contents to value - * @param {Object|Arrray.} value - * @return {FileCacheStore} - */ - store(value: Object|Array): FileCacheStore { - this._contents = value; - return this; - } - - /** - * Set a cache value - * @param {any} key Key - * @param {any} value Value - * @return {FileCacheStore} - */ - set(key: any, value: any): FileCacheStore { - this._contents[key] = value; - return this; - } -} - -/** - * FileCache - */ -class FileCache extends EventEmitter { - filePath: string; - cacheName: string; - cacheDir: string; - isCleaning: boolean; - - /** - * FileCache constructor - * @param {string} filePath File to process and check for changes - * @param {string} cacheName Unique name for cache directory - * @param {string} cacheDir Cache base directory - * @constructor - */ - constructor(filePath: string, cacheName: string, cacheDir: string) { - super(); - - this.filePath = filePath; - this.cacheName = cacheName; - this.cacheDir = cacheDir; - this.isCleaning = false; - } - - /** - * Check if file exists - * @param {string} path - * @return {boolean} - */ - _fileExists(path: string): boolean { - try { - fs.statSync(path); - return true; - } catch (err) { - return false; - } - } - - /** - * Get cached contents - * @return {Object|Array.|null} - */ - get(): Object|Array|null { - if (this._fileExists(this.filePath)) { - // Create simple in-memory store for event listener results - let eventResult = new FileCacheStore(); - - // Read file - let file = fs.readFileSync(this.filePath, 'utf8'); - - // Calculate file hash - let hash = crypto.createHash('sha1').update(file, 'utf8').digest('hex'); - - // Always call callback when cache dir is not set - if (!this.cacheDir) { - this.emit('change', eventResult, file, hash); - return eventResult.contents; - } - - // Get cache path - let cachePath = path.join(this.cacheDir, this.cacheName, hash); - - // Return cached data if found - if (this._fileExists(cachePath)) { - return fs.readJsonSync(cachePath, {throws: false}); - } - - // Create cache directory if it doesn't exist - fs.ensureDirSync(path.dirname(cachePath)); - - // Get processed data - this.emit('change', eventResult, file, hash); - - // Write cache - fs.writeJsonSync(cachePath, eventResult.contents); - return eventResult.contents; - } - - return null; - } - - /** - * Clear cache - * @async - * @return {Promise} - */ - async clearCache() { - if (!this.cacheDir) { - return; - } - - return fs.emptyDir(path.join(this.cacheDir, this.cacheName)); - } - - /** - * Clear cache synchronously - * @return {void} - */ - clearCacheSync() { - if (!this.cacheDir) { - return; - } - - return fs.emptyDirSync(path.join(this.cacheDir, this.cacheName)); - } -} - -module.exports = FileCache; diff --git a/file-cache.js.map b/file-cache.js.map deleted file mode 100644 index 6f83ab3..0000000 --- a/file-cache.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["file-cache.js.flow"],"names":["crypto","require","EventEmitter","fs","path","FileCacheStore","_contents","value","key","FileCache","filePath","cacheName","cacheDir","isCleaning","statSync","err","_fileExists","eventResult","file","readFileSync","hash","createHash","update","digest","emit","contents","cachePath","join","readJsonSync","throws","ensureDirSync","dirname","writeJsonSync","emptyDir","emptyDirSync","module","exports"],"mappings":"s/BAEA,GAAMA,QAASC,QAAQ,QAAR,CAAf,CACA,GAAMC,cAAeD,QAAQ,QAAR,EAAkBC,YAAvC,CACA,GAAMC,IAAKF,QAAQ,UAAR,CAAX,CACA,GAAMG,MAAOH,QAAQ,MAAR,CAAb,C,GAMMI,e,YAWF,yBAAc,mDACV,KAAKC,SAAL,CAAiB,EAAjB,CACH,C,4EAeKC,K,CAA6C,CAC/C,KAAKD,SAAL,CAAiBC,KAAjB,CACA,MAAO,KAAP,CACH,C,gCAQGC,G,CAAUD,K,CAA4B,CACtC,KAAKD,SAAL,CAAeE,GAAf,EAAsBD,KAAtB,CACA,MAAO,KAAP,CACH,C,oCAvBc,CACX,MAAO,MAAKD,SAAZ,CACH,C,iCA2BCG,U,yEAaF,mBAAYC,QAAZ,CAA8BC,SAA9B,CAAiDC,QAAjD,CAAmE,gLAG/D,MAAKF,QAAL,CAAgBA,QAAhB,CACA,MAAKC,SAAL,CAAiBA,SAAjB,CACA,MAAKC,QAAL,CAAgBA,QAAhB,CACA,MAAKC,UAAL,CAAkB,KAAlB,CAN+D,aAOlE,C,mFAOWT,I,CAAuB,CAC/B,GAAI,CACAD,GAAGW,QAAH,CAAYV,IAAZ,EACA,MAAO,KAAP,CACH,CAAC,MAAOW,GAAP,CAAY,CACV,MAAO,MAAP,CACH,CACJ,C,iCAMgC,CAC7B,GAAI,KAAKC,WAAL,CAAiB,KAAKN,QAAtB,CAAJ,CAAqC,CAEjC,GAAIO,aAAc,GAAIZ,eAAJ,EAAlB,CAGA,GAAIa,MAAOf,GAAGgB,YAAH,CAAgB,KAAKT,QAArB,CAA+B,MAA/B,CAAX,CAGA,GAAIU,MAAOpB,OAAOqB,UAAP,CAAkB,MAAlB,EAA0BC,MAA1B,CAAiCJ,IAAjC,CAAuC,MAAvC,EAA+CK,MAA/C,CAAsD,KAAtD,CAAX,CAGA,GAAI,CAAC,KAAKX,QAAV,CAAoB,CAChB,KAAKY,IAAL,CAAU,QAAV,CAAoBP,WAApB,CAAiCC,IAAjC,CAAuCE,IAAvC,EACA,MAAOH,aAAYQ,QAAnB,CACH,CAGD,GAAIC,WAAYtB,KAAKuB,IAAL,CAAU,KAAKf,QAAf,CAAyB,KAAKD,SAA9B,CAAyCS,IAAzC,CAAhB,CAGA,GAAI,KAAKJ,WAAL,CAAiBU,SAAjB,CAAJ,CAAiC,CAC7B,MAAOvB,IAAGyB,YAAH,CAAgBF,SAAhB,CAA2B,CAACG,OAAQ,KAAT,CAA3B,CAAP,CACH,CAGD1B,GAAG2B,aAAH,CAAiB1B,KAAK2B,OAAL,CAAaL,SAAb,CAAjB,EAGA,KAAKF,IAAL,CAAU,QAAV,CAAoBP,WAApB,CAAiCC,IAAjC,CAAuCE,IAAvC,EAGAjB,GAAG6B,aAAH,CAAiBN,SAAjB,CAA4BT,YAAYQ,QAAxC,EACA,MAAOR,aAAYQ,QAAnB,CACH,CAED,MAAO,KAAP,CACH,C,gPAQQ,KAAKb,Q,iGAIHT,GAAG8B,QAAH,CAAY7B,KAAKuB,IAAL,CAAU,KAAKf,QAAf,CAAyB,KAAKD,SAA9B,CAAZ,C,qMAOM,CACb,GAAI,CAAC,KAAKC,QAAV,CAAoB,CAChB,OACH,CAED,MAAOT,IAAG+B,YAAH,CAAgB9B,KAAKuB,IAAL,CAAU,KAAKf,QAAf,CAAyB,KAAKD,SAA9B,CAAhB,CAAP,CACH,C,uBAtGmBT,Y,EAyGxBiC,OAAOC,OAAP,CAAiB3B,SAAjB","file":"file-cache.js","sourcesContent":["// @flow\n\nconst crypto = require('crypto');\nconst EventEmitter = require('events').EventEmitter;\nconst fs = require('fs-extra');\nconst path = require('path');\n\n/**\n * FileCache\n * Simple in-memory key/value pair storage to store event listener results\n */\nclass FileCacheStore {\n /**\n * Cache contents\n * @type {Object|Array.}\n */\n _contents: Object|Array;\n\n /**\n * FileCacheStore constructor\n * @constructor\n */\n constructor() {\n this._contents = {};\n }\n\n /**\n * Get cache contents\n * @return {Object|Array.}\n */\n get contents() {\n return this._contents;\n }\n\n /**\n * Set cache contents to value\n * @param {Object|Arrray.} value\n * @return {FileCacheStore}\n */\n store(value: Object|Array): FileCacheStore {\n this._contents = value;\n return this;\n }\n\n /**\n * Set a cache value\n * @param {any} key Key\n * @param {any} value Value\n * @return {FileCacheStore}\n */\n set(key: any, value: any): FileCacheStore {\n this._contents[key] = value;\n return this;\n }\n}\n\n/**\n * FileCache\n */\nclass FileCache extends EventEmitter {\n filePath: string;\n cacheName: string;\n cacheDir: string;\n isCleaning: boolean;\n\n /**\n * FileCache constructor\n * @param {string} filePath File to process and check for changes\n * @param {string} cacheName Unique name for cache directory\n * @param {string} cacheDir Cache base directory\n * @constructor\n */\n constructor(filePath: string, cacheName: string, cacheDir: string) {\n super();\n\n this.filePath = filePath;\n this.cacheName = cacheName;\n this.cacheDir = cacheDir;\n this.isCleaning = false;\n }\n\n /**\n * Check if file exists\n * @param {string} path\n * @return {boolean}\n */\n _fileExists(path: string): boolean {\n try {\n fs.statSync(path);\n return true;\n } catch (err) {\n return false;\n }\n }\n\n /**\n * Get cached contents\n * @return {Object|Array.|null}\n */\n get(): Object|Array|null {\n if (this._fileExists(this.filePath)) {\n // Create simple in-memory store for event listener results\n let eventResult = new FileCacheStore();\n\n // Read file\n let file = fs.readFileSync(this.filePath, 'utf8');\n\n // Calculate file hash\n let hash = crypto.createHash('sha1').update(file, 'utf8').digest('hex');\n\n // Always call callback when cache dir is not set\n if (!this.cacheDir) {\n this.emit('change', eventResult, file, hash);\n return eventResult.contents;\n }\n\n // Get cache path\n let cachePath = path.join(this.cacheDir, this.cacheName, hash);\n\n // Return cached data if found\n if (this._fileExists(cachePath)) {\n return fs.readJsonSync(cachePath, {throws: false});\n }\n\n // Create cache directory if it doesn't exist\n fs.ensureDirSync(path.dirname(cachePath));\n\n // Get processed data\n this.emit('change', eventResult, file, hash);\n\n // Write cache\n fs.writeJsonSync(cachePath, eventResult.contents);\n return eventResult.contents;\n }\n\n return null;\n }\n\n /**\n * Clear cache\n * @async\n * @return {Promise}\n */\n async clearCache() {\n if (!this.cacheDir) {\n return;\n }\n\n return fs.emptyDir(path.join(this.cacheDir, this.cacheName));\n }\n\n /**\n * Clear cache synchronously\n * @return {void}\n */\n clearCacheSync() {\n if (!this.cacheDir) {\n return;\n }\n\n return fs.emptyDirSync(path.join(this.cacheDir, this.cacheName));\n }\n}\n\nmodule.exports = FileCache;\n"]} \ No newline at end of file diff --git a/gulp/index.js b/gulp/index.js deleted file mode 100644 index 28d4898..0000000 --- a/gulp/index.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict'; -const gulp = require('gulp'); -const util = require('gulp-util'); - -module.exports = tasks => { - tasks.forEach(name => { - const task = require('./tasks/' + name); - - // Task function only - if (typeof task === 'function') { - gulp.task(name, task); - return; - } - - // Task dependencies or task function and dependencies - if (task instanceof Array && task.length > 0) { - // Task function with dependencies - if (task.length >= 2 && task[0] instanceof Array && typeof task[task.length - 1] === 'function') { - gulp.task(name, task[0], task[task.length - 1]); - return; - } - - // Task dependencies only - gulp.task(name, task); - return; - } - - util.log(util.colors.cyan('Task ' + name + ' is not a valid task, please fix!')); - }); - - return gulp; -}; diff --git a/gulp/tasks/babel.js b/gulp/tasks/babel.js deleted file mode 100644 index d3e3f5c..0000000 --- a/gulp/tasks/babel.js +++ /dev/null @@ -1,22 +0,0 @@ -'use strict'; -const fs = require('fs'); -const gulp = require('gulp'); -const babel = require('gulp-babel'); -const rename = require('gulp-rename'); -const sourcemaps = require('gulp-sourcemaps'); - -let task = () => { - let babelrc = JSON.parse(fs.readFileSync('.babelrc', 'utf8') || '{}'); - - return gulp.src(['./**/*.js.flow', '!node_modules', '!node_modules/**']) - .pipe(sourcemaps.init()) - .pipe(babel(babelrc)) - .pipe(rename(path => { - // Fix file extension for double ext files (.js.flow) - path.extname = path.basename.endsWith('.js') ? '' : '.js'; - })) - .pipe(sourcemaps.write('.')) - .pipe(gulp.dest('.')); -}; - -module.exports = [['eslint'], task]; diff --git a/gulp/tasks/eslint.js b/gulp/tasks/eslint.js deleted file mode 100644 index 7b14dae..0000000 --- a/gulp/tasks/eslint.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict'; -const gulp = require('gulp'); -const eslint = require('gulp-eslint'); - -let task = () => { - return gulp.src(['./**/*.js.flow', './tests/*.js', '!node_modules', '!node_modules/**']) - .pipe(eslint()) - .pipe(eslint.format('node_modules/eslint-formatter-pretty')) - .pipe(eslint.failAfterError()); -}; - -module.exports = task; diff --git a/gulp/tasks/watch.js b/gulp/tasks/watch.js deleted file mode 100644 index 373d34f..0000000 --- a/gulp/tasks/watch.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; -const gulp = require('gulp'); - -let task = done => { - gulp.watch(['./**/*.js.flow', '!node_modules', '!node_modules/**'], ['babel']); -}; - -module.exports = [['default'], task]; diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index e09110d..0000000 --- a/gulpfile.js +++ /dev/null @@ -1,13 +0,0 @@ -const gulp = require('./gulp')([ - 'babel', - 'eslint', - 'watch' -]); - -gulp.task('default', [ - 'eslint', - 'babel' -]); - -// Backwards compatibility -gulp.task('build', ['default']); diff --git a/index.js b/index.js deleted file mode 100644 index 845c9d6..0000000 --- a/index.js +++ /dev/null @@ -1,2 +0,0 @@ -'use strict';var _promise=require('babel-runtime/core-js/promise');var _promise2=_interopRequireDefault(_promise);var _regenerator=require('babel-runtime/regenerator');var _regenerator2=_interopRequireDefault(_regenerator);var _asyncToGenerator2=require('babel-runtime/helpers/asyncToGenerator');var _asyncToGenerator3=_interopRequireDefault(_asyncToGenerator2);var _stringify=require('babel-runtime/core-js/json/stringify');var _stringify2=_interopRequireDefault(_stringify);var _assign=require('babel-runtime/core-js/object/assign');var _assign2=_interopRequireDefault(_assign);var _classCallCheck2=require('babel-runtime/helpers/classCallCheck');var _classCallCheck3=_interopRequireDefault(_classCallCheck2);var _createClass2=require('babel-runtime/helpers/createClass');var _createClass3=_interopRequireDefault(_createClass2);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}var CacheConf=require('cache-conf');var Conf=require('conf');var fs=require('fs-extra');var Fuse=require('fuse.js');var got=require('got');var moment=require('moment');var notifier=require('node-notifier');var os=require('os');var path=require('path');var semver=require('semver');var FileCache=require('./file-cache');var updater=require('./updater');var Hugo=function(){function Hugo(){(0,_classCallCheck3.default)(this,Hugo);this._fuseDefaults={keys:['title'],threshold:0.4};this._options={useTmpCache:true,checkUpdates:true,updateSource:'packal',updateInterval:moment.duration(1,'days'),updateNotification:true,updateItem:true};this._outputBuffer={};this.config=new Conf({cwd:this.workflowMeta.data});this.cache=new CacheConf({configName:'cache',cwd:this.workflowMeta.cache,version:this.workflowMeta.version});}(0,_createClass3.default)(Hugo,[{key:'addItem',value:function addItem(item){if(!this._outputBuffer.items){this._outputBuffer.items=[];}if(!item.title){if(this.alfredMeta.debug===true){console.error('Item skipped, missing title.');}return this;}if(item.arg&&typeof item.arg==='object'){var arg=item.arg.arg;var variables=item.arg.variables||{};if(semver.gte(this.alfredMeta.version,'3.4.1')){delete item.arg;if(arg){item.arg=arg;}item.variables=(0,_assign2.default)({},item.variables,variables);}else{if(item.variables&&typeof item.variables==='object'){variables=(0,_assign2.default)({},variables,item.variables);delete item.variables;}item.arg=(0,_stringify2.default)({alfredworkflow:{arg:arg,variables:variables}});}}else if(item.variables&&typeof item.variables==='object'&&semver.lt(this.alfredMeta.version,'3.4.1')){item.arg=(0,_stringify2.default)({alfredworkflow:{arg:item.arg,variables:item.variables}});delete item.variables;}this._outputBuffer.items.push(item);return this;}},{key:'addItems',value:function addItems(items){var _this=this;items.map(function(item){_this.addItem(item);return item;});return this;}},{key:'addVariable',value:function addVariable(key,value){if(!this._outputBuffer.variables){this._outputBuffer.variables={};}this._outputBuffer.variables[key]=value;return this;}},{key:'addVariables',value:function addVariables(variables){if(!this._outputBuffer.variables){this._outputBuffer.variables=variables;return this;}this._outputBuffer.variables=(0,_assign2.default)({},this._outputBuffer.variables,variables);return this;}},{key:'getVariable',value:function getVariable(key){if(!this._outputBuffer.variables){return null;}return this._outputBuffer.variables[key]||null;}},{key:'getVariables',value:function getVariables(){return this._outputBuffer.variables||{};}},{key:'getItemVariable',value:function getItemVariable(item,key){if(semver.gte(this.alfredMeta.version,'3.4.1')){if(item.variables){return item.variables[key]||null;}}else if(item.arg){try{var arg={};var variables={};if(typeof item.arg==='string'){arg=JSON.parse(item.arg);}if(arg.alfredworkflow){variables=arg.alfredworkflow.variables||{};}return variables[key]||null;}catch(e){}}return null;}},{key:'getItemVariables',value:function getItemVariables(item){if(semver.gte(this.alfredMeta.version,'3.4.1')){return item.variables||{};}else if(item.arg){try{var arg={};if(typeof item.arg==='string'){arg=JSON.parse(item.arg);}if(arg.alfredworkflow){return arg.alfredworkflow.variables||{};}return arg.variables||{};}catch(e){}}return{};}},{key:'action',value:function action(keyword,callback){var query=process.argv[2];if(query&&callback&&query===keyword){query=process.argv[3]||'';callback(query);}return this;}},{key:'cacheFile',value:function cacheFile(filePath,cacheName){return new FileCache(filePath,cacheName,this.workflowMeta.cache);}},{key:'checkUpdates',value:function(){var _ref=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(){var _this2=this;return _regenerator2.default.wrap(function _callee$(_context){while(1){switch(_context.prev=_context.next){case 0:if(!(this._options.checkUpdates!==true||this._options.updateItem!==true&&this._options.updateNotification!==true)){_context.next=2;break;}return _context.abrupt('return');case 2:_context.next=4;return updater.checkUpdates(this._options.updateSource,this._options.updateInterval).catch(function(err){console.error(err);return;}).then(function(result){if(!result){return;}var current=_this2.workflowMeta.version;var latest=result.version;if(!semver.valid(current)){console.error(`Version ${current} is not a valid version number.`);return;}if(!semver.valid(latest)){console.error(`Could not determine latest version number.`);return;}if(semver.gt(latest,current)){if(result.checkedOnline===true&&_this2._options.updateNotification===true){_this2.notify({message:`Workflow version ${latest} available. Current version: ${current}.`});}if(_this2._options.updateItem===true){_this2.addItem({title:`Workflow update available!`,subtitle:`Version ${latest} is available. Current version: ${current}.`,icon:_this2.workflowMeta.icon,arg:result.url,variables:{task:'wfUpdate'}});}}});case 4:case'end':return _context.stop();}}},_callee,this);}));function checkUpdates(){return _ref.apply(this,arguments);}return checkUpdates;}()},{key:'clearCache',value:function(){var _ref2=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2(){return _regenerator2.default.wrap(function _callee2$(_context2){while(1){switch(_context2.prev=_context2.next){case 0:if(!this.workflowMeta.cache){_context2.next=2;break;}return _context2.abrupt('return',fs.emptyDir(this.workflowMeta.cache));case 2:case'end':return _context2.stop();}}},_callee2,this);}));function clearCache(){return _ref2.apply(this,arguments);}return clearCache;}()},{key:'clearCacheSync',value:function clearCacheSync(){if(this.workflowMeta.cache){return fs.emptyDirSync(this.workflowMeta.cache);}}},{key:'filterItems',value:function filterItems(query){var options=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};options=(0,_assign2.default)({},this._fuseDefaults,options);if(query.length===0){return this;}var fuse=new Fuse(this._outputBuffer.items,options);this._outputBuffer.items=fuse.search(query)||[];return this;}},{key:'options',value:function options(_options){var cacheDirChanged='useTmpCache'in _options&&_options.useTmpCache!==this._options.useTmpCache;if(_options.updateInterval&&!moment.isDuration(_options.updateInterval)){if(_options.updateInterval<1){delete _options.updateInterval;}else{_options.updateInterval=moment.duration(_options.updateInterval,'seconds')||moment.duration(1,'days');}}this._options=(0,_assign2.default)({},this._options,_options);if(cacheDirChanged){this.cache=new CacheConf({configName:'cache',cwd:this.workflowMeta.cache,version:this.workflowMeta.version});}return this;}},{key:'matches',value:function matches(candidates,query){var options=arguments.length>2&&arguments[2]!==undefined?arguments[2]:{};options=(0,_assign2.default)({},this._fuseDefaults,options);if(query.length===0){return candidates;}var fuse=new Fuse(candidates,options);return fuse.search(query)||[];}},{key:'notify',value:function(){var _ref3=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee3(options){var _this3=this;return _regenerator2.default.wrap(function _callee3$(_context3){while(1){switch(_context3.prev=_context3.next){case 0:return _context3.abrupt('return',new _promise2.default(function(resolve,reject){var defaults={title:('Alfred '+_this3.workflowMeta.name).trim(),sender:'com.runningwithcrayons.Alfred-3',contentImage:_this3.workflowMeta.icon};options=(0,_assign2.default)({},defaults,options);notifier.notify(options,function(err,response){if(err){reject(err);return;}resolve(response);});}));case 1:case'end':return _context3.stop();}}},_callee3,this);}));function notify(_x3){return _ref3.apply(this,arguments);}return notify;}()},{key:'rerun',value:function rerun(value){value=parseFloat(value);if(value&&value>0.1&&value<=5){this._rerun=value;}return this;}},{key:'feedback',value:function(){var _ref4=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee4(){var output;return _regenerator2.default.wrap(function _callee4$(_context4){while(1){switch(_context4.prev=_context4.next){case 0:if(this._rerun){this._outputBuffer.rerun=this._rerun;}if(!(this._options.checkUpdates===true)){_context4.next=4;break;}_context4.next=4;return this.checkUpdates().catch(function(){});case 4:output=this._outputBuffer;console.log((0,_stringify2.default)(output,null,'\t'));this._outputBuffer={};return _context4.abrupt('return',output);case 8:case'end':return _context4.stop();}}},_callee4,this);}));function feedback(){return _ref4.apply(this,arguments);}return feedback;}()},{key:'fetch',value:function(){var _ref5=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee5(url){var _this4=this;var options=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var cacheAge=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var cacheResult;return _regenerator2.default.wrap(function _callee5$(_context5){while(1){switch(_context5.prev=_context5.next){case 0:options=(0,_assign2.default)({},{json:true},options);if(!(cacheAge&&cacheAge>0)){_context5.next=5;break;}cacheResult=this.cache.get(url);if(!cacheResult){_context5.next=5;break;}return _context5.abrupt('return',cacheResult);case 5:return _context5.abrupt('return',got(url,options).then(function(response){if(cacheAge&&cacheAge>0){_this4.cache.set(url,response.body,{maxAge:cacheAge*1000});}return response.body;}));case 6:case'end':return _context5.stop();}}},_callee5,this);}));function fetch(_x6){return _ref5.apply(this,arguments);}return fetch;}()},{key:'alfredMeta',get:function get(){var version=process.env.alfred_version||'0.0.0';if(!semver.valid(version)){version+='.0';if(!semver.valid(version)&&process.env.alfred_debug==='1'){console.error(`Invalid Alfred version: ${version}`);version='0.0.0';}}var data={version:version,theme:process.env.alfred_theme,themeFile:'',themeBackground:process.env.alfred_theme_background,themeSelectionBackground:process.env.alfred_theme_selection_background,themeSubtext:parseFloat(process.env.alfred_theme_subtext),preferences:process.env.alfred_preferences,preferencesLocalHash:process.env.alfred_preferences_localhash,debug:process.env.alfred_debug==='1'};if(process.env.HOME&&data.theme){var homedir=process.env.HOME||'';var themeFile=path.resolve(homedir,'Library','Application Support','Alfred '+semver.major(version),'Alfred.alfredpreferences','themes',data.theme,'theme.json');try{fs.statSync(themeFile);data.themeFile=themeFile;}catch(e){if(process.env.alfred_debug==='1'){console.error(`Could not find theme file "${themeFile}"`);}}}return data;}},{key:'alfredTheme',get:function get(){var themeFile=this.alfredMeta.themeFile;if(!themeFile){return{};}return fs.readJsonSync(themeFile,{throws:false})||{};}},{key:'input',get:function get(){if(process.argv.length>3){return process.argv[3]||'';}return process.argv[2]||'';}},{key:'itemCount',get:function get(){if(this.outputBuffer&&this.outputBuffer.items){return this.outputBuffer.items.length;}return 0;}},{key:'outputBuffer',get:function get(){return this._outputBuffer;}},{key:'workflowMeta',get:function get(){var cacheDir=process.env.alfred_workflow_cache;var bundleId=process.env.alfred_workflow_bundleid;if(bundleId&&this._options.useTmpCache===true){cacheDir=path.resolve(path.join(os.tmpdir(),bundleId));}return{name:process.env.alfred_workflow_name,version:process.env.alfred_workflow_version,uid:process.env.alfred_workflow_uid,bundleId:bundleId,data:process.env.alfred_workflow_data,cache:cacheDir,icon:path.join(process.cwd(),'icon.png')};}}]);return Hugo;}();module.exports=new Hugo(); -//# sourceMappingURL=index.js.map diff --git a/index.js.flow b/index.js.flow deleted file mode 100644 index 9d87a97..0000000 --- a/index.js.flow +++ /dev/null @@ -1,717 +0,0 @@ -// @flow - -const CacheConf = require('cache-conf'); -const Conf = require('conf'); -const fs = require('fs-extra'); -const Fuse = require('fuse.js'); -const got = require('got'); -const moment = require('moment'); -const notifier = require('node-notifier'); -const os = require('os'); -const path = require('path'); -const semver = require('semver'); - -const FileCache = require('./file-cache'); -const updater = require('./updater'); - -/** - * Hugo - */ -class Hugo { - /** - * FuseJS defaults - * @see https://github.com/krisk/fuse#options - * @type {Object} - */ - _fuseDefaults: Object; - - /** - * Hugo options - * @type {Object} - */ - _options: Object; - - /** - * Output buffer - * @type {Object} - */ - _outputBuffer: Object; - - /** - * Refresh (rerun) interval in seconds - * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json - * @type {number|null} - */ - _rerun: ?number; - - /** - * Cache store - * @see https://www.npmjs.com/package/cache-conf - * @type {CacheConf} - */ - cache: CacheConf; - - /** - * Configuration store - * @see https://www.npmjs.com/package/conf - * @type {Conf} - */ - config: Conf; - - /** - * Hugo constructor - * @constructor - */ - constructor() { - // Set defaults for FuseJS - this._fuseDefaults = { - keys: ['title'], - threshold: 0.4 - }; - - // Save options - this._options = { - useTmpCache: true, - checkUpdates: true, - updateSource: 'packal', - updateInterval: moment.duration(1, 'days'), - updateNotification: true, - updateItem: true - }; - - // Initialize output buffer - this._outputBuffer = {}; - - // Configure config store - this.config = new Conf({ - cwd: this.workflowMeta.data - }); - - // Configure cache store - this.cache = new CacheConf({ - configName: 'cache', - cwd: this.workflowMeta.cache, - version: this.workflowMeta.version - }); - } - - /** - * Alfred metadata - * @return {Object} - */ - get alfredMeta(): Object { - let version: string = process.env.alfred_version || '0.0.0'; - - // Check Alfred version for missing patch version (e.g. 3.4 is invalid, should be 3.4.0) - if (!semver.valid(version)) { - version += '.0'; - - // Check if adding .0 to the end makes a valid version string (eg. in case of 3.4) - if (!semver.valid(version) && process.env.alfred_debug === '1') { - console.error(`Invalid Alfred version: ${version}`); - version = '0.0.0'; - } - } - - // Gather environment information - let data: Object = { - version: version, - theme: process.env.alfred_theme, - themeFile: '', - themeBackground: process.env.alfred_theme_background, - themeSelectionBackground: process.env.alfred_theme_selection_background, - themeSubtext: parseFloat(process.env.alfred_theme_subtext), - preferences: process.env.alfred_preferences, - preferencesLocalHash: process.env.alfred_preferences_localhash, - debug: process.env.alfred_debug === '1' - }; - - // Find and load curent Alfred theme file - if (process.env.HOME && data.theme) { - let homedir: string = process.env.HOME || ''; - - let themeFile = path.resolve(homedir, 'Library', 'Application Support', 'Alfred ' + semver.major(version), - 'Alfred.alfredpreferences', 'themes', data.theme, 'theme.json'); - - try { - fs.statSync(themeFile); - data.themeFile = themeFile; - } catch (e) { - if (process.env.alfred_debug === '1') { - console.error(`Could not find theme file "${themeFile}"`); - } - } - } - - return data; - } - - /** - * Alfred theme - * @return {Object} - */ - get alfredTheme(): Object { - let themeFile = this.alfredMeta.themeFile; - - if (!themeFile) { - return {}; - } - - return fs.readJsonSync(themeFile, {throws: false}) || {}; - } - - /** - * Alfred user input - * @return {string} - */ - get input(): string { - if (process.argv.length > 3) { - return process.argv[3] || ''; - } - return process.argv[2] || ''; - } - - /** - * Number of Alfred items in the current output buffer - * @return {number} - */ - get itemCount(): number { - if (this.outputBuffer && this.outputBuffer.items) { - return this.outputBuffer.items.length; - } - - return 0; - } - - /** - * Current output buffer - * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json - * @return {Object} Object to be output and interpreted by Alfred - */ - get outputBuffer(): Object { - return this._outputBuffer; - } - - /** - * Workflow metadata - * @return {Object} - */ - get workflowMeta(): Object { - let cacheDir = process.env.alfred_workflow_cache; - let bundleId = process.env.alfred_workflow_bundleid; - - if (bundleId && this._options.useTmpCache === true) { - cacheDir = path.resolve(path.join(os.tmpdir(), bundleId)); - } - - return { - name: process.env.alfred_workflow_name, - version: process.env.alfred_workflow_version, - uid: process.env.alfred_workflow_uid, - bundleId: bundleId, - data: process.env.alfred_workflow_data, - cache: cacheDir, - icon: path.join(process.cwd(), 'icon.png') - }; - } - - /** - * Add item to output buffer - * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json - * @param {Object} item Item to add - * @return {Hugo} - */ - addItem(item: Object): Hugo { - if (!this._outputBuffer.items) { - this._outputBuffer.items = []; - } - - // Require item title - if (!item.title) { - if (this.alfredMeta.debug === true) { - console.error('Item skipped, missing title.'); - } - return this; - } - - // Parse item variables - if (item.arg && typeof item.arg === 'object') { - let arg = item.arg.arg; - let variables = item.arg.variables || {}; - - if (semver.gte(this.alfredMeta.version, '3.4.1')) { - // Delete item arg - delete item.arg; - - // Only add arg when there is one - if (arg) { - item.arg = arg; - } - - // Item variables - item.variables = Object.assign({}, item.variables, variables); - } else { - // Merge item.variables (new style) with item.arg.variables (old style) - if (item.variables && typeof item.variables === 'object') { - variables = Object.assign({}, variables, item.variables); - delete item.variables; - } - - // Build item arg (old style) - item.arg = JSON.stringify({ - alfredworkflow: { - arg: arg, - variables: variables - } - }); - } - } else if (item.variables && typeof item.variables === 'object' && semver.lt(this.alfredMeta.version, '3.4.1')) { - // Build item arg (old style) with new style item variables - item.arg = JSON.stringify({ - alfredworkflow: { - arg: item.arg, - variables: item.variables - } - }); - - delete item.variables; - } - - // Add item to output buffer - this._outputBuffer.items.push(item); - - return this; - } - - /** - * Add items to output buffer - * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json - * @param {Array.} items List of items to add - * @return {Hugo} - */ - addItems(items: Array): Hugo { - items.map(item => { - this.addItem(item); - return item; - }); - - return this; - } - - /** - * Add session variable to output buffer - * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json - * @param {string} key Variable key - * @param {string} value Variable value - * @return {Hugo} - */ - addVariable(key: string, value: string): Hugo { - if (!this._outputBuffer.variables) { - this._outputBuffer.variables = {}; - } - - this._outputBuffer.variables[key] = value; - - return this; - } - - /** - * Add session variables to output buffer - * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json/ - * @param {Object} variables List of variables to add - * @return {Hugo} - */ - addVariables(variables: Object): Hugo { - if (!this._outputBuffer.variables) { - this._outputBuffer.variables = variables; - return this; - } - - this._outputBuffer.variables = Object.assign({}, this._outputBuffer.variables, variables); - - return this; - } - - /** - * Get session variable from output buffer - * @param {string} key Variable key - * @return {string|null} Variable value - */ - getVariable(key: string): ?string { - if (!this._outputBuffer.variables) { - return null; - } - - return this._outputBuffer.variables[key] || null; - } - - /** - * Get session variables from output buffer - * @return {Object} Variables - */ - getVariables(): Object { - return this._outputBuffer.variables || {}; - } - - /** - * Get item variable - * @param {Object} item - * @param {string} key Variable key - * @return {string|null} Variable value - */ - getItemVariable(item: Object, key: string): ?string { - if (semver.gte(this.alfredMeta.version, '3.4.1')) { - if (item.variables) { - return item.variables[key] || null; - } - } else if (item.arg) { - try { - let arg = {}; - let variables = {}; - - if (typeof item.arg === 'string') { - arg = JSON.parse(item.arg); - } - - if (arg.alfredworkflow) { - variables = arg.alfredworkflow.variables || {}; - } - - return variables[key] || null; - } catch (e) {} - } - - return null; - } - - /** - * Get item variables - * - * As of Alfred 3.4.1 item variables are handled differently (properly). This method makes it easier to get the - * variables of an item without having to deal with different versions. - * - * @param {Object} item - * @return {Object} Item variables - */ - getItemVariables(item: Object): Object { - if (semver.gte(this.alfredMeta.version, '3.4.1')) { - return item.variables || {}; - } else if (item.arg) { - try { - let arg = {}; - - if (typeof item.arg === 'string') { - arg = JSON.parse(item.arg); - } - - if (arg.alfredworkflow) { - return arg.alfredworkflow.variables || {}; - } - - return arg.variables || {}; - } catch (e) {} - } - - return {}; - } - - /** - * Run a callback when first script argument matches keyword. Callback will have third argument as query parameter. - * @example node index.js myaction "my query" - * @param {string} keyword Action name - * @param {Function} callback Callback to execute when query matches action name - * @return {Hugo} - */ - action(keyword: string, callback: (query: string) => void): Hugo { - let query: string = process.argv[2]; - - if (query && callback && query === keyword) { - query = process.argv[3] || ''; - callback(query); - } - - return this; - } - - /** - * Cache processed data - * This allows you to read and process the data once, then storing it in cache until the file has changed again. - * - * @param {string} filepath File path - * @param {string} cacheName Cache name (must be unique for each file) - * @return {FileCache} - */ - cacheFile(filePath: string, cacheName: string): FileCache { - return new FileCache(filePath, cacheName, this.workflowMeta.cache); - } - - /** - * Check for updates and notify the user - * @async - * @return {Promise} - */ - async checkUpdates() { - // No need to check if we're not showing anything, duh. - if (this._options.checkUpdates !== true || - (this._options.updateItem !== true && this._options.updateNotification !== true)) { - return; - } - - await updater.checkUpdates(this._options.updateSource, this._options.updateInterval) - .catch(err => { - console.error(err); - return; - }) - .then(result => { - if (!result) { - return; - } - - // Version information - let current: string = this.workflowMeta.version; - let latest: string = result.version; - - if (!semver.valid(current)) { - console.error(`Version ${current} is not a valid version number.`); - return; - } - - if (!semver.valid(latest)) { - console.error(`Could not determine latest version number.`); - return; - } - - // Display notification - if (semver.gt(latest, current)) { - if (result.checkedOnline === true && this._options.updateNotification === true) { - this.notify({ - message: `Workflow version ${latest} available. Current version: ${current}.` - }); - } - if (this._options.updateItem === true) { - this.addItem({ - title: `Workflow update available!`, - subtitle: `Version ${latest} is available. Current version: ${current}.`, - icon: this.workflowMeta.icon, - arg: result.url, - variables: { - task: 'wfUpdate' - } - }); - } - } - }); - } - - /** - * Clear cache - * @async - * @return {Promise} - */ - async clearCache() { - if (this.workflowMeta.cache) { - return fs.emptyDir(this.workflowMeta.cache); - } - } - - /** - * Clear cache (sync) - * @return {void} - */ - clearCacheSync() { - if (this.workflowMeta.cache) { - return fs.emptyDirSync(this.workflowMeta.cache); - } - } - - /** - * Filter added items (output buffer) with fuse.js - * @see http://fusejs.io - * @param {string} query Search string - * @param {Object} options fuse.js options - * @return {Hugo} - */ - filterItems(query: string, options: Object = {}): Hugo { - options = Object.assign({}, this._fuseDefaults, options); - - if (query.length === 0) { - return this; - } - - // Create fuse.js fuzzy search object - let fuse = new Fuse(this._outputBuffer.items, options); - - // Set output buffer to matching items - this._outputBuffer.items = fuse.search(query) || []; - - return this; - } - - /** - * Set Hugo options - * @param {Object} options Options to set - * @return {Hugo} - */ - options(options: Object): Hugo { - let cacheDirChanged = 'useTmpCache' in options && options.useTmpCache !== this._options.useTmpCache; - - // Convert updateInterval to moment.Duration object - if (options.updateInterval && !moment.isDuration(options.updateInterval)) { - if (options.updateInterval < 1) { - delete options.updateInterval; - } else { - options.updateInterval = moment.duration(options.updateInterval, 'seconds') || moment.duration(1, 'days'); - } - } - - // Update options - this._options = Object.assign({}, this._options, options); - - // Update cache dir - if (cacheDirChanged) { - this.cache = new CacheConf({ - configName: 'cache', - cwd: this.workflowMeta.cache, - version: this.workflowMeta.version - }); - } - - return this; - } - - /** - * Filter list of candidates with fuse.js - * @see http://fusejs.io - * @param {Array.} candidates Input data - * @param {string} query Search string - * @param {Object} options fuse.js options - * @return {Array.} - */ - matches(candidates: Array, query: string, options: Object = {}): Array { - options = Object.assign({}, this._fuseDefaults, options); - - if (query.length === 0) { - return candidates; - } - - // Create fuse.js fuzzy search object - let fuse = new Fuse(candidates, options); - - // Return results - return fuse.search(query) || []; - } - - /** - * Send a notification - * - * Notification title defaults to the Workflow name, or when not available to 'Alfred'. You can adjust all the options - * that node-notifier supports. Please see their documentation for available options. - * - * @see https://github.com/mikaelbr/node-notifier - * @param {Object} options Notification options - * @return {Promise} Notifier response - */ - async notify(options: Object) { - return new Promise((resolve, reject) => { - let defaults = { - title: ('Alfred ' + this.workflowMeta.name).trim(), - sender: 'com.runningwithcrayons.Alfred-3', - contentImage: this.workflowMeta.icon - }; - - // Set options - options = Object.assign({}, defaults, options); - - // Notify - notifier.notify(options, (err, response) => { - if (err) { - reject(err); - return; - } - - resolve(response); - }); - }); - } - - /** - * Set rerun parameter - * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json - * @param {number} value Interval to rerun the script when idle - * @return {Hugo} - */ - rerun(value: number): Hugo { - value = parseFloat(value); - - if (value && value > 0.1 && value <= 5) { - this._rerun = value; - } - - return this; - } - - /** - * Flush the output buffer so Alfred shows our items - * @async - */ - async feedback() { - if (this._rerun) { - this._outputBuffer.rerun = this._rerun; - } - - // Check for updates - if (this._options.checkUpdates === true) { - await this.checkUpdates() - .catch(() => {}); - } - - let output = this._outputBuffer; - - // Output JSON - console.log(JSON.stringify(output, null, '\t')); - - // Reset output buffer - this._outputBuffer = {}; - - return output; - } - - /** - * Fetch url and parse JSON. Useful for REST APIs. - * @see https://www.npmjs.com/package/got - * @param {string} url Url to request - * @param {Object} options http.request options - * @param {number|null} cacheAge Cache lifetime (in seconds), above 0 to enable or null to disable. - * @return {Object|string} - * @async - */ - async fetch(url: string, options: Object = {}, cacheAge: ?number = null): Object|string { - // Set default options - options = Object.assign({}, { - json: true - }, options); - - // Check cache for a hit - if (cacheAge && cacheAge > 0) { - let cacheResult: Object|string|null = this.cache.get(url); - - if (cacheResult) { - return cacheResult; - } - } - - // Do request - return got(url, options) - .then(response => { - if (cacheAge && cacheAge > 0) { - this.cache.set(url, response.body, { - maxAge: cacheAge * 1000 - }); - } - - return response.body; - }); - } -} - -module.exports = new Hugo(); diff --git a/index.js.map b/index.js.map deleted file mode 100644 index 396954c..0000000 --- a/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["index.js.flow"],"names":["CacheConf","require","Conf","fs","Fuse","got","moment","notifier","os","path","semver","FileCache","updater","Hugo","_fuseDefaults","keys","threshold","_options","useTmpCache","checkUpdates","updateSource","updateInterval","duration","updateNotification","updateItem","_outputBuffer","config","cwd","workflowMeta","data","cache","configName","version","item","items","title","alfredMeta","debug","console","error","arg","variables","gte","alfredworkflow","lt","push","map","addItem","key","value","JSON","parse","e","keyword","callback","query","process","argv","filePath","cacheName","catch","err","then","result","current","latest","valid","gt","checkedOnline","notify","message","subtitle","icon","url","task","emptyDir","emptyDirSync","options","length","fuse","search","cacheDirChanged","isDuration","candidates","resolve","reject","defaults","name","trim","sender","contentImage","response","parseFloat","_rerun","rerun","output","log","cacheAge","json","cacheResult","get","set","body","maxAge","env","alfred_version","alfred_debug","theme","alfred_theme","themeFile","themeBackground","alfred_theme_background","themeSelectionBackground","alfred_theme_selection_background","themeSubtext","alfred_theme_subtext","preferences","alfred_preferences","preferencesLocalHash","alfred_preferences_localhash","HOME","homedir","major","statSync","readJsonSync","throws","outputBuffer","cacheDir","alfred_workflow_cache","bundleId","alfred_workflow_bundleid","join","tmpdir","alfred_workflow_name","alfred_workflow_version","uid","alfred_workflow_uid","alfred_workflow_data","module","exports"],"mappings":"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","file":"index.js","sourcesContent":["// @flow\n\nconst CacheConf = require('cache-conf');\nconst Conf = require('conf');\nconst fs = require('fs-extra');\nconst Fuse = require('fuse.js');\nconst got = require('got');\nconst moment = require('moment');\nconst notifier = require('node-notifier');\nconst os = require('os');\nconst path = require('path');\nconst semver = require('semver');\n\nconst FileCache = require('./file-cache');\nconst updater = require('./updater');\n\n/**\n * Hugo\n */\nclass Hugo {\n /**\n * FuseJS defaults\n * @see https://github.com/krisk/fuse#options\n * @type {Object}\n */\n _fuseDefaults: Object;\n\n /**\n * Hugo options\n * @type {Object}\n */\n _options: Object;\n\n /**\n * Output buffer\n * @type {Object}\n */\n _outputBuffer: Object;\n\n /**\n * Refresh (rerun) interval in seconds\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json\n * @type {number|null}\n */\n _rerun: ?number;\n\n /**\n * Cache store\n * @see https://www.npmjs.com/package/cache-conf\n * @type {CacheConf}\n */\n cache: CacheConf;\n\n /**\n * Configuration store\n * @see https://www.npmjs.com/package/conf\n * @type {Conf}\n */\n config: Conf;\n\n /**\n * Hugo constructor\n * @constructor\n */\n constructor() {\n // Set defaults for FuseJS\n this._fuseDefaults = {\n keys: ['title'],\n threshold: 0.4\n };\n\n // Save options\n this._options = {\n useTmpCache: true,\n checkUpdates: true,\n updateSource: 'packal',\n updateInterval: moment.duration(1, 'days'),\n updateNotification: true,\n updateItem: true\n };\n\n // Initialize output buffer\n this._outputBuffer = {};\n\n // Configure config store\n this.config = new Conf({\n cwd: this.workflowMeta.data\n });\n\n // Configure cache store\n this.cache = new CacheConf({\n configName: 'cache',\n cwd: this.workflowMeta.cache,\n version: this.workflowMeta.version\n });\n }\n\n /**\n * Alfred metadata\n * @return {Object}\n */\n get alfredMeta(): Object {\n let version: string = process.env.alfred_version || '0.0.0';\n\n // Check Alfred version for missing patch version (e.g. 3.4 is invalid, should be 3.4.0)\n if (!semver.valid(version)) {\n version += '.0';\n\n // Check if adding .0 to the end makes a valid version string (eg. in case of 3.4)\n if (!semver.valid(version) && process.env.alfred_debug === '1') {\n console.error(`Invalid Alfred version: ${version}`);\n version = '0.0.0';\n }\n }\n\n // Gather environment information\n let data: Object = {\n version: version,\n theme: process.env.alfred_theme,\n themeFile: '',\n themeBackground: process.env.alfred_theme_background,\n themeSelectionBackground: process.env.alfred_theme_selection_background,\n themeSubtext: parseFloat(process.env.alfred_theme_subtext),\n preferences: process.env.alfred_preferences,\n preferencesLocalHash: process.env.alfred_preferences_localhash,\n debug: process.env.alfred_debug === '1'\n };\n\n // Find and load curent Alfred theme file\n if (process.env.HOME && data.theme) {\n let homedir: string = process.env.HOME || '';\n\n let themeFile = path.resolve(homedir, 'Library', 'Application Support', 'Alfred ' + semver.major(version),\n 'Alfred.alfredpreferences', 'themes', data.theme, 'theme.json');\n\n try {\n fs.statSync(themeFile);\n data.themeFile = themeFile;\n } catch (e) {\n if (process.env.alfred_debug === '1') {\n console.error(`Could not find theme file \"${themeFile}\"`);\n }\n }\n }\n\n return data;\n }\n\n /**\n * Alfred theme\n * @return {Object}\n */\n get alfredTheme(): Object {\n let themeFile = this.alfredMeta.themeFile;\n\n if (!themeFile) {\n return {};\n }\n\n return fs.readJsonSync(themeFile, {throws: false}) || {};\n }\n\n /**\n * Alfred user input\n * @return {string}\n */\n get input(): string {\n if (process.argv.length > 3) {\n return process.argv[3] || '';\n }\n return process.argv[2] || '';\n }\n\n /**\n * Number of Alfred items in the current output buffer\n * @return {number}\n */\n get itemCount(): number {\n if (this.outputBuffer && this.outputBuffer.items) {\n return this.outputBuffer.items.length;\n }\n\n return 0;\n }\n\n /**\n * Current output buffer\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json\n * @return {Object} Object to be output and interpreted by Alfred\n */\n get outputBuffer(): Object {\n return this._outputBuffer;\n }\n\n /**\n * Workflow metadata\n * @return {Object}\n */\n get workflowMeta(): Object {\n let cacheDir = process.env.alfred_workflow_cache;\n let bundleId = process.env.alfred_workflow_bundleid;\n\n if (bundleId && this._options.useTmpCache === true) {\n cacheDir = path.resolve(path.join(os.tmpdir(), bundleId));\n }\n\n return {\n name: process.env.alfred_workflow_name,\n version: process.env.alfred_workflow_version,\n uid: process.env.alfred_workflow_uid,\n bundleId: bundleId,\n data: process.env.alfred_workflow_data,\n cache: cacheDir,\n icon: path.join(process.cwd(), 'icon.png')\n };\n }\n\n /**\n * Add item to output buffer\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json\n * @param {Object} item Item to add\n * @return {Hugo}\n */\n addItem(item: Object): Hugo {\n if (!this._outputBuffer.items) {\n this._outputBuffer.items = [];\n }\n\n // Require item title\n if (!item.title) {\n if (this.alfredMeta.debug === true) {\n console.error('Item skipped, missing title.');\n }\n return this;\n }\n\n // Parse item variables\n if (item.arg && typeof item.arg === 'object') {\n let arg = item.arg.arg;\n let variables = item.arg.variables || {};\n\n if (semver.gte(this.alfredMeta.version, '3.4.1')) {\n // Delete item arg\n delete item.arg;\n\n // Only add arg when there is one\n if (arg) {\n item.arg = arg;\n }\n\n // Item variables\n item.variables = Object.assign({}, item.variables, variables);\n } else {\n // Merge item.variables (new style) with item.arg.variables (old style)\n if (item.variables && typeof item.variables === 'object') {\n variables = Object.assign({}, variables, item.variables);\n delete item.variables;\n }\n\n // Build item arg (old style)\n item.arg = JSON.stringify({\n alfredworkflow: {\n arg: arg,\n variables: variables\n }\n });\n }\n } else if (item.variables && typeof item.variables === 'object' && semver.lt(this.alfredMeta.version, '3.4.1')) {\n // Build item arg (old style) with new style item variables\n item.arg = JSON.stringify({\n alfredworkflow: {\n arg: item.arg,\n variables: item.variables\n }\n });\n\n delete item.variables;\n }\n\n // Add item to output buffer\n this._outputBuffer.items.push(item);\n\n return this;\n }\n\n /**\n * Add items to output buffer\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json\n * @param {Array.} items List of items to add\n * @return {Hugo}\n */\n addItems(items: Array): Hugo {\n items.map(item => {\n this.addItem(item);\n return item;\n });\n\n return this;\n }\n\n /**\n * Add session variable to output buffer\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json\n * @param {string} key Variable key\n * @param {string} value Variable value\n * @return {Hugo}\n */\n addVariable(key: string, value: string): Hugo {\n if (!this._outputBuffer.variables) {\n this._outputBuffer.variables = {};\n }\n\n this._outputBuffer.variables[key] = value;\n\n return this;\n }\n\n /**\n * Add session variables to output buffer\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json/\n * @param {Object} variables List of variables to add\n * @return {Hugo}\n */\n addVariables(variables: Object): Hugo {\n if (!this._outputBuffer.variables) {\n this._outputBuffer.variables = variables;\n return this;\n }\n\n this._outputBuffer.variables = Object.assign({}, this._outputBuffer.variables, variables);\n\n return this;\n }\n\n /**\n * Get session variable from output buffer\n * @param {string} key Variable key\n * @return {string|null} Variable value\n */\n getVariable(key: string): ?string {\n if (!this._outputBuffer.variables) {\n return null;\n }\n\n return this._outputBuffer.variables[key] || null;\n }\n\n /**\n * Get session variables from output buffer\n * @return {Object} Variables\n */\n getVariables(): Object {\n return this._outputBuffer.variables || {};\n }\n\n /**\n * Get item variable\n * @param {Object} item\n * @param {string} key Variable key\n * @return {string|null} Variable value\n */\n getItemVariable(item: Object, key: string): ?string {\n if (semver.gte(this.alfredMeta.version, '3.4.1')) {\n if (item.variables) {\n return item.variables[key] || null;\n }\n } else if (item.arg) {\n try {\n let arg = {};\n let variables = {};\n\n if (typeof item.arg === 'string') {\n arg = JSON.parse(item.arg);\n }\n\n if (arg.alfredworkflow) {\n variables = arg.alfredworkflow.variables || {};\n }\n\n return variables[key] || null;\n } catch (e) {}\n }\n\n return null;\n }\n\n /**\n * Get item variables\n *\n * As of Alfred 3.4.1 item variables are handled differently (properly). This method makes it easier to get the\n * variables of an item without having to deal with different versions.\n *\n * @param {Object} item\n * @return {Object} Item variables\n */\n getItemVariables(item: Object): Object {\n if (semver.gte(this.alfredMeta.version, '3.4.1')) {\n return item.variables || {};\n } else if (item.arg) {\n try {\n let arg = {};\n\n if (typeof item.arg === 'string') {\n arg = JSON.parse(item.arg);\n }\n\n if (arg.alfredworkflow) {\n return arg.alfredworkflow.variables || {};\n }\n\n return arg.variables || {};\n } catch (e) {}\n }\n\n return {};\n }\n\n /**\n * Run a callback when first script argument matches keyword. Callback will have third argument as query parameter.\n * @example node index.js myaction \"my query\"\n * @param {string} keyword Action name\n * @param {Function} callback Callback to execute when query matches action name\n * @return {Hugo}\n */\n action(keyword: string, callback: (query: string) => void): Hugo {\n let query: string = process.argv[2];\n\n if (query && callback && query === keyword) {\n query = process.argv[3] || '';\n callback(query);\n }\n\n return this;\n }\n\n /**\n * Cache processed data\n * This allows you to read and process the data once, then storing it in cache until the file has changed again.\n *\n * @param {string} filepath File path\n * @param {string} cacheName Cache name (must be unique for each file)\n * @return {FileCache}\n */\n cacheFile(filePath: string, cacheName: string): FileCache {\n return new FileCache(filePath, cacheName, this.workflowMeta.cache);\n }\n\n /**\n * Check for updates and notify the user\n * @async\n * @return {Promise}\n */\n async checkUpdates() {\n // No need to check if we're not showing anything, duh.\n if (this._options.checkUpdates !== true ||\n (this._options.updateItem !== true && this._options.updateNotification !== true)) {\n return;\n }\n\n await updater.checkUpdates(this._options.updateSource, this._options.updateInterval)\n .catch(err => {\n console.error(err);\n return;\n })\n .then(result => {\n if (!result) {\n return;\n }\n\n // Version information\n let current: string = this.workflowMeta.version;\n let latest: string = result.version;\n\n if (!semver.valid(current)) {\n console.error(`Version ${current} is not a valid version number.`);\n return;\n }\n\n if (!semver.valid(latest)) {\n console.error(`Could not determine latest version number.`);\n return;\n }\n\n // Display notification\n if (semver.gt(latest, current)) {\n if (result.checkedOnline === true && this._options.updateNotification === true) {\n this.notify({\n message: `Workflow version ${latest} available. Current version: ${current}.`\n });\n }\n if (this._options.updateItem === true) {\n this.addItem({\n title: `Workflow update available!`,\n subtitle: `Version ${latest} is available. Current version: ${current}.`,\n icon: this.workflowMeta.icon,\n arg: result.url,\n variables: {\n task: 'wfUpdate'\n }\n });\n }\n }\n });\n }\n\n /**\n * Clear cache\n * @async\n * @return {Promise}\n */\n async clearCache() {\n if (this.workflowMeta.cache) {\n return fs.emptyDir(this.workflowMeta.cache);\n }\n }\n\n /**\n * Clear cache (sync)\n * @return {void}\n */\n clearCacheSync() {\n if (this.workflowMeta.cache) {\n return fs.emptyDirSync(this.workflowMeta.cache);\n }\n }\n\n /**\n * Filter added items (output buffer) with fuse.js\n * @see http://fusejs.io\n * @param {string} query Search string\n * @param {Object} options fuse.js options\n * @return {Hugo}\n */\n filterItems(query: string, options: Object = {}): Hugo {\n options = Object.assign({}, this._fuseDefaults, options);\n\n if (query.length === 0) {\n return this;\n }\n\n // Create fuse.js fuzzy search object\n let fuse = new Fuse(this._outputBuffer.items, options);\n\n // Set output buffer to matching items\n this._outputBuffer.items = fuse.search(query) || [];\n\n return this;\n }\n\n /**\n * Set Hugo options\n * @param {Object} options Options to set\n * @return {Hugo}\n */\n options(options: Object): Hugo {\n let cacheDirChanged = 'useTmpCache' in options && options.useTmpCache !== this._options.useTmpCache;\n\n // Convert updateInterval to moment.Duration object\n if (options.updateInterval && !moment.isDuration(options.updateInterval)) {\n if (options.updateInterval < 1) {\n delete options.updateInterval;\n } else {\n options.updateInterval = moment.duration(options.updateInterval, 'seconds') || moment.duration(1, 'days');\n }\n }\n\n // Update options\n this._options = Object.assign({}, this._options, options);\n\n // Update cache dir\n if (cacheDirChanged) {\n this.cache = new CacheConf({\n configName: 'cache',\n cwd: this.workflowMeta.cache,\n version: this.workflowMeta.version\n });\n }\n\n return this;\n }\n\n /**\n * Filter list of candidates with fuse.js\n * @see http://fusejs.io\n * @param {Array.} candidates Input data\n * @param {string} query Search string\n * @param {Object} options fuse.js options\n * @return {Array.}\n */\n matches(candidates: Array, query: string, options: Object = {}): Array {\n options = Object.assign({}, this._fuseDefaults, options);\n\n if (query.length === 0) {\n return candidates;\n }\n\n // Create fuse.js fuzzy search object\n let fuse = new Fuse(candidates, options);\n\n // Return results\n return fuse.search(query) || [];\n }\n\n /**\n * Send a notification\n *\n * Notification title defaults to the Workflow name, or when not available to 'Alfred'. You can adjust all the options\n * that node-notifier supports. Please see their documentation for available options.\n *\n * @see https://github.com/mikaelbr/node-notifier\n * @param {Object} options Notification options\n * @return {Promise} Notifier response\n */\n async notify(options: Object) {\n return new Promise((resolve, reject) => {\n let defaults = {\n title: ('Alfred ' + this.workflowMeta.name).trim(),\n sender: 'com.runningwithcrayons.Alfred-3',\n contentImage: this.workflowMeta.icon\n };\n\n // Set options\n options = Object.assign({}, defaults, options);\n\n // Notify\n notifier.notify(options, (err, response) => {\n if (err) {\n reject(err);\n return;\n }\n\n resolve(response);\n });\n });\n }\n\n /**\n * Set rerun parameter\n * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json\n * @param {number} value Interval to rerun the script when idle\n * @return {Hugo}\n */\n rerun(value: number): Hugo {\n value = parseFloat(value);\n\n if (value && value > 0.1 && value <= 5) {\n this._rerun = value;\n }\n\n return this;\n }\n\n /**\n * Flush the output buffer so Alfred shows our items\n * @async\n */\n async feedback() {\n if (this._rerun) {\n this._outputBuffer.rerun = this._rerun;\n }\n\n // Check for updates\n if (this._options.checkUpdates === true) {\n await this.checkUpdates()\n .catch(() => {});\n }\n\n let output = this._outputBuffer;\n\n // Output JSON\n console.log(JSON.stringify(output, null, '\\t'));\n\n // Reset output buffer\n this._outputBuffer = {};\n\n return output;\n }\n\n /**\n * Fetch url and parse JSON. Useful for REST APIs.\n * @see https://www.npmjs.com/package/got\n * @param {string} url Url to request\n * @param {Object} options http.request options\n * @param {number|null} cacheAge Cache lifetime (in seconds), above 0 to enable or null to disable.\n * @return {Object|string}\n * @async\n */\n async fetch(url: string, options: Object = {}, cacheAge: ?number = null): Object|string {\n // Set default options\n options = Object.assign({}, {\n json: true\n }, options);\n\n // Check cache for a hit\n if (cacheAge && cacheAge > 0) {\n let cacheResult: Object|string|null = this.cache.get(url);\n\n if (cacheResult) {\n return cacheResult;\n }\n }\n\n // Do request\n return got(url, options)\n .then(response => {\n if (cacheAge && cacheAge > 0) {\n this.cache.set(url, response.body, {\n maxAge: cacheAge * 1000\n });\n }\n\n return response.body;\n });\n }\n}\n\nmodule.exports = new Hugo();\n"]} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 17c3f63..0000000 --- a/package-lock.json +++ /dev/null @@ -1,6791 +0,0 @@ -{ - "name": "alfred-hugo", - "version": "1.2.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@ava/babel-preset-stage-4": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@ava/babel-preset-stage-4/-/babel-preset-stage-4-1.1.0.tgz", - "integrity": "sha512-oWqTnIGXW3k72UFidXzW0ONlO7hnO9x02S/QReJ7NBGeiBH9cUHY9+EfV6C8PXC6YJH++WrliEq03wMSJGNZFg==", - "dev": true, - "requires": { - "babel-plugin-check-es2015-constants": "6.22.0", - "babel-plugin-syntax-trailing-function-commas": "6.22.0", - "babel-plugin-transform-async-to-generator": "6.24.1", - "babel-plugin-transform-es2015-destructuring": "6.23.0", - "babel-plugin-transform-es2015-function-name": "6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", - "babel-plugin-transform-es2015-parameters": "6.24.1", - "babel-plugin-transform-es2015-spread": "6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "6.24.1", - "babel-plugin-transform-es2015-unicode-regex": "6.24.1", - "babel-plugin-transform-exponentiation-operator": "6.24.1", - "package-hash": "1.2.0" - } - }, - "@ava/babel-preset-transform-test-files": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@ava/babel-preset-transform-test-files/-/babel-preset-transform-test-files-2.0.1.tgz", - "integrity": "sha1-11IyzG1x3Jx+rkt2qQBP2BUB0ME=", - "dev": true, - "requires": { - "babel-plugin-ava-throws-helper": "1.0.0", - "babel-plugin-espower": "2.3.2", - "package-hash": "1.2.0" - } - }, - "@ava/pretty-format": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@ava/pretty-format/-/pretty-format-1.1.0.tgz", - "integrity": "sha1-0KV9Jeua6rlkO90aAwZCuRwSPig=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "esutils": "2.0.2" - } - }, - "@gulp-sourcemaps/identity-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.1.tgz", - "integrity": "sha1-z6I7xYQPkQTOMqZedNt+epdLvuE=", - "dev": true, - "requires": { - "acorn": "5.0.3", - "css": "2.2.1", - "normalize-path": "2.1.1", - "source-map": "0.5.6", - "through2": "2.0.3" - } - }, - "@gulp-sourcemaps/map-sources": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz", - "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=", - "dev": true, - "requires": { - "normalize-path": "2.1.1", - "through2": "2.0.3" - } - }, - "acorn": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.0.3.tgz", - "integrity": "sha1-xGDfCEkUY/AozLguqzcwvwEIez0=", - "dev": true - }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "requires": { - "acorn": "3.3.0" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } - } - }, - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true, - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, - "ajv-keywords": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", - "dev": true - }, - "alfred-link": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/alfred-link/-/alfred-link-0.2.0.tgz", - "integrity": "sha1-u0Vs5aTsv7xX+0oCCinNG/pNeNI=", - "requires": { - "del": "2.2.2", - "path-exists": "3.0.0", - "pify": "2.3.0", - "plist": "2.1.0", - "read-pkg-up": "1.0.1", - "resolve-alfred-prefs": "1.0.0", - "sudo-block": "1.2.0", - "user-home": "2.0.0" - } - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true - }, - "ansi-align": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-1.1.0.tgz", - "integrity": "sha1-LwwWWIKXOa3V67FeawxuNCPwFro=", - "dev": true, - "requires": { - "string-width": "1.0.2" - } - }, - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "anymatch": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.0.tgz", - "integrity": "sha1-o+Uvo5FoyCX/V7AkgSbOWo/5VQc=", - "dev": true, - "requires": { - "arrify": "1.0.1", - "micromatch": "2.3.11" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", - "dev": true - }, - "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "dev": true, - "requires": { - "sprintf-js": "1.0.3" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "1.0.3" - } - }, - "arr-exclude": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/arr-exclude/-/arr-exclude-1.0.0.tgz", - "integrity": "sha1-38fC5VKicHI8zaBM8xKMjL/lxjE=", - "dev": true - }, - "arr-flatten": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.0.3.tgz", - "integrity": "sha1-onTthawIhJtr14R8RYB0XcUa37E=", - "dev": true - }, - "array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", - "dev": true - }, - "array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", - "dev": true - }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true - }, - "array-slice": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.0.0.tgz", - "integrity": "sha1-5zA08A3MH0CHYAj9IP6ud71LfC8=", - "dev": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "requires": { - "array-uniq": "1.0.3" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" - }, - "assertion-error": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz", - "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=", - "dev": true - }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true - }, - "atob": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/atob/-/atob-1.1.3.tgz", - "integrity": "sha1-lfE2KbEsOlGl0hWr3OKqnzL4B3M=", - "dev": true - }, - "auto-bind": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-1.1.0.tgz", - "integrity": "sha1-k7hk3H7gGjJigXddXHXKCnUeWWE=", - "dev": true - }, - "ava": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/ava/-/ava-0.18.2.tgz", - "integrity": "sha1-eSU9FjYHcDSieAu1W1w+bD1/MS8=", - "dev": true, - "requires": { - "@ava/babel-preset-stage-4": "1.1.0", - "@ava/babel-preset-transform-test-files": "2.0.1", - "@ava/pretty-format": "1.1.0", - "arr-flatten": "1.0.3", - "array-union": "1.0.2", - "array-uniq": "1.0.3", - "arrify": "1.0.1", - "auto-bind": "1.1.0", - "ava-init": "0.2.0", - "babel-code-frame": "6.22.0", - "babel-core": "6.25.0", - "bluebird": "3.5.0", - "caching-transform": "1.0.1", - "chalk": "1.1.3", - "chokidar": "1.7.0", - "clean-stack": "1.3.0", - "clean-yaml-object": "0.1.0", - "cli-cursor": "2.1.0", - "cli-spinners": "1.0.0", - "cli-truncate": "0.2.1", - "co-with-promise": "4.6.0", - "code-excerpt": "2.1.0", - "common-path-prefix": "1.0.0", - "convert-source-map": "1.5.0", - "core-assert": "0.2.1", - "currently-unhandled": "0.4.1", - "debug": "2.6.8", - "diff": "3.2.0", - "dot-prop": "4.1.1", - "empower-core": "0.6.2", - "equal-length": "1.0.1", - "figures": "2.0.0", - "find-cache-dir": "0.1.1", - "fn-name": "2.0.1", - "get-port": "2.1.0", - "globby": "6.1.0", - "has-flag": "2.0.0", - "ignore-by-default": "1.0.1", - "indent-string": "3.1.0", - "is-ci": "1.0.10", - "is-generator-fn": "1.0.0", - "is-obj": "1.0.1", - "is-observable": "0.2.0", - "is-promise": "2.1.0", - "jest-snapshot": "18.1.0", - "last-line-stream": "1.0.0", - "lodash.debounce": "4.0.8", - "lodash.difference": "4.5.0", - "lodash.flatten": "4.4.0", - "lodash.isequal": "4.5.0", - "loud-rejection": "1.6.0", - "matcher": "0.1.2", - "max-timeout": "1.0.0", - "md5-hex": "2.0.0", - "meow": "3.7.0", - "ms": "0.7.3", - "multimatch": "2.1.0", - "observable-to-promise": "0.4.0", - "option-chain": "0.1.1", - "package-hash": "1.2.0", - "pkg-conf": "2.0.0", - "plur": "2.1.2", - "pretty-ms": "2.1.0", - "require-precompiled": "0.1.0", - "resolve-cwd": "1.0.0", - "slash": "1.0.0", - "source-map-support": "0.4.15", - "stack-utils": "1.0.1", - "strip-ansi": "3.0.1", - "strip-bom-buf": "1.0.0", - "time-require": "0.1.2", - "unique-temp-dir": "1.0.0", - "update-notifier": "1.0.3" - }, - "dependencies": { - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "1.0.2", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - } - } - }, - "ava-init": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/ava-init/-/ava-init-0.2.0.tgz", - "integrity": "sha1-kwTItMNX1m49/a4fv/R7EZnVxV0=", - "dev": true, - "requires": { - "arr-exclude": "1.0.0", - "execa": "0.5.1", - "has-yarn": "1.0.0", - "read-pkg-up": "2.0.0", - "write-pkg": "2.1.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "2.1.0", - "read-pkg": "2.0.0" - } - } - } - }, - "babel-code-frame": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", - "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.1" - } - }, - "babel-core": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.25.0.tgz", - "integrity": "sha1-fdQrBGPHQunVKW3rPsZ6kyLa1yk=", - "dev": true, - "requires": { - "babel-code-frame": "6.22.0", - "babel-generator": "6.25.0", - "babel-helpers": "6.24.1", - "babel-messages": "6.23.0", - "babel-register": "6.24.1", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0", - "babylon": "6.17.4", - "convert-source-map": "1.5.0", - "debug": "2.6.8", - "json5": "0.5.1", - "lodash": "4.17.4", - "minimatch": "3.0.4", - "path-is-absolute": "1.0.1", - "private": "0.1.7", - "slash": "1.0.0", - "source-map": "0.5.6" - } - }, - "babel-eslint": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-7.2.3.tgz", - "integrity": "sha1-sv4tgBJkcPXBlELcdXJTqJdxCCc=", - "dev": true, - "requires": { - "babel-code-frame": "6.22.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0", - "babylon": "6.17.4" - } - }, - "babel-generator": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.25.0.tgz", - "integrity": "sha1-M6GvcNXyiQrrRlpKd5PB32qeqfw=", - "dev": true, - "requires": { - "babel-messages": "6.23.0", - "babel-runtime": "6.23.0", - "babel-types": "6.25.0", - "detect-indent": "4.0.0", - "jsesc": "1.3.0", - "lodash": "4.17.4", - "source-map": "0.5.6", - "trim-right": "1.0.1" - }, - "dependencies": { - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true - } - } - }, - "babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", - "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", - "dev": true, - "requires": { - "babel-helper-explode-assignable-expression": "6.24.1", - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" - } - }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.23.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-helper-define-map": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.24.1.tgz", - "integrity": "sha1-epdH8ljYlH0y1RX2qhx70CIEoIA=", - "dev": true, - "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.23.0", - "babel-types": "6.25.0", - "lodash": "4.17.4" - } - }, - "babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", - "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", - "dev": true, - "requires": { - "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" - } - }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" - } - }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" - } - }, - "babel-helper-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz", - "integrity": "sha1-024i+rEAjXnYhkjjIRaGgShFbOg=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0", - "lodash": "4.17.4" - } - }, - "babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", - "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", - "dev": true, - "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", - "dev": true, - "requires": { - "babel-helper-optimise-call-expression": "6.24.1", - "babel-messages": "6.23.0", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0", - "babel-template": "6.25.0" - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0" - } - }, - "babel-plugin-ava-throws-helper": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/babel-plugin-ava-throws-helper/-/babel-plugin-ava-throws-helper-1.0.0.tgz", - "integrity": "sha1-j+bnnS/RmDi1w2Sfic+wP9Vj4kE=", - "dev": true, - "requires": { - "babel-template": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0" - } - }, - "babel-plugin-espower": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/babel-plugin-espower/-/babel-plugin-espower-2.3.2.tgz", - "integrity": "sha1-VRa4/NsmyfDh2BYHSfbkxl5xJx4=", - "dev": true, - "requires": { - "babel-generator": "6.25.0", - "babylon": "6.17.4", - "call-matcher": "1.0.1", - "core-js": "2.4.1", - "espower-location-detector": "1.0.0", - "espurify": "1.7.0", - "estraverse": "4.2.0" - } - }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", - "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", - "dev": true - }, - "babel-plugin-syntax-class-properties": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", - "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=", - "dev": true - }, - "babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", - "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", - "dev": true - }, - "babel-plugin-syntax-flow": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", - "integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=", - "dev": true - }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", - "dev": true - }, - "babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", - "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", - "dev": true, - "requires": { - "babel-helper-remap-async-to-generator": "6.24.1", - "babel-plugin-syntax-async-functions": "6.13.0", - "babel-runtime": "6.23.0" - } - }, - "babel-plugin-transform-class-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz", - "integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=", - "dev": true, - "requires": { - "babel-helper-function-name": "6.24.1", - "babel-plugin-syntax-class-properties": "6.13.0", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0" - } - }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0" - } - }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0" - } - }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz", - "integrity": "sha1-dsKV3DpHQbFmWt/TFnIV3P8ypXY=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0", - "lodash": "4.17.4" - } - }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", - "dev": true, - "requires": { - "babel-helper-define-map": "6.24.1", - "babel-helper-function-name": "6.24.1", - "babel-helper-optimise-call-expression": "6.24.1", - "babel-helper-replace-supers": "6.24.1", - "babel-messages": "6.23.0", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0", - "babel-template": "6.25.0" - } - }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0" - } - }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" - } - }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0" - } - }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", - "dev": true, - "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" - } - }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0" - } - }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0" - } - }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz", - "integrity": "sha1-0+MQtA72ZKNmIiAAl8bUQCmPK/4=", - "dev": true, - "requires": { - "babel-plugin-transform-strict-mode": "6.24.1", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0" - } - }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0" - } - }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", - "dev": true, - "requires": { - "babel-helper-replace-supers": "6.24.1", - "babel-runtime": "6.23.0" - } - }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", - "dev": true, - "requires": { - "babel-helper-call-delegate": "6.24.1", - "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.23.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" - } - }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0" - } - }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", - "dev": true, - "requires": { - "babel-helper-regex": "6.24.1", - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" - } - }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0" - } - }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0" - } - }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", - "dev": true, - "requires": { - "babel-helper-regex": "6.24.1", - "babel-runtime": "6.23.0", - "regexpu-core": "2.0.0" - } - }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", - "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", - "dev": true, - "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", - "babel-plugin-syntax-exponentiation-operator": "6.13.0", - "babel-runtime": "6.23.0" - } - }, - "babel-plugin-transform-flow-strip-types": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", - "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=", - "dev": true, - "requires": { - "babel-plugin-syntax-flow": "6.18.0", - "babel-runtime": "6.23.0" - } - }, - "babel-plugin-transform-regenerator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz", - "integrity": "sha1-uNowWtQ8PJm0hI5P5AN7dw0jxBg=", - "dev": true, - "requires": { - "regenerator-transform": "0.9.11" - } - }, - "babel-plugin-transform-runtime": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz", - "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0" - } - }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0" - } - }, - "babel-preset-env": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.0.tgz", - "integrity": "sha512-OVgtQRuOZKckrILgMA5rvctvFZPv72Gua9Rt006AiPoB0DJKGN07UmaQA+qRrYgK71MVct8fFhT0EyNWYorVew==", - "dev": true, - "requires": { - "babel-plugin-check-es2015-constants": "6.22.0", - "babel-plugin-syntax-trailing-function-commas": "6.22.0", - "babel-plugin-transform-async-to-generator": "6.24.1", - "babel-plugin-transform-es2015-arrow-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoping": "6.24.1", - "babel-plugin-transform-es2015-classes": "6.24.1", - "babel-plugin-transform-es2015-computed-properties": "6.24.1", - "babel-plugin-transform-es2015-destructuring": "6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", - "babel-plugin-transform-es2015-for-of": "6.23.0", - "babel-plugin-transform-es2015-function-name": "6.24.1", - "babel-plugin-transform-es2015-literals": "6.22.0", - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", - "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", - "babel-plugin-transform-es2015-modules-umd": "6.24.1", - "babel-plugin-transform-es2015-object-super": "6.24.1", - "babel-plugin-transform-es2015-parameters": "6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", - "babel-plugin-transform-es2015-spread": "6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "6.24.1", - "babel-plugin-transform-es2015-template-literals": "6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "6.24.1", - "babel-plugin-transform-exponentiation-operator": "6.24.1", - "babel-plugin-transform-regenerator": "6.24.1", - "browserslist": "2.2.2", - "invariant": "2.2.2", - "semver": "5.4.1" - } - }, - "babel-preset-flow": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz", - "integrity": "sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0=", - "dev": true, - "requires": { - "babel-plugin-transform-flow-strip-types": "6.22.0" - } - }, - "babel-register": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.24.1.tgz", - "integrity": "sha1-fhDhOi9xBlvfrVoXh7pFvKbe118=", - "dev": true, - "requires": { - "babel-core": "6.25.0", - "babel-runtime": "6.23.0", - "core-js": "2.4.1", - "home-or-tmp": "2.0.0", - "lodash": "4.17.4", - "mkdirp": "0.5.1", - "source-map-support": "0.4.15" - } - }, - "babel-runtime": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", - "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=", - "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.10.5" - } - }, - "babel-template": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.25.0.tgz", - "integrity": "sha1-ZlJBFmt8KqTGGdceGSlpVSsQwHE=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0", - "babylon": "6.17.4", - "lodash": "4.17.4" - } - }, - "babel-traverse": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.25.0.tgz", - "integrity": "sha1-IldJfi/NGbie3BPEyROB+VEklvE=", - "dev": true, - "requires": { - "babel-code-frame": "6.22.0", - "babel-messages": "6.23.0", - "babel-runtime": "6.23.0", - "babel-types": "6.25.0", - "babylon": "6.17.4", - "debug": "2.6.8", - "globals": "9.18.0", - "invariant": "2.2.2", - "lodash": "4.17.4" - } - }, - "babel-types": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.25.0.tgz", - "integrity": "sha1-cK+ySNVmDl0Y+BHZHIMDtUE0oY4=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0", - "esutils": "2.0.2", - "lodash": "4.17.4", - "to-fast-properties": "1.0.3" - } - }, - "babylon": { - "version": "6.17.4", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.17.4.tgz", - "integrity": "sha512-kChlV+0SXkjE0vUn9OZ7pBMWRFd8uq3mZe8x1K6jhuNcAFAtEnjchFAqB+dYEXKyd+JpT6eppRR78QAr5gTsUw==", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base64-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.0.tgz", - "integrity": "sha1-o5mS1yNYSBGYK+XikLtqU9hnAPE=" - }, - "beeper": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", - "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", - "dev": true - }, - "big-integer": { - "version": "1.6.23", - "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.23.tgz", - "integrity": "sha1-6F1QgiDHTj9DpM5y7tUfPaTblNE=" - }, - "binary-extensions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.8.0.tgz", - "integrity": "sha1-SOyNFt9Dd+rl+liEaCSAr02Vx3Q=", - "dev": true - }, - "bluebird": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", - "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", - "dev": true - }, - "boxen": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-0.6.0.tgz", - "integrity": "sha1-g2TUJIrDT/DvGy8r9JpsYM4NgbY=", - "dev": true, - "requires": { - "ansi-align": "1.1.0", - "camelcase": "2.1.1", - "chalk": "1.1.3", - "cli-boxes": "1.0.0", - "filled-array": "1.1.0", - "object-assign": "4.1.1", - "repeating": "2.0.1", - "string-width": "1.0.2", - "widest-line": "1.0.0" - } - }, - "bplist-parser": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.1.1.tgz", - "integrity": "sha1-1g1dzCDLptx+HymbNdPh+V2vuuY=", - "requires": { - "big-integer": "1.6.23" - } - }, - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" - } - }, - "browserslist": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.2.2.tgz", - "integrity": "sha512-MejxGMNIeIqzgaMKVYfFTWHinrwZOnWMXteN9VlHinTd13/0aDmXY9uyRqNsCTnVxqRmrjQFcXI7cy0q9K1IYg==", - "dev": true, - "requires": { - "caniuse-lite": "1.0.30000704", - "electron-to-chromium": "1.3.16" - } - }, - "buf-compare": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buf-compare/-/buf-compare-1.0.1.tgz", - "integrity": "sha1-/vKNqLgROgoNtEMLC2Rntpcws0o=", - "dev": true - }, - "bufferstreams": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/bufferstreams/-/bufferstreams-1.1.1.tgz", - "integrity": "sha1-AWE3MGCsWYjv+ZBYcxEU9uGV1R4=", - "dev": true, - "requires": { - "readable-stream": "2.3.2" - } - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" - }, - "cache-conf": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cache-conf/-/cache-conf-0.5.0.tgz", - "integrity": "sha1-aBxC7Rdx6tK8I2MqddPNjceUXFk=", - "requires": { - "conf": "0.12.0", - "pkg-up": "1.0.0" - } - }, - "caching-transform": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-1.0.1.tgz", - "integrity": "sha1-bb2y8g+Nj7znnz6U6dF0Lc31wKE=", - "dev": true, - "requires": { - "md5-hex": "1.3.0", - "mkdirp": "0.5.1", - "write-file-atomic": "1.3.4" - }, - "dependencies": { - "md5-hex": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.3.0.tgz", - "integrity": "sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ=", - "dev": true, - "requires": { - "md5-o-matic": "0.1.1" - } - }, - "write-file-atomic": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", - "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "imurmurhash": "0.1.4", - "slide": "1.1.6" - } - } - } - }, - "call-matcher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-matcher/-/call-matcher-1.0.1.tgz", - "integrity": "sha1-UTTQd5hPcSpU2tPL9i3ijc5BbKg=", - "dev": true, - "requires": { - "core-js": "2.4.1", - "deep-equal": "1.0.1", - "espurify": "1.7.0", - "estraverse": "4.2.0" - } - }, - "call-signature": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/call-signature/-/call-signature-0.0.2.tgz", - "integrity": "sha1-qEq8glpV70yysCi9dOIFpluaSZY=", - "dev": true - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "0.2.0" - } - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, - "requires": { - "camelcase": "2.1.1", - "map-obj": "1.0.1" - } - }, - "caniuse-lite": { - "version": "1.0.30000704", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000704.tgz", - "integrity": "sha1-rbbqARNFFWY2gtuTq6spHUwClGs=", - "dev": true - }, - "capture-stack-trace": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", - "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=" - }, - "chai": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", - "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=", - "dev": true, - "requires": { - "assertion-error": "1.0.2", - "deep-eql": "0.1.3", - "type-detect": "1.0.0" - } - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "1.3.0", - "async-each": "1.0.1", - "fsevents": "1.1.2", - "glob-parent": "2.0.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "2.0.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.1.0" - } - }, - "ci-info": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.0.0.tgz", - "integrity": "sha1-3FKF8rTiUYIWg2gcOBwziPRuxTQ=", - "dev": true - }, - "circular-json": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.1.tgz", - "integrity": "sha1-vos2rvzN6LPKeqLWr8B6NyQsDS0=", - "dev": true - }, - "clean-stack": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-1.3.0.tgz", - "integrity": "sha1-noIVAa6XmYbEax1m0tQy2y/UrjE=", - "dev": true - }, - "clean-yaml-object": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", - "integrity": "sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g=", - "dev": true - }, - "cli-boxes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", - "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "2.0.0" - } - }, - "cli-spinners": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.0.0.tgz", - "integrity": "sha1-75h+09SDkaw9q5GAtAanQhgNbmo=", - "dev": true - }, - "cli-truncate": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", - "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", - "dev": true, - "requires": { - "slice-ansi": "0.0.4", - "string-width": "1.0.2" - } - }, - "cli-width": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", - "integrity": "sha1-sjTKIJsp72b8UY2bmNWEewDt8Ao=", - "dev": true - }, - "clone": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz", - "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=", - "dev": true - }, - "clone-stats": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", - "dev": true - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "co-with-promise": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co-with-promise/-/co-with-promise-4.6.0.tgz", - "integrity": "sha1-QT59tvWJOmC5Qs9JLEvsk9tBWrc=", - "dev": true, - "requires": { - "pinkie-promise": "1.0.0" - }, - "dependencies": { - "pinkie": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-1.0.0.tgz", - "integrity": "sha1-Wkfyi6EBXQIBvae/DzWOR77Ix+Q=", - "dev": true - }, - "pinkie-promise": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-1.0.0.tgz", - "integrity": "sha1-0dpn9UglY7t89X8oauKCLs+/NnA=", - "dev": true, - "requires": { - "pinkie": "1.0.0" - } - } - } - }, - "code-excerpt": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-2.1.0.tgz", - "integrity": "sha1-XcwIHoj0p+O1VOnjXX7yMtR/gUc=", - "dev": true, - "requires": { - "convert-to-spaces": "1.0.2" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "common-path-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-1.0.0.tgz", - "integrity": "sha1-zVL28HEuC6q5fW+XModPIvR3UsA=", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.2", - "typedarray": "0.0.6" - } - }, - "conf": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/conf/-/conf-0.12.0.tgz", - "integrity": "sha1-hJjFmeJIf+xwNQXRgcETh1uMMQw=", - "requires": { - "dot-prop": "4.1.1", - "env-paths": "1.0.0", - "mkdirp": "0.5.1", - "pkg-up": "1.0.0" - } - }, - "configstore": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-2.1.0.tgz", - "integrity": "sha1-c3o6cDbpiGECqmCZ5HuzOrGroaE=", - "dev": true, - "requires": { - "dot-prop": "3.0.0", - "graceful-fs": "4.1.11", - "mkdirp": "0.5.1", - "object-assign": "4.1.1", - "os-tmpdir": "1.0.2", - "osenv": "0.1.4", - "uuid": "2.0.3", - "write-file-atomic": "1.3.4", - "xdg-basedir": "2.0.0" - }, - "dependencies": { - "dot-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", - "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", - "dev": true, - "requires": { - "is-obj": "1.0.1" - } - }, - "write-file-atomic": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", - "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "imurmurhash": "0.1.4", - "slide": "1.1.6" - } - } - } - }, - "convert-source-map": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", - "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=", - "dev": true - }, - "convert-to-spaces": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz", - "integrity": "sha1-fj5Iu+bZl7FBfdyihoIEtNPYVxU=", - "dev": true - }, - "core-assert": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz", - "integrity": "sha1-+F4s+b/tKPdzzIs/pcW2m9wC/j8=", - "dev": true, - "requires": { - "buf-compare": "1.0.1", - "is-error": "2.2.1" - } - }, - "core-js": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", - "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "create-error-class": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", - "requires": { - "capture-stack-trace": "1.0.0" - } - }, - "cross-spawn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", - "dev": true, - "requires": { - "lru-cache": "4.1.1", - "which": "1.2.14" - } - }, - "crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", - "dev": true - }, - "css": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/css/-/css-2.2.1.tgz", - "integrity": "sha1-c6TIHehdtmTU7mdPfUcIXjstVdw=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "source-map": "0.1.43", - "source-map-resolve": "0.3.1", - "urix": "0.1.0" - }, - "dependencies": { - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", - "dev": true, - "requires": { - "amdefine": "1.0.1" - } - } - } - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, - "requires": { - "array-find-index": "1.0.2" - } - }, - "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "dev": true, - "requires": { - "es5-ext": "0.10.23" - } - }, - "date-time": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/date-time/-/date-time-0.1.1.tgz", - "integrity": "sha1-7S9tk9l5DOL9ZtW1/z7dW7y/Owc=", - "dev": true - }, - "dateformat": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.0.0.tgz", - "integrity": "sha1-J0Pjq7XD/CRi5SfcpEXgTp9N7hc=", - "dev": true - }, - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "dev": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "debug-fabulous": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-0.1.0.tgz", - "integrity": "sha1-rQ6gel1RkyT7VYQqjzTuWcf4/2w=", - "dev": true, - "requires": { - "debug": "2.6.8", - "object-assign": "4.1.0" - }, - "dependencies": { - "object-assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.0.tgz", - "integrity": "sha1-ejs9DpgGPUP0wD8uiubNUahog6A=", - "dev": true - } - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "deep-eql": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", - "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", - "dev": true, - "requires": { - "type-detect": "0.1.1" - }, - "dependencies": { - "type-detect": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", - "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", - "dev": true - } - } - }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true - }, - "deep-extend": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", - "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=" - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "deep-strict-equal": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/deep-strict-equal/-/deep-strict-equal-0.2.0.tgz", - "integrity": "sha1-SgeBR6irV/ag1PVUckPNIvROtOQ=", - "dev": true, - "requires": { - "core-assert": "0.2.1" - } - }, - "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true, - "requires": { - "clone": "1.0.2" - } - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.6.1" - } - }, - "delay": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/delay/-/delay-1.3.1.tgz", - "integrity": "sha1-oqimHHak1QtnD+KrLVHLA4Arupg=", - "dev": true - }, - "deprecated": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/deprecated/-/deprecated-0.0.1.tgz", - "integrity": "sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=", - "dev": true - }, - "detect-file": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz", - "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=", - "dev": true, - "requires": { - "fs-exists-sync": "0.1.0" - } - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "requires": { - "repeating": "2.0.1" - } - }, - "detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", - "dev": true - }, - "diff": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", - "dev": true - }, - "doctrine": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", - "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", - "dev": true, - "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" - } - }, - "dot-prop": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.1.1.tgz", - "integrity": "sha1-qEk/C3te7sglJbXHWH+n3nyoWcE=", - "requires": { - "is-obj": "1.0.1" - } - }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", - "dev": true, - "requires": { - "readable-stream": "2.3.2" - } - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=" - }, - "electron-to-chromium": { - "version": "1.3.16", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.16.tgz", - "integrity": "sha1-0OAmc1dUdwkBrjAaIWZMukXZL30=", - "dev": true - }, - "empower-core": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/empower-core/-/empower-core-0.6.2.tgz", - "integrity": "sha1-Wt71ZgiOMfuoC6CjbfR9cJQWkUQ=", - "dev": true, - "requires": { - "call-signature": "0.0.2", - "core-js": "2.4.1" - } - }, - "end-of-stream": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-0.1.5.tgz", - "integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=", - "dev": true, - "requires": { - "once": "1.3.3" - }, - "dependencies": { - "once": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", - "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - } - } - }, - "enhance-visitors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/enhance-visitors/-/enhance-visitors-1.0.0.tgz", - "integrity": "sha1-qpRdBdpGVnKh69OP7i7T2oUY6Vo=", - "dev": true, - "requires": { - "lodash": "4.17.4" - } - }, - "env-paths": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-1.0.0.tgz", - "integrity": "sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA=" - }, - "equal-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/equal-length/-/equal-length-1.0.1.tgz", - "integrity": "sha1-IcoRLUirJLTh5//A5TOdMf38J0w=", - "dev": true - }, - "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", - "requires": { - "is-arrayish": "0.2.1" - } - }, - "es5-ext": { - "version": "0.10.23", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.23.tgz", - "integrity": "sha1-dXi1G+l0IHpUh4IbVlOMIk5Oezg=", - "dev": true, - "requires": { - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1" - } - }, - "es6-iterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", - "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.23", - "es6-symbol": "3.1.1" - } - }, - "es6-map": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.23", - "es6-iterator": "2.0.1", - "es6-set": "0.1.5", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" - } - }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.23", - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" - } - }, - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.23" - } - }, - "es6-weak-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.23", - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "escope": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", - "dev": true, - "requires": { - "es6-map": "0.1.5", - "es6-weak-map": "2.0.2", - "esrecurse": "4.2.0", - "estraverse": "4.2.0" - } - }, - "eslint": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", - "dev": true, - "requires": { - "babel-code-frame": "6.22.0", - "chalk": "1.1.3", - "concat-stream": "1.6.0", - "debug": "2.6.8", - "doctrine": "2.0.0", - "escope": "3.6.0", - "espree": "3.4.3", - "esquery": "1.0.0", - "estraverse": "4.2.0", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "glob": "7.1.2", - "globals": "9.18.0", - "ignore": "3.3.3", - "imurmurhash": "0.1.4", - "inquirer": "0.12.0", - "is-my-json-valid": "2.16.0", - "is-resolvable": "1.0.0", - "js-yaml": "3.8.4", - "json-stable-stringify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.4", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "1.2.1", - "progress": "1.1.8", - "require-uncached": "1.0.3", - "shelljs": "0.7.8", - "strip-bom": "3.0.0", - "strip-json-comments": "2.0.1", - "table": "3.8.3", - "text-table": "0.2.0", - "user-home": "2.0.0" - }, - "dependencies": { - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } - } - }, - "eslint-config-xo": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.17.0.tgz", - "integrity": "sha1-Hn1Khr9JF5gFxGIugyp7G+606IE=", - "dev": true - }, - "eslint-formatter-pretty": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-formatter-pretty/-/eslint-formatter-pretty-1.1.0.tgz", - "integrity": "sha1-q00G2gL+2ME66fDcVApDPvftb14=", - "dev": true, - "requires": { - "ansi-escapes": "1.4.0", - "chalk": "1.1.3", - "log-symbols": "1.0.2", - "plur": "2.1.2", - "string-width": "2.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz", - "integrity": "sha1-Y1xUNsxypuDDh87KJ41OLuxSaH4=", - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "3.0.1" - } - } - } - }, - "eslint-plugin-ava": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-ava/-/eslint-plugin-ava-4.2.1.tgz", - "integrity": "sha1-fNtegbx3n0gz1HIKYJPl9KbKGRM=", - "dev": true, - "requires": { - "arrify": "1.0.1", - "deep-strict-equal": "0.2.0", - "enhance-visitors": "1.0.0", - "espree": "3.4.3", - "espurify": "1.7.0", - "import-modules": "1.1.0", - "multimatch": "2.1.0", - "pkg-up": "2.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "2.0.0" - } - }, - "pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", - "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", - "dev": true, - "requires": { - "find-up": "2.1.0" - } - } - } - }, - "eslint-plugin-flowtype-errors": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype-errors/-/eslint-plugin-flowtype-errors-3.3.1.tgz", - "integrity": "sha512-6EUSAn7NZaiLpYKuNp+pXGGR8e7J0suBnoSsi1rQ6p38+Z1Agl+A8CJo3GvgCXtQuZkFjdTuGav//vqICxDD8g==", - "dev": true, - "requires": { - "babel-runtime": "6.23.0", - "slash": "1.0.0" - } - }, - "espower-location-detector": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/espower-location-detector/-/espower-location-detector-1.0.0.tgz", - "integrity": "sha1-oXt+zFnTDheeK+9z+0E3cEyzMbU=", - "dev": true, - "requires": { - "is-url": "1.2.2", - "path-is-absolute": "1.0.1", - "source-map": "0.5.6", - "xtend": "4.0.1" - } - }, - "espree": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.4.3.tgz", - "integrity": "sha1-KRC1zNSc6JPC//+qtP2LOjG4I3Q=", - "dev": true, - "requires": { - "acorn": "5.0.3", - "acorn-jsx": "3.0.1" - } - }, - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true - }, - "espurify": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/espurify/-/espurify-1.7.0.tgz", - "integrity": "sha1-HFz2y8zDLm9jk4C9T5kfq5up0iY=", - "dev": true, - "requires": { - "core-js": "2.4.1" - } - }, - "esquery": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", - "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", - "dev": true, - "requires": { - "estraverse": "4.2.0" - } - }, - "esrecurse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", - "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", - "dev": true, - "requires": { - "estraverse": "4.2.0", - "object-assign": "4.1.1" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.23" - } - }, - "execa": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.5.1.tgz", - "integrity": "sha1-3j+4XLjW6RyFvLzrFkWBeFy1ezY=", - "dev": true, - "requires": { - "cross-spawn": "4.0.2", - "get-stream": "2.3.1", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" - }, - "dependencies": { - "get-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", - "dev": true, - "requires": { - "object-assign": "4.1.1", - "pinkie-promise": "2.0.1" - } - } - } - }, - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", - "dev": true - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "0.1.1" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "2.2.3" - } - }, - "expand-tilde": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz", - "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", - "dev": true, - "requires": { - "os-homedir": "1.0.2" - } - }, - "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", - "dev": true - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "fancy-log": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz", - "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "time-stamp": "1.1.0" - } - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "1.2.2", - "object-assign": "4.1.1" - } - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", - "dev": true, - "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "1.1.7", - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" - } - }, - "filled-array": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/filled-array/-/filled-array-1.1.0.tgz", - "integrity": "sha1-w8T2xmO5I0WamqKZEtLQMfFQf4Q=", - "dev": true - }, - "find-cache-dir": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-0.1.1.tgz", - "integrity": "sha1-yN765XyKUqinhPnjHFfHQumToLk=", - "dev": true, - "requires": { - "commondir": "1.0.1", - "mkdirp": "0.5.1", - "pkg-dir": "1.0.0" - } - }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" - }, - "dependencies": { - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "requires": { - "pinkie-promise": "2.0.1" - } - } - } - }, - "findup-sync": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.3.tgz", - "integrity": "sha1-QAQ5Kee8YK3wt/SCfExudaDeyhI=", - "dev": true, - "requires": { - "detect-file": "0.1.0", - "is-glob": "2.0.1", - "micromatch": "2.3.11", - "resolve-dir": "0.1.1" - } - }, - "fined": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.0.tgz", - "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=", - "dev": true, - "requires": { - "expand-tilde": "2.0.2", - "is-plain-object": "2.0.3", - "object.defaults": "1.1.0", - "object.pick": "1.2.0", - "parse-filepath": "1.0.1" - }, - "dependencies": { - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "1.0.1" - } - } - } - }, - "first-chunk-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/first-chunk-stream/-/first-chunk-stream-1.0.0.tgz", - "integrity": "sha1-Wb+1DNkF9g18OUzT2ayqtOatk04=", - "dev": true - }, - "flagged-respawn": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz", - "integrity": "sha1-/xke3c1wiKZ1smEP/8l2vpuAdLU=", - "dev": true - }, - "flat-cache": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", - "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", - "dev": true, - "requires": { - "circular-json": "0.3.1", - "del": "2.2.2", - "graceful-fs": "4.1.11", - "write": "0.2.1" - } - }, - "flow-bin": { - "version": "0.40.0", - "resolved": "https://registry.npmjs.org/flow-bin/-/flow-bin-0.40.0.tgz", - "integrity": "sha1-4Q1ghG2SMSTkf1SPFrpg/Yuv9aU=", - "dev": true - }, - "fn-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fn-name/-/fn-name-2.0.1.tgz", - "integrity": "sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc=", - "dev": true - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "1.0.2" - } - }, - "fs-exists-sync": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", - "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=", - "dev": true - }, - "fs-extra": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.0.tgz", - "integrity": "sha1-QU+0yi0hcLoAFBWdOorsMwNBjZ4=", - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "3.0.1", - "universalify": "0.1.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "fsevents": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.2.tgz", - "integrity": "sha512-Sn44E5wQW4bTHXvQmvSHwqbuiXtduD6Rrjm2ZtUEGbyrig+nUH3t/QD4M4/ZXViY556TBpRgZkHLDx3JxPwxiw==", - "dev": true, - "optional": true, - "requires": { - "nan": "2.6.2", - "node-pre-gyp": "0.6.36" - }, - "dependencies": { - "abbrev": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "ajv": { - "version": "4.11.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "aproba": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "1.0.0", - "readable-stream": "2.2.9" - } - }, - "asn1": { - "version": "0.2.3", - "bundled": true, - "dev": true, - "optional": true - }, - "assert-plus": { - "version": "0.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "asynckit": { - "version": "0.4.0", - "bundled": true, - "dev": true, - "optional": true - }, - "aws-sign2": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "aws4": { - "version": "1.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "balanced-match": { - "version": "0.4.2", - "bundled": true, - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "tweetnacl": "0.14.5" - } - }, - "block-stream": { - "version": "0.0.9", - "bundled": true, - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, - "boom": { - "version": "2.10.1", - "bundled": true, - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "brace-expansion": { - "version": "1.1.7", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "0.4.2", - "concat-map": "0.0.1" - } - }, - "buffer-shims": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "caseless": { - "version": "0.12.0", - "bundled": true, - "dev": true, - "optional": true - }, - "co": { - "version": "4.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "combined-stream": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "requires": { - "delayed-stream": "1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "cryptiles": { - "version": "2.0.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "boom": "2.10.1" - } - }, - "dashdash": { - "version": "1.14.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "debug": { - "version": "2.6.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.4.2", - "bundled": true, - "dev": true, - "optional": true - }, - "delayed-stream": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "ecc-jsbn": { - "version": "0.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "extend": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "extsprintf": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "bundled": true, - "dev": true, - "optional": true - }, - "form-data": { - "version": "2.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.15" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "fstream": { - "version": "1.0.11", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.1" - } - }, - "fstream-ignore": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fstream": "1.0.11", - "inherits": "2.0.3", - "minimatch": "3.0.4" - } - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "1.1.1", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" - } - }, - "getpass": { - "version": "0.1.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true, - "dev": true - }, - "har-schema": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "optional": true - }, - "har-validator": { - "version": "4.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "hawk": { - "version": "3.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" - } - }, - "hoek": { - "version": "2.16.3", - "bundled": true, - "dev": true - }, - "http-signature": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.0", - "sshpk": "1.13.0" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "ini": { - "version": "1.3.4", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "isstream": { - "version": "0.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "jodid25519": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "jsbn": { - "version": "0.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "json-schema": { - "version": "0.2.3", - "bundled": true, - "dev": true, - "optional": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsonify": "0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "jsonify": { - "version": "0.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "jsprim": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.0.2", - "json-schema": "0.2.3", - "verror": "1.3.6" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "mime-db": { - "version": "1.27.0", - "bundled": true, - "dev": true - }, - "mime-types": { - "version": "2.1.15", - "bundled": true, - "dev": true, - "requires": { - "mime-db": "1.27.0" - } - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "node-pre-gyp": { - "version": "0.6.36", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "mkdirp": "0.5.1", - "nopt": "4.0.1", - "npmlog": "4.1.0", - "rc": "1.2.1", - "request": "2.81.0", - "rimraf": "2.6.1", - "semver": "5.3.0", - "tar": "2.2.1", - "tar-pack": "3.4.0" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1.1.0", - "osenv": "0.1.4" - } - }, - "npmlog": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "oauth-sign": { - "version": "0.8.2", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "performance-now": { - "version": "0.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "1.0.7", - "bundled": true, - "dev": true - }, - "punycode": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "optional": true - }, - "qs": { - "version": "6.4.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.2.9", - "bundled": true, - "dev": true, - "requires": { - "buffer-shims": "1.0.0", - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "1.0.1", - "util-deprecate": "1.0.2" - } - }, - "request": { - "version": "2.81.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.15", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.0.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.2", - "tunnel-agent": "0.6.0", - "uuid": "3.0.1" - } - }, - "rimraf": { - "version": "2.6.1", - "bundled": true, - "dev": true, - "requires": { - "glob": "7.1.2" - } - }, - "safe-buffer": { - "version": "5.0.1", - "bundled": true, - "dev": true - }, - "semver": { - "version": "5.3.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sntp": { - "version": "1.0.9", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "hoek": "2.16.3" - } - }, - "sshpk": { - "version": "1.13.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jodid25519": "1.0.2", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "string_decoder": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, - "stringstream": { - "version": "0.0.5", - "bundled": true, - "dev": true, - "optional": true - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "2.2.1", - "bundled": true, - "dev": true, - "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" - } - }, - "tar-pack": { - "version": "3.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "2.6.8", - "fstream": "1.0.11", - "fstream-ignore": "1.0.5", - "once": "1.4.0", - "readable-stream": "2.2.9", - "rimraf": "2.6.1", - "tar": "2.2.1", - "uid-number": "0.0.6" - } - }, - "tough-cookie": { - "version": "2.3.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "punycode": "1.4.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "bundled": true, - "dev": true, - "optional": true - }, - "uid-number": { - "version": "0.0.6", - "bundled": true, - "dev": true, - "optional": true - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "uuid": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "verror": { - "version": "1.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "extsprintf": "1.0.2" - } - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - } - } - }, - "fuse.js": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-2.7.4.tgz", - "integrity": "sha1-luQg/efvARrEnCWKYhMU/ldlNvk=" - }, - "gaze": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", - "integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=", - "dev": true, - "requires": { - "globule": "0.1.0" - } - }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", - "dev": true - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "requires": { - "is-property": "1.0.2" - } - }, - "get-port": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-2.1.0.tgz", - "integrity": "sha1-h4P53OvR7qSVozThpqJR54iHqxo=", - "dev": true, - "requires": { - "pinkie-promise": "2.0.1" - } - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "2.0.1" - } - }, - "glob-stream": { - "version": "3.1.18", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", - "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", - "dev": true, - "requires": { - "glob": "4.5.3", - "glob2base": "0.0.12", - "minimatch": "2.0.10", - "ordered-read-streams": "0.1.0", - "through2": "0.6.5", - "unique-stream": "1.0.0" - }, - "dependencies": { - "glob": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", - "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", - "dev": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "2.0.10", - "once": "1.4.0" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "minimatch": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", - "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", - "dev": true, - "requires": { - "brace-expansion": "1.1.8" - } - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - } - } - }, - "glob-watcher": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-0.0.6.tgz", - "integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=", - "dev": true, - "requires": { - "gaze": "0.5.2" - } - }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "0.1.1" - } - }, - "global-modules": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz", - "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", - "dev": true, - "requires": { - "global-prefix": "0.1.5", - "is-windows": "0.2.0" - } - }, - "global-prefix": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz", - "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", - "dev": true, - "requires": { - "homedir-polyfill": "1.0.1", - "ini": "1.3.4", - "is-windows": "0.2.0", - "which": "1.2.14" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - }, - "globule": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/globule/-/globule-0.1.0.tgz", - "integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=", - "dev": true, - "requires": { - "glob": "3.1.21", - "lodash": "1.0.2", - "minimatch": "0.2.14" - }, - "dependencies": { - "glob": { - "version": "3.1.21", - "resolved": "https://registry.npmjs.org/glob/-/glob-3.1.21.tgz", - "integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=", - "dev": true, - "requires": { - "graceful-fs": "1.2.3", - "inherits": "1.0.2", - "minimatch": "0.2.14" - } - }, - "graceful-fs": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.2.3.tgz", - "integrity": "sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q=", - "dev": true - }, - "inherits": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-1.0.2.tgz", - "integrity": "sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js=", - "dev": true - }, - "lodash": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", - "integrity": "sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE=", - "dev": true - }, - "lru-cache": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.7.3.tgz", - "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", - "dev": true - }, - "minimatch": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-0.2.14.tgz", - "integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=", - "dev": true, - "requires": { - "lru-cache": "2.7.3", - "sigmund": "1.0.1" - } - } - } - }, - "glogg": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", - "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", - "dev": true, - "requires": { - "sparkles": "1.0.0" - } - }, - "got": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", - "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", - "requires": { - "create-error-class": "3.0.2", - "duplexer3": "0.1.4", - "get-stream": "3.0.0", - "is-redirect": "1.0.0", - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "lowercase-keys": "1.0.0", - "safe-buffer": "5.1.1", - "timed-out": "4.0.1", - "unzip-response": "2.0.1", - "url-parse-lax": "1.0.0" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" - }, - "growly": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" - }, - "gulp": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/gulp/-/gulp-3.9.1.tgz", - "integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=", - "dev": true, - "requires": { - "archy": "1.0.0", - "chalk": "1.1.3", - "deprecated": "0.0.1", - "gulp-util": "3.0.8", - "interpret": "1.0.3", - "liftoff": "2.3.0", - "minimist": "1.2.0", - "orchestrator": "0.3.8", - "pretty-hrtime": "1.0.3", - "semver": "4.3.6", - "tildify": "1.2.0", - "v8flags": "2.1.1", - "vinyl-fs": "0.3.14" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "semver": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/semver/-/semver-4.3.6.tgz", - "integrity": "sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=", - "dev": true - } - } - }, - "gulp-babel": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/gulp-babel/-/gulp-babel-6.1.2.tgz", - "integrity": "sha1-fAF25Lo/JExgWIoMSzIKRdGt784=", - "dev": true, - "requires": { - "babel-core": "6.25.0", - "gulp-util": "3.0.8", - "object-assign": "4.1.1", - "replace-ext": "0.0.1", - "through2": "2.0.3", - "vinyl-sourcemaps-apply": "0.2.1" - } - }, - "gulp-eslint": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/gulp-eslint/-/gulp-eslint-3.0.1.tgz", - "integrity": "sha1-BOV+PhjGl0JnwSz2hV3HF9SjE70=", - "dev": true, - "requires": { - "bufferstreams": "1.1.1", - "eslint": "3.19.0", - "gulp-util": "3.0.8" - } - }, - "gulp-rename": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.2.2.tgz", - "integrity": "sha1-OtRCh2PwXidk3sHGfYaNsnVoeBc=", - "dev": true - }, - "gulp-sourcemaps": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.0.tgz", - "integrity": "sha1-fMzomaijv8oVk6M0jQ+/Qd0/UeU=", - "dev": true, - "requires": { - "@gulp-sourcemaps/identity-map": "1.0.1", - "@gulp-sourcemaps/map-sources": "1.0.0", - "acorn": "4.0.13", - "convert-source-map": "1.5.0", - "css": "2.2.1", - "debug-fabulous": "0.1.0", - "detect-newline": "2.1.0", - "graceful-fs": "4.1.11", - "source-map": "0.5.6", - "strip-bom-string": "1.0.0", - "through2": "2.0.3", - "vinyl": "1.2.0" - }, - "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true - }, - "vinyl": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", - "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", - "dev": true, - "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - } - } - }, - "gulp-util": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", - "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", - "dev": true, - "requires": { - "array-differ": "1.0.0", - "array-uniq": "1.0.3", - "beeper": "1.1.1", - "chalk": "1.1.3", - "dateformat": "2.0.0", - "fancy-log": "1.3.0", - "gulplog": "1.0.0", - "has-gulplog": "0.1.0", - "lodash._reescape": "3.0.0", - "lodash._reevaluate": "3.0.0", - "lodash._reinterpolate": "3.0.0", - "lodash.template": "3.6.2", - "minimist": "1.2.0", - "multipipe": "0.1.2", - "object-assign": "3.0.0", - "replace-ext": "0.0.1", - "through2": "2.0.3", - "vinyl": "0.5.3" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "object-assign": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", - "dev": true - } - } - }, - "gulplog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", - "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", - "dev": true, - "requires": { - "glogg": "1.0.0" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "2.1.1" - } - }, - "has-color": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", - "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "has-gulplog": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", - "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", - "dev": true, - "requires": { - "sparkles": "1.0.0" - } - }, - "has-yarn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-1.0.0.tgz", - "integrity": "sha1-ieJdtgS3Jcj1l2//Ct3JIbgopac=", - "dev": true - }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "dev": true, - "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" - } - }, - "homedir-polyfill": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", - "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", - "dev": true, - "requires": { - "parse-passwd": "1.0.0" - } - }, - "hook-std": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-0.3.0.tgz", - "integrity": "sha1-HnXwZYlnrB+dfBe57G69mT+IKOU=", - "dev": true - }, - "hosted-git-info": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.4.2.tgz", - "integrity": "sha1-AHa59GonBQbduq6lZJaJdGBhKmc=" - }, - "ignore": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.3.tgz", - "integrity": "sha1-QyNS5XrM2HqzEQ6C0/6g5HgSFW0=", - "dev": true - }, - "ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", - "dev": true - }, - "import-modules": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-1.1.0.tgz", - "integrity": "sha1-dI23nFzEK7lwHvq0JPiU5yYA6dw=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "indent-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.1.0.tgz", - "integrity": "sha1-CP9DNGAziDmbMp5rlTjcejz13n0=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" - }, - "ini": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", - "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=" - }, - "inquirer": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", - "dev": true, - "requires": { - "ansi-escapes": "1.4.0", - "ansi-regex": "2.1.1", - "chalk": "1.1.3", - "cli-cursor": "1.0.2", - "cli-width": "2.1.0", - "figures": "1.7.0", - "lodash": "4.17.4", - "readline2": "1.0.1", - "run-async": "0.1.0", - "rx-lite": "3.1.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "through": "2.3.8" - }, - "dependencies": { - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "dev": true, - "requires": { - "restore-cursor": "1.0.1" - } - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" - } - }, - "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "dev": true, - "requires": { - "exit-hook": "1.1.1", - "onetime": "1.1.0" - } - } - } - }, - "interpret": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", - "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=", - "dev": true - }, - "invariant": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", - "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", - "dev": true, - "requires": { - "loose-envify": "1.3.1" - } - }, - "irregular-plurals": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.2.0.tgz", - "integrity": "sha1-OPKZg0uowAwwvpxVThNyaXUv86w=", - "dev": true - }, - "is-absolute": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz", - "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=", - "dev": true, - "requires": { - "is-relative": "0.2.1", - "is-windows": "0.2.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "1.8.0" - } - }, - "is-buffer": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", - "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", - "dev": true - }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "requires": { - "builtin-modules": "1.1.1" - } - }, - "is-ci": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", - "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", - "dev": true, - "requires": { - "ci-info": "1.0.0" - } - }, - "is-docker": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-1.1.0.tgz", - "integrity": "sha1-8EN01O7lMQ6ajhE78UlUEeRhdqE=" - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "2.0.0" - } - }, - "is-error": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.1.tgz", - "integrity": "sha1-aEqW2EB2V3yY9M20DG0mpRI78Zw=", - "dev": true - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-generator-fn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz", - "integrity": "sha1-lp1J4bszKfa7fwkIm+JleLLd1Go=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "is-my-json-valid": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz", - "integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=", - "dev": true, - "requires": { - "generate-function": "2.0.0", - "generate-object-property": "1.2.0", - "jsonpointer": "4.0.1", - "xtend": "4.0.1" - } - }, - "is-npm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", - "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", - "dev": true - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - } - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" - }, - "is-observable": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-0.2.0.tgz", - "integrity": "sha1-s2ExHYPG5dcmyr9eJQsCNxBvWuI=", - "dev": true, - "requires": { - "symbol-observable": "0.2.4" - } - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=" - }, - "is-path-in-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", - "requires": { - "is-path-inside": "1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", - "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", - "requires": { - "path-is-inside": "1.0.2" - } - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true - }, - "is-plain-object": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.3.tgz", - "integrity": "sha1-wVvz5LZrYtcu+vKSWEhmPsvGGbY=", - "dev": true, - "requires": { - "isobject": "3.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.0.tgz", - "integrity": "sha1-OVZSF/NmF4nooKDAgNX35rxG4aA=", - "dev": true - } - } - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "dev": true - }, - "is-redirect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=" - }, - "is-relative": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz", - "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=", - "dev": true, - "requires": { - "is-unc-path": "0.1.2" - } - }, - "is-resolvable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", - "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", - "dev": true, - "requires": { - "tryit": "1.0.3" - } - }, - "is-retry-allowed": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=" - }, - "is-root": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-root/-/is-root-1.0.0.tgz", - "integrity": "sha1-B7bCM7w5TNnQK6FclmvWZg1jQtU=" - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" - }, - "is-unc-path": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz", - "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=", - "dev": true, - "requires": { - "unc-path-regex": "0.1.2" - } - }, - "is-url": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.2.tgz", - "integrity": "sha1-SYkFpZO/R8wtnn9zg3K792lsfyY=", - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" - }, - "is-windows": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz", - "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "jest-diff": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-18.1.0.tgz", - "integrity": "sha1-T/eedN2YjBORlbNl3GXYf2BvSAM=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "diff": "3.2.0", - "jest-matcher-utils": "18.1.0", - "pretty-format": "18.1.0" - } - }, - "jest-file-exists": { - "version": "17.0.0", - "resolved": "https://registry.npmjs.org/jest-file-exists/-/jest-file-exists-17.0.0.tgz", - "integrity": "sha1-f2Prc6HEOhP0Yb4mF2i0WvLN0Wk=", - "dev": true - }, - "jest-matcher-utils": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-18.1.0.tgz", - "integrity": "sha1-GsRlGVXuKmDO8ef8yYzf13PA+TI=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "pretty-format": "18.1.0" - } - }, - "jest-mock": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-18.0.0.tgz", - "integrity": "sha1-XCSIRuoz+lWLUm9TEqtKZ2XkibM=", - "dev": true - }, - "jest-snapshot": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-18.1.0.tgz", - "integrity": "sha1-VbltLuY5ybznb4fyo/1Atxx6WRY=", - "dev": true, - "requires": { - "jest-diff": "18.1.0", - "jest-file-exists": "17.0.0", - "jest-matcher-utils": "18.1.0", - "jest-util": "18.1.0", - "natural-compare": "1.4.0", - "pretty-format": "18.1.0" - } - }, - "jest-util": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-18.1.0.tgz", - "integrity": "sha1-OpnDIRSrF/hL4JQ4JScAbm1L/Go=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "diff": "3.2.0", - "graceful-fs": "4.1.11", - "jest-file-exists": "17.0.0", - "jest-mock": "18.0.0", - "mkdirp": "0.5.1" - } - }, - "js-tokens": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.1.tgz", - "integrity": "sha1-COnxMkhKLEWjCQfp3E1VZ7fxFNc=", - "dev": true - }, - "js-yaml": { - "version": "3.8.4", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.8.4.tgz", - "integrity": "sha1-UgtFZPhlc7qWZir4Woyvp7S1pvY=", - "dev": true, - "requires": { - "argparse": "1.0.9", - "esprima": "3.1.3" - } - }, - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "requires": { - "jsonify": "0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "jsonfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", - "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", - "requires": { - "graceful-fs": "4.1.11" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.5" - } - }, - "last-line-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/last-line-stream/-/last-line-stream-1.0.0.tgz", - "integrity": "sha1-0bZNafhv8kry0EiDos7uFFIKVgA=", - "dev": true, - "requires": { - "through2": "2.0.3" - } - }, - "latest-version": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", - "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", - "requires": { - "package-json": "4.0.1" - } - }, - "lazy-req": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/lazy-req/-/lazy-req-1.1.0.tgz", - "integrity": "sha1-va6+rTD42CQDnODOFJ1Nqge6H6w=", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" - } - }, - "liftoff": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz", - "integrity": "sha1-qY8v9nGD2Lp8+soQVIvX/wVQs4U=", - "dev": true, - "requires": { - "extend": "3.0.1", - "findup-sync": "0.4.3", - "fined": "1.1.0", - "flagged-respawn": "0.3.2", - "lodash.isplainobject": "4.0.6", - "lodash.isstring": "4.0.1", - "lodash.mapvalues": "4.6.0", - "rechoir": "0.6.2", - "resolve": "1.3.3" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "2.0.0", - "path-exists": "3.0.0" - } - }, - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", - "dev": true - }, - "lodash._basecopy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", - "dev": true - }, - "lodash._basetostring": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", - "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", - "dev": true - }, - "lodash._basevalues": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", - "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", - "dev": true - }, - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", - "dev": true - }, - "lodash._isiterateecall": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", - "dev": true - }, - "lodash._reescape": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", - "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", - "dev": true - }, - "lodash._reevaluate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", - "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", - "dev": true - }, - "lodash._reinterpolate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "lodash._root": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", - "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", - "dev": true - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.escape": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", - "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", - "dev": true, - "requires": { - "lodash._root": "3.0.1" - } - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", - "dev": true - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", - "dev": true - }, - "lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.isstring": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=", - "dev": true - }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "dev": true, - "requires": { - "lodash._getnative": "3.9.1", - "lodash.isarguments": "3.1.0", - "lodash.isarray": "3.0.4" - } - }, - "lodash.mapvalues": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", - "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=", - "dev": true - }, - "lodash.restparam": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", - "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", - "dev": true - }, - "lodash.template": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", - "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", - "dev": true, - "requires": { - "lodash._basecopy": "3.0.1", - "lodash._basetostring": "3.0.1", - "lodash._basevalues": "3.0.0", - "lodash._isiterateecall": "3.0.9", - "lodash._reinterpolate": "3.0.0", - "lodash.escape": "3.2.0", - "lodash.keys": "3.1.2", - "lodash.restparam": "3.6.1", - "lodash.templatesettings": "3.1.1" - } - }, - "lodash.templatesettings": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", - "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", - "dev": true, - "requires": { - "lodash._reinterpolate": "3.0.0", - "lodash.escape": "3.2.0" - } - }, - "log-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", - "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", - "dev": true, - "requires": { - "chalk": "1.1.3" - } - }, - "loose-envify": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", - "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", - "dev": true, - "requires": { - "js-tokens": "3.0.1" - } - }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true, - "requires": { - "currently-unhandled": "0.4.1", - "signal-exit": "3.0.2" - } - }, - "lowercase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", - "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=" - }, - "lru-cache": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", - "dev": true, - "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" - } - }, - "make-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.0.0.tgz", - "integrity": "sha1-l6ARdR6R3YfPre9Ygy67BJNt6Xg=", - "dev": true, - "requires": { - "pify": "2.3.0" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "matcher": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-0.1.2.tgz", - "integrity": "sha1-7yDL3mTCTFDMYa9bg+4LG4/wAQE=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5" - } - }, - "max-timeout": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/max-timeout/-/max-timeout-1.0.0.tgz", - "integrity": "sha1-to9povmeC0dv1Msj4gWcp1BxXh8=", - "dev": true - }, - "md5-hex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-2.0.0.tgz", - "integrity": "sha1-0FiOnxx0lUSS7NJKwKxs6ZfZLjM=", - "dev": true, - "requires": { - "md5-o-matic": "0.1.1" - } - }, - "md5-o-matic": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz", - "integrity": "sha1-givM1l4RfFFPqxdrJZRdVBAKA8M=", - "dev": true - }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "2.1.0", - "decamelize": "1.2.0", - "loud-rejection": "1.6.0", - "map-obj": "1.0.1", - "minimist": "1.2.0", - "normalize-package-data": "2.3.8", - "object-assign": "4.1.1", - "read-pkg-up": "1.0.1", - "redent": "1.0.0", - "trim-newlines": "1.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.3" - } - }, - "mimic-fn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", - "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "1.1.8" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } - }, - "moment": { - "version": "2.18.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz", - "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8=" - }, - "ms": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.3.tgz", - "integrity": "sha1-cIFVpeROM/X9D8U+gdDUCpG+H/8=", - "dev": true - }, - "multimatch": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", - "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", - "dev": true, - "requires": { - "array-differ": "1.0.0", - "array-union": "1.0.2", - "arrify": "1.0.1", - "minimatch": "3.0.4" - } - }, - "multipipe": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", - "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", - "dev": true, - "requires": { - "duplexer2": "0.0.2" - }, - "dependencies": { - "duplexer2": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", - "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", - "dev": true, - "requires": { - "readable-stream": "1.1.14" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, - "mute-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", - "dev": true - }, - "nan": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz", - "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=", - "dev": true, - "optional": true - }, - "natives": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.0.tgz", - "integrity": "sha1-6f+EFBimsux6SV6TmYT3jxY+bjE=", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "nock": { - "version": "9.0.14", - "resolved": "https://registry.npmjs.org/nock/-/nock-9.0.14.tgz", - "integrity": "sha1-IhFVAlMXPOKYvNifyoJeg4E8pys=", - "dev": true, - "requires": { - "chai": "3.5.0", - "debug": "2.6.8", - "deep-equal": "1.0.1", - "json-stringify-safe": "5.0.1", - "lodash": "4.17.4", - "mkdirp": "0.5.1", - "propagate": "0.4.0", - "qs": "6.5.0", - "semver": "5.4.1" - } - }, - "node-notifier": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.1.2.tgz", - "integrity": "sha1-L6nhJgX6EACdRFSdb82KY93g5P8=", - "requires": { - "growly": "1.3.0", - "semver": "5.4.1", - "shellwords": "0.1.0", - "which": "1.2.14" - } - }, - "node-status-codes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz", - "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8=", - "dev": true - }, - "normalize-package-data": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.8.tgz", - "integrity": "sha1-2Bntoqne29H/pWPqQHHZNngilbs=", - "requires": { - "hosted-git-info": "2.4.2", - "is-builtin-module": "1.0.0", - "semver": "5.4.1", - "validate-npm-package-license": "3.0.1" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "1.0.2" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "2.0.1" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", - "dev": true, - "requires": { - "array-each": "1.0.1", - "array-slice": "1.0.0", - "for-own": "1.0.0", - "isobject": "3.0.0" - }, - "dependencies": { - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "1.0.2" - } - }, - "isobject": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.0.tgz", - "integrity": "sha1-OVZSF/NmF4nooKDAgNX35rxG4aA=", - "dev": true - } - } - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" - } - }, - "object.pick": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.2.0.tgz", - "integrity": "sha1-tTkr7peC2m2ft9avr1OXefEjTCs=", - "dev": true, - "requires": { - "isobject": "2.1.0" - } - }, - "observable-to-promise": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/observable-to-promise/-/observable-to-promise-0.4.0.tgz", - "integrity": "sha1-KK/nFkUwjy1B1x9HrT/s4aN35Ss=", - "dev": true, - "requires": { - "is-observable": "0.2.0", - "symbol-observable": "0.2.4" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1.0.2" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "1.1.0" - } - }, - "option-chain": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/option-chain/-/option-chain-0.1.1.tgz", - "integrity": "sha1-6bgR4AbxwPVIAvKClb/Ilw+Nz70=", - "dev": true, - "requires": { - "object-assign": "4.1.1" - } - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "2.0.6", - "levn": "0.3.0", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "1.0.0" - } - }, - "orchestrator": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/orchestrator/-/orchestrator-0.3.8.tgz", - "integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=", - "dev": true, - "requires": { - "end-of-stream": "0.1.5", - "sequencify": "0.0.7", - "stream-consume": "0.1.0" - } - }, - "ordered-read-streams": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz", - "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "osenv": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz", - "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=", - "dev": true, - "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", - "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", - "dev": true - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "1.1.0" - } - }, - "package-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-1.2.0.tgz", - "integrity": "sha1-AD5WzVe3NqbtYRTMK4FUJnJ3DkQ=", - "dev": true, - "requires": { - "md5-hex": "1.3.0" - }, - "dependencies": { - "md5-hex": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.3.0.tgz", - "integrity": "sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ=", - "dev": true, - "requires": { - "md5-o-matic": "0.1.1" - } - } - } - }, - "package-json": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", - "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", - "requires": { - "got": "6.7.1", - "registry-auth-token": "3.3.1", - "registry-url": "3.1.0", - "semver": "5.4.1" - } - }, - "parse-filepath": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.1.tgz", - "integrity": "sha1-FZ1hVdQ5BNFsEO9piRHaHpGWm3M=", - "dev": true, - "requires": { - "is-absolute": "0.2.6", - "map-cache": "0.2.2", - "path-root": "0.1.1" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.3", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "requires": { - "error-ex": "1.3.1" - } - }, - "parse-ms": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz", - "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=", - "dev": true - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true - }, - "path-root": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", - "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", - "dev": true, - "requires": { - "path-root-regex": "0.1.2" - } - }, - "path-root-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", - "dev": true - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "requires": { - "pinkie": "2.0.4" - } - }, - "pkg-conf": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.0.0.tgz", - "integrity": "sha1-BxyHZQQDvM+5xif1h1G/5HwGcnk=", - "dev": true, - "requires": { - "find-up": "2.1.0", - "load-json-file": "2.0.0" - }, - "dependencies": { - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "2.0.0" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "strip-bom": "3.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } - } - }, - "pkg-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", - "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", - "dev": true, - "requires": { - "find-up": "1.1.2" - } - }, - "pkg-up": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-1.0.0.tgz", - "integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=", - "requires": { - "find-up": "1.1.2" - } - }, - "plist": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/plist/-/plist-2.1.0.tgz", - "integrity": "sha1-V8zbeggh3yGDEhejytVOPhRqECU=", - "requires": { - "base64-js": "1.2.0", - "xmlbuilder": "8.2.2", - "xmldom": "0.1.27" - } - }, - "plur": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", - "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", - "dev": true, - "requires": { - "irregular-plurals": "1.2.0" - } - }, - "pluralize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "pretty-format": { - "version": "18.1.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-18.1.0.tgz", - "integrity": "sha1-+2Wob3p/kZSWPu6RhlwbzxA54oQ=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1" - } - }, - "pretty-hrtime": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", - "dev": true - }, - "pretty-ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz", - "integrity": "sha1-QlfCVt8/sLRR1q/6qwIYhBJpgdw=", - "dev": true, - "requires": { - "is-finite": "1.0.2", - "parse-ms": "1.0.1", - "plur": "1.0.0" - }, - "dependencies": { - "plur": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz", - "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=", - "dev": true - } - } - }, - "private": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", - "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=", - "dev": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", - "dev": true - }, - "propagate": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/propagate/-/propagate-0.4.0.tgz", - "integrity": "sha1-8/zKCm/gZzanulcpZgaWF8EwtIE=", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "qs": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.0.tgz", - "integrity": "sha512-fjVFjW9yhqMhVGwRExCXLhJKrLlkYSaxNWdyc9rmHlrVZbk35YHH312dFd7191uQeXkI3mKLZTIbSvIeFwFemg==", - "dev": true - }, - "randomatic": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", - "dev": true, - "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "1.1.5" - } - } - } - }, - "rc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz", - "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=", - "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" - } - } - }, - "read-all-stream": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/read-all-stream/-/read-all-stream-3.1.0.tgz", - "integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=", - "dev": true, - "requires": { - "pinkie-promise": "2.0.1", - "readable-stream": "2.3.2" - } - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "requires": { - "load-json-file": "2.0.0", - "normalize-package-data": "2.3.8", - "path-type": "2.0.0" - }, - "dependencies": { - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "strip-bom": "3.0.0" - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "requires": { - "pify": "2.3.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=" - } - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" - }, - "dependencies": { - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.3.8", - "path-type": "1.1.0" - } - } - } - }, - "readable-stream": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.2.tgz", - "integrity": "sha1-WgTfBeT1f+Pw3Gj90R3FyXx+b00=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "readdirp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", - "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "minimatch": "3.0.4", - "readable-stream": "2.3.2", - "set-immediate-shim": "1.0.1" - } - }, - "readline2": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "mute-stream": "0.0.5" - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "1.3.3" - } - }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "2.1.0", - "strip-indent": "1.0.1" - }, - "dependencies": { - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "2.0.1" - } - } - } - }, - "regenerate": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz", - "integrity": "sha1-0ZQcZ7rUN+G+dkM63Vs4X5WxkmA=", - "dev": true - }, - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" - }, - "regenerator-transform": { - "version": "0.9.11", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.9.11.tgz", - "integrity": "sha1-On0GdSDLe3F2dp61/4aGkb7+EoM=", - "dev": true, - "requires": { - "babel-runtime": "6.23.0", - "babel-types": "6.25.0", - "private": "0.1.7" - } - }, - "regex-cache": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz", - "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=", - "dev": true, - "requires": { - "is-equal-shallow": "0.1.3", - "is-primitive": "2.0.0" - } - }, - "regexpu-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", - "dev": true, - "requires": { - "regenerate": "1.3.2", - "regjsgen": "0.2.0", - "regjsparser": "0.1.5" - } - }, - "registry-auth-token": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz", - "integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=", - "requires": { - "rc": "1.2.1", - "safe-buffer": "5.1.1" - } - }, - "registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", - "requires": { - "rc": "1.2.1" - } - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", - "dev": true - }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", - "dev": true, - "requires": { - "jsesc": "0.5.0" - } - }, - "remove-trailing-separator": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz", - "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=", - "dev": true - }, - "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "1.0.2" - } - }, - "replace-ext": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", - "dev": true - }, - "require-precompiled": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/require-precompiled/-/require-precompiled-0.1.0.tgz", - "integrity": "sha1-WhtS63Dr7UPrmC6XTIWrWVceVvo=", - "dev": true - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" - }, - "dependencies": { - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - } - } - }, - "resolve": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.3.3.tgz", - "integrity": "sha1-ZVkHw0aahoDcLeOidaj91paR8OU=", - "dev": true, - "requires": { - "path-parse": "1.0.5" - } - }, - "resolve-alfred-prefs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-alfred-prefs/-/resolve-alfred-prefs-1.0.0.tgz", - "integrity": "sha1-qukUCIV4gptYSk5rclB+jCCW7Dc=", - "requires": { - "bplist-parser": "0.1.1", - "path-exists": "3.0.0", - "pify": "2.3.0", - "untildify": "3.0.2", - "user-home": "2.0.0" - } - }, - "resolve-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-1.0.0.tgz", - "integrity": "sha1-Tq7qQe0EDRcCRX32SkKysH0kb58=", - "dev": true, - "requires": { - "resolve-from": "2.0.0" - } - }, - "resolve-dir": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz", - "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", - "dev": true, - "requires": { - "expand-tilde": "1.2.2", - "global-modules": "0.2.3" - } - }, - "resolve-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "2.0.1", - "signal-exit": "3.0.2" - } - }, - "rimraf": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", - "requires": { - "glob": "7.1.2" - } - }, - "run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", - "dev": true, - "requires": { - "once": "1.4.0" - } - }, - "rx-lite": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", - "dev": true - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" - }, - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" - }, - "semver-diff": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", - "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", - "dev": true, - "requires": { - "semver": "5.4.1" - } - }, - "sequencify": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/sequencify/-/sequencify-0.0.7.tgz", - "integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=", - "dev": true - }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true - }, - "shelljs": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", - "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", - "dev": true, - "requires": { - "glob": "7.1.2", - "interpret": "1.0.3", - "rechoir": "0.6.2" - } - }, - "shellwords": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.0.tgz", - "integrity": "sha1-Zq/Ue2oSky2Qccv9mKUueFzQuhQ=" - }, - "sigmund": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sigmund/-/sigmund-1.0.1.tgz", - "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, - "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - }, - "slide": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", - "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", - "dev": true - }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "dev": true, - "requires": { - "is-plain-obj": "1.1.0" - } - }, - "source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", - "dev": true - }, - "source-map-resolve": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz", - "integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=", - "dev": true, - "requires": { - "atob": "1.1.3", - "resolve-url": "0.2.1", - "source-map-url": "0.3.0", - "urix": "0.1.0" - } - }, - "source-map-support": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.15.tgz", - "integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=", - "dev": true, - "requires": { - "source-map": "0.5.6" - } - }, - "source-map-url": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz", - "integrity": "sha1-fsrxO1e80J2opAxdJp2zN5nUqvk=", - "dev": true - }, - "sparkles": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", - "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", - "dev": true - }, - "spdx-correct": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", - "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", - "requires": { - "spdx-license-ids": "1.2.2" - } - }, - "spdx-expression-parse": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", - "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=" - }, - "spdx-license-ids": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", - "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=" - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha1-1PM6tU6OOHeLDKXP07OvsS22hiA=", - "dev": true - }, - "stream-consume": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz", - "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "requires": { - "is-utf8": "0.2.1" - } - }, - "strip-bom-buf": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz", - "integrity": "sha1-HLRar1dTD0yvhsf3UXnSyaUd1XI=", - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - }, - "strip-bom-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz", - "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=", - "dev": true - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "4.0.1" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" - }, - "sudo-block": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/sudo-block/-/sudo-block-1.2.0.tgz", - "integrity": "sha1-zFOb+BkWJNT1B9g+60W0zqJ/NGM=", - "requires": { - "chalk": "1.1.3", - "is-docker": "1.1.0", - "is-root": "1.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - }, - "symbol-observable": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-0.2.4.tgz", - "integrity": "sha1-lag9smGG1q9+ehjb2XYKL4bQj0A=", - "dev": true - }, - "table": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", - "dev": true, - "requires": { - "ajv": "4.11.8", - "ajv-keywords": "1.5.1", - "chalk": "1.1.3", - "lodash": "4.17.4", - "slice-ansi": "0.0.4", - "string-width": "2.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "string-width": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.0.0.tgz", - "integrity": "sha1-Y1xUNsxypuDDh87KJ41OLuxSaH4=", - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "3.0.1" - } - } - } - }, - "temp-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", - "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=", - "dev": true - }, - "tempy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/tempy/-/tempy-0.1.0.tgz", - "integrity": "sha1-hSdBPNBxAINPzJy7gkK+lboOH+4=", - "dev": true, - "requires": { - "pify": "2.3.0", - "temp-dir": "1.0.0", - "unique-string": "1.0.0" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "through2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", - "dev": true, - "requires": { - "readable-stream": "2.3.2", - "xtend": "4.0.1" - } - }, - "tildify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", - "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", - "dev": true, - "requires": { - "os-homedir": "1.0.2" - } - }, - "time-require": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/time-require/-/time-require-0.1.2.tgz", - "integrity": "sha1-+eEss3D8JgXhFARYK6VO9corLZg=", - "dev": true, - "requires": { - "chalk": "0.4.0", - "date-time": "0.1.1", - "pretty-ms": "0.2.2", - "text-table": "0.2.0" - }, - "dependencies": { - "ansi-styles": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", - "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", - "dev": true - }, - "chalk": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", - "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", - "dev": true, - "requires": { - "ansi-styles": "1.0.0", - "has-color": "0.1.7", - "strip-ansi": "0.1.1" - } - }, - "parse-ms": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-0.1.2.tgz", - "integrity": "sha1-3T+iXtbC78e93hKtm0bBY6opIk4=", - "dev": true - }, - "pretty-ms": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-0.2.2.tgz", - "integrity": "sha1-2oeaaC/zOjcBEEbxPWJ/Z8c7hPY=", - "dev": true, - "requires": { - "parse-ms": "0.1.2" - } - }, - "strip-ansi": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", - "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", - "dev": true - } - } - }, - "time-stamp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", - "dev": true - }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" - }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, - "tryit": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", - "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "1.1.2" - } - }, - "type-detect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz", - "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=", - "dev": true - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "uid2": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", - "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=", - "dev": true - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true - }, - "unique-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", - "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=", - "dev": true - }, - "unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", - "dev": true, - "requires": { - "crypto-random-string": "1.0.0" - } - }, - "unique-temp-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-temp-dir/-/unique-temp-dir-1.0.0.tgz", - "integrity": "sha1-bc6VsmgcoAPuv7MEpBX5y6vMU4U=", - "dev": true, - "requires": { - "mkdirp": "0.5.1", - "os-tmpdir": "1.0.2", - "uid2": "0.0.3" - } - }, - "universalify": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", - "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=" - }, - "untildify": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/untildify/-/untildify-3.0.2.tgz", - "integrity": "sha1-fx8wIFWz/qDz6B3HjrNnZstl4/E=" - }, - "unzip-response": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", - "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=" - }, - "update-notifier": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-1.0.3.tgz", - "integrity": "sha1-j5LFFUgr1oMbfJMBPnD4dVLHz1o=", - "dev": true, - "requires": { - "boxen": "0.6.0", - "chalk": "1.1.3", - "configstore": "2.1.0", - "is-npm": "1.0.0", - "latest-version": "2.0.0", - "lazy-req": "1.1.0", - "semver-diff": "2.1.0", - "xdg-basedir": "2.0.0" - }, - "dependencies": { - "got": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-5.7.1.tgz", - "integrity": "sha1-X4FjWmHkplifGAVp6k44FoClHzU=", - "dev": true, - "requires": { - "create-error-class": "3.0.2", - "duplexer2": "0.1.4", - "is-redirect": "1.0.0", - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "lowercase-keys": "1.0.0", - "node-status-codes": "1.0.0", - "object-assign": "4.1.1", - "parse-json": "2.2.0", - "pinkie-promise": "2.0.1", - "read-all-stream": "3.1.0", - "readable-stream": "2.3.2", - "timed-out": "3.1.3", - "unzip-response": "1.0.2", - "url-parse-lax": "1.0.0" - } - }, - "latest-version": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-2.0.0.tgz", - "integrity": "sha1-VvjWE5YghHuAF/jx9NeOIRMkFos=", - "dev": true, - "requires": { - "package-json": "2.4.0" - } - }, - "package-json": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-2.4.0.tgz", - "integrity": "sha1-DRW9Z9HLvduyyiIv8u24a8sxqLs=", - "dev": true, - "requires": { - "got": "5.7.1", - "registry-auth-token": "3.3.1", - "registry-url": "3.1.0", - "semver": "5.4.1" - } - }, - "timed-out": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-3.1.3.tgz", - "integrity": "sha1-lYYL/MXHbCd/j4Mm/Q9bLiDrohc=", - "dev": true - }, - "unzip-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz", - "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=", - "dev": true - } - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "requires": { - "prepend-http": "1.0.4" - } - }, - "user-home": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", - "requires": { - "os-homedir": "1.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "uuid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", - "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", - "dev": true - }, - "v8flags": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-2.1.1.tgz", - "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", - "dev": true, - "requires": { - "user-home": "1.1.1" - }, - "dependencies": { - "user-home": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz", - "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA=", - "dev": true - } - } - }, - "validate-npm-package-license": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", - "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", - "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" - } - }, - "vinyl": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", - "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", - "dev": true, - "requires": { - "clone": "1.0.2", - "clone-stats": "0.0.1", - "replace-ext": "0.0.1" - } - }, - "vinyl-fs": { - "version": "0.3.14", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-0.3.14.tgz", - "integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=", - "dev": true, - "requires": { - "defaults": "1.0.3", - "glob-stream": "3.1.18", - "glob-watcher": "0.0.6", - "graceful-fs": "3.0.11", - "mkdirp": "0.5.1", - "strip-bom": "1.0.0", - "through2": "0.6.5", - "vinyl": "0.4.6" - }, - "dependencies": { - "clone": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", - "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", - "dev": true - }, - "graceful-fs": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-3.0.11.tgz", - "integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=", - "dev": true, - "requires": { - "natives": "1.1.0" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "strip-bom": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-1.0.0.tgz", - "integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=", - "dev": true, - "requires": { - "first-chunk-stream": "1.0.0", - "is-utf8": "0.2.1" - } - }, - "through2": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": "1.0.34", - "xtend": "4.0.1" - } - }, - "vinyl": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", - "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", - "dev": true, - "requires": { - "clone": "0.2.0", - "clone-stats": "0.0.1" - } - } - } - }, - "vinyl-sourcemaps-apply": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", - "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", - "dev": true, - "requires": { - "source-map": "0.5.6" - } - }, - "which": { - "version": "1.2.14", - "resolved": "https://registry.npmjs.org/which/-/which-1.2.14.tgz", - "integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=", - "requires": { - "isexe": "2.0.0" - } - }, - "widest-line": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-1.0.0.tgz", - "integrity": "sha1-DAnIXCqUaD0Nfq+O4JfVZL8OEFw=", - "dev": true, - "requires": { - "string-width": "1.0.2" - } - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "0.5.1" - } - }, - "write-file-atomic": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.1.0.tgz", - "integrity": "sha512-0TZ20a+xcIl4u0+Mj5xDH2yOWdmQiXlKf9Hm+TgDXjTMsEYb+gDrmb8e8UNAzMCitX8NBqG4Z/FUQIyzv/R1JQ==", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "imurmurhash": "0.1.4", - "slide": "1.1.6" - } - }, - "write-json-file": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-2.2.0.tgz", - "integrity": "sha1-UYYlBruzthnu+reFnx/WxtBTCHY=", - "dev": true, - "requires": { - "detect-indent": "5.0.0", - "graceful-fs": "4.1.11", - "make-dir": "1.0.0", - "pify": "2.3.0", - "sort-keys": "1.1.2", - "write-file-atomic": "2.1.0" - }, - "dependencies": { - "detect-indent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", - "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=", - "dev": true - } - } - }, - "write-pkg": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/write-pkg/-/write-pkg-2.1.0.tgz", - "integrity": "sha1-NTqkTDnEjCFED1wIzmq9RhQcnAg=", - "dev": true, - "requires": { - "sort-keys": "1.1.2", - "write-json-file": "2.2.0" - } - }, - "xdg-basedir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-2.0.0.tgz", - "integrity": "sha1-7byQPMOF/ARSPZZqM1UEtVBNG9I=", - "dev": true, - "requires": { - "os-homedir": "1.0.2" - } - }, - "xmlbuilder": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz", - "integrity": "sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M=" - }, - "xmldom": { - "version": "0.1.27", - "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.27.tgz", - "integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=" - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - } - } -} diff --git a/package.json b/package.json index 1599ea8..6220b81 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "alfred-hugo", - "version": "1.2.0", + "version": "2.0.0", "description": "Alfred workflow bindings for NodeJS", "author": "Maarten de Boer (https://cloudstek.nl)", "contributors": [ @@ -8,12 +8,7 @@ ], "repository": "Cloudstek/alfred-hugo", "bugs": "https://github.com/Cloudstek/alfred-hugo/issues", - "main": "index.js", - "scripts": { - "test": "ava", - "build": "gulp", - "watch": "gulp watch" - }, + "main": "dist/main.js", "keywords": [ "alfred", "workflow", @@ -26,54 +21,61 @@ ], "license": "BSD-2-Clause", "devDependencies": { - "ava": "^0.18.2", - "babel-eslint": "^7.1.1", - "babel-plugin-transform-class-properties": "^6.23.0", - "babel-plugin-transform-runtime": "^6.23.0", - "babel-preset-env": "^1.6.0", - "babel-preset-flow": "^6.23.0", - "delay": "^1.3.1", - "eslint": "^3.18.0", - "eslint-config-xo": "^0.17.0", - "eslint-formatter-pretty": "^1.1.0", - "eslint-plugin-ava": "^4.2.0", - "eslint-plugin-flowtype-errors": "^3.3.1", - "flow-bin": "^0.40.0", - "gulp": "^3.9.1", - "gulp-babel": "^6.1.2", - "gulp-eslint": "^3.0.1", - "gulp-rename": "^1.2.2", - "gulp-sourcemaps": "^2.6.0", - "hook-std": "^0.3.0", - "nock": "^9.0.14", - "tempy": "^0.1.0" + "@types/fs-extra": "^7.0.0", + "@types/got": "^9.4.4", + "@types/mockdate": "^2.0.0", + "@types/nock": "^10.0.3", + "@types/node": "^12.0.2", + "@types/node-notifier": "^5.4.0", + "@types/read-pkg": "^4.0.0", + "@types/semver": "^6.0.0", + "@types/sinon": "^7.0.12", + "ava": "^2.0.0", + "del-cli": "^2.0.0", + "delay": "^4.2.0", + "mockdate": "^2.0.2", + "nock": "^10.0.6", + "npm-run-all": "^4.1.5", + "nyc": "^14.1.1", + "sinon": "^7.3.2", + "tempy": "^0.3.0", + "tslint": "^5.16.0", + "typescript": "^3.4.5" }, "dependencies": { - "alfred-link": "^0.2.0", - "babel-runtime": "^6.23.0", - "cache-conf": "^0.5.0", - "conf": "^0.12.0", - "fs-extra": "^4.0.0", - "fuse.js": "^2.6.2", - "got": "^6.7.1", - "latest-version": "^3.0.0", + "@cloudstek/cache": "^1.0.1", + "alfred-link": "^0.3.0", + "axios": "^0.19.0", + "fs-extra": "^8.0.1", + "fuse.js": "^3.4.4", "moment": "^2.17.1", "node-notifier": "^5.0.2", - "read-pkg": "^2.0.0", - "semver": "^5.4.1" + "read-pkg": "^5.1.1", + "semver": "^6.1.0" }, "engines": { - "node": ">=4" + "node": ">=8" + }, + "scripts": { + "clean": "npm-run-all -p clean:*", + "clean:dist": "del-cli dist", + "clean:test": "del-cli build", + "clean:coverage": "del-cli coverage .nyc_output", + "build": "tsc", + "build:dist": "npm-run-all -s clean && tsc -p tsconfig.dist.json", + "test": "npm-run-all clean:test clean:coverage build test:run clean:test", + "test:run": "nyc ava", + "test:ci": "npm-run-all -p clean:* -s build:test && nyc -s ava && nyc report --reporter=text-lcov | coveralls", + "lint": "npm-run-all -l -p lint:*", + "lint:src": "tslint src/**/*.ts", + "lint:test": "tslint test/**/*.ts" }, "ava": { - "babel": "inherit", - "concurrency": 5, - "failFast": false, "files": [ - "tests/*.js" + "build/test/**/*" ], - "source": [ - "*.js" + "helpers": [ + "build/test/helpers/**/*" ] } } diff --git a/src/file-cache.ts b/src/file-cache.ts new file mode 100644 index 0000000..b393372 --- /dev/null +++ b/src/file-cache.ts @@ -0,0 +1,61 @@ +import { Cache } from "@cloudstek/cache"; +import { ICacheOptions } from "@cloudstek/cache"; +import Crypto from "crypto"; +import { EventEmitter } from "events"; +import fs from "fs-extra"; + +import * as utils from "./utils"; + +/** + * File cache. + * + * This allows you to read and process the data once, then storing it in cache until the file has changed again. + */ +export class FileCache extends EventEmitter { + private filePath: string; + private cache: Cache; + + /** + * FileCache constructor + * + * @param filePath File to process and check for changes + * @param options Cache options + * + * @constructor + */ + constructor(filePath: string, options: ICacheOptions) { + super(); + + this.filePath = filePath; + + // Initialize cache store for this file + options.name = Crypto.createHash("sha1").update(filePath).digest("hex") + ".json"; + this.cache = new Cache(options); + } + + /** + * Get (cached) contents. + */ + public get() { + if (utils.fileExists(this.filePath) === false) { + return null; + } + + // Read file + const file = fs.readFileSync(this.filePath, "utf8"); + + // Calculate file hash + const hash = Crypto.createHash("sha1").update(file, "utf8").digest("hex"); + + if (this.cache.has("hash") === false || this.cache.get("hash") !== hash) { + this.emit("change", this.cache, file, hash); + + this.cache.set("hash", hash); + this.cache.commit(); + + return this.cache.all(); + } + + return this.cache.all(); + } +} diff --git a/src/hugo.ts b/src/hugo.ts new file mode 100644 index 0000000..12e5676 --- /dev/null +++ b/src/hugo.ts @@ -0,0 +1,440 @@ +import { Cache } from "@cloudstek/cache"; +import { ICacheOptions } from "@cloudstek/cache"; +import fs from "fs-extra"; +import Fuse from "fuse.js"; +import Axios, { AxiosRequestConfig } from "axios"; +import moment from "moment"; +import path from "path"; +import Semver from "semver"; +import NotificationCenter from "node-notifier/notifiers/notificationcenter"; + +import { FileCache } from "./file-cache"; +import { AlfredMeta, FilterResults, HugoOptions, WorkflowMeta, UpdateSource, Item } from "./types"; +import { Updater } from "./updater"; +import * as utils from "./utils"; + +export class Hugo { + public cache: Cache; + public config: Cache; + public rerun: number; + public variables: { [key: string]: any } = {}; + public items: Item[] = []; + + private fuseDefaults: Fuse.FuseOptions; + private options: HugoOptions; + private updater: Updater; + private notifier: NotificationCenter; + + public constructor(options?: HugoOptions) { + // Save options + this.options = { + checkUpdates: true, + updateInterval: moment.duration(1, "days"), + updateItem: true, + updateNotification: true, + updateSource: UpdateSource.NPM, + }; + + this.configure(options || {}); + + // Set defaults for FuseJS + this.fuseDefaults = { + keys: ["title"], + threshold: 0.4, + }; + + // Configure config store + this.config = new Cache({ + dir: this.workflowMeta.data, + name: "config.json", + ttl: false, + }); + + // Configure cache store + this.cache = new Cache({ + dir: this.workflowMeta.cache, + }); + + // Initialize updater + this.updater = new Updater(this.cache, this.options.updateInterval); + + // Notofier + this.notifier = new NotificationCenter(); + } + + /** + * Set Hugo options + * + * @param options Options to set + */ + public configure(options: HugoOptions): Hugo { + // Update options + options = Object.assign({}, this.options, options); + + // Convert updateInterval to moment.Duration object + if (options.updateInterval) { + if (!moment.isDuration(options.updateInterval)) { + options.updateInterval = moment.duration(options.updateInterval, "seconds"); + } + + if (options.updateInterval.asSeconds() < 1) { + options.checkUpdates = false; + delete options.updateInterval; + } + } + + if (typeof options.updateSource === "string") { + if (!UpdateSource[options.updateSource as any]) { + throw new Error("Invalid update source."); + } + } + + this.options = options; + + return this; + } + + /** + * Alfred metadata + * + * @return + */ + public get alfredMeta(): AlfredMeta { + let version = Semver.valid(Semver.coerce(process.env.alfred_version)); + + // Check if version is valid + if (version === null) { + if (process.env.alfred_debug === "1") { + console.error(`Invalid Alfred version: ${process.env.alfred_version}`); + } + + version = undefined; + } + + // Gather environment information + const data: AlfredMeta = { + debug: process.env.alfred_debug === "1", + preferences: process.env.alfred_preferences, + preferencesLocalHash: process.env.alfred_preferences_localhash, + theme: process.env.alfred_theme, + themeBackground: process.env.alfred_theme_background, + themeSelectionBackground: process.env.alfred_theme_selection_background, + themeSubtext: parseFloat(process.env.alfred_theme_subtext || "0"), + version, + }; + + // Find and load curent Alfred theme file + if (process.env.HOME && data.theme) { + const homedir: string = process.env.HOME; + + const themeFile = path.resolve(homedir, "Library", "Application Support", "Alfred " + Semver.major(version), + "Alfred.alfredpreferences", "themes", data.theme, "theme.json"); + + try { + fs.statSync(themeFile); + data.themeFile = themeFile; + } catch (e) { + if (process.env.alfred_debug === "1") { + console.error(`Could not find theme file "${themeFile}"`); + } + } + } + + return data; + } + + /** + * Alfred theme + */ + public get alfredTheme(): object { + const themeFile = this.alfredMeta.themeFile; + + if (!themeFile || utils.fileExists(themeFile) === false) { + return {}; + } + + return fs.readJsonSync(themeFile); + } + + /** + * Workflow metadata + */ + public get workflowMeta(): WorkflowMeta { + let version = Semver.valid(Semver.coerce(process.env.alfred_workflow_version)); + + // Check if version is valid + if (version === null) { + if (process.env.alfred_debug === "1") { + console.error(`Invalid workflow version: ${process.env.alfred_workflow_version}`); + } + + version = undefined; + } + + return { + bundleId: process.env.alfred_workflow_bundleid, + cache: process.env.alfred_workflow_cache, + data: process.env.alfred_workflow_data, + icon: path.join(process.cwd(), "icon.png"), + name: process.env.alfred_workflow_name, + uid: process.env.alfred_workflow_uid, + version, + }; + } + + /** + * Reset Hugo. + */ + public reset() { + this.rerun = undefined; + this.variables = {}; + this.items = []; + + return this; + } + + /** + * Alfred user input + */ + public get input(): string { + // User input with the action name stripped off + // node index.js myaction "myquery" + if (process.argv.length > 3) { + return process.argv[3]; + } + + // User input when not inside an action + return process.argv[2] || ""; + } + + /** + * Current output buffer + * + * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json + * + * @return Object to be output and interpreted by Alfred + */ + public get output(): FilterResults { + if (this.rerun !== null && (this.rerun < 0.1 || this.rerun > 5.0)) { + throw new Error("Invalid value for rerun, must be between 0.1 and 5.0"); + } + + return { + rerun: this.rerun, + items: this.items, + variables: this.variables, + }; + } + + /** + * Run a callback when first script argument matches keyword. Callback will have third argument as query parameter. + * + * @example node index.js myaction "my query" + * + * @param keyword Action name + * @param callback Callback to execute when query matches action name + */ + public action(keyword: string, callback: (query: string) => void): Hugo { + const action = process.argv[2] || ""; + + if (action === keyword) { + callback(process.argv[3] || ""); + } + + return this; + } + + /** + * Cache processed file. + * + * This allows you to read and process the data once, then storing it in cache until the file has changed again. + * + * @param filepath File path + * @param options Cache options + */ + public cacheFile(filePath: string, options?: ICacheOptions): FileCache { + return new FileCache(filePath, options || { + dir: this.workflowMeta.cache, + }); + } + + /** + * Clear cache + * + * Clear the whole workflow cache directory. + */ + public async clearCache() { + if (this.workflowMeta.cache) { + return fs.emptyDir(this.workflowMeta.cache); + } + } + + /** + * Clear cache + * + * Clear the whole workflow cache directory. + */ + public clearCacheSync(): void { + if (this.workflowMeta.cache) { + fs.emptyDirSync(this.workflowMeta.cache); + } + } + + /** + * Filter list of candidates with fuse.js + * + * @see http://fusejs.io + * + * @param {Array.} candidates Input data + * @param {string} query Search string + * @param {Object} options fuse.js options + */ + public search(candidates: Item[], query: string, options?: Fuse.FuseOptions): Item[] { + options = Object.assign({}, this.fuseDefaults, options || {}); + + if (query.trim().length === 0) { + return candidates; + } + + // Create fuse.js fuzzy search object + const fuse = new Fuse(candidates, options); + + // Return results + return fuse.search(query) || []; + } + + /** + * Send a notification + * + * Notification title defaults to the Workflow name, or when not available to 'Alfred'. + * You can adjust all the options that node-notifier supports. Please see their documentation for available options. + * + * @see https://github.com/mikaelbr/node-notifier + * + * @param notification Notification options + */ + public async notify(notification: NotificationCenter.Notification) { + return new Promise((resolve, reject) => { + const defaults: NotificationCenter.Notification = { + contentImage: this.workflowMeta.icon, + title: ("Alfred " + this.workflowMeta.name).trim(), + }; + + // Set options + notification = Object.assign({}, defaults, notification); + + // Notify + this.notifier.notify(notification, (err, response) => { + if (err) { + reject(err); + return; + } + + resolve(response); + }); + }); + } + + /** + * Check for updates and notify the user + * + * @param pkg Package.json contents. When undefined, will read from file. + */ + public async checkUpdates(pkg?: any) { + // No need to check if we're not showing anything, duh. + if (this.options.checkUpdates !== true || + (this.options.updateItem !== true && this.options.updateNotification !== true)) { + return; + } + + await this.updater.checkUpdates(this.options.updateSource as string, pkg) + .then((result) => { + if (!result) { + return; + } + + // Version information + const current = this.workflowMeta.version; + const latest = result.version; + + if (!current) { + return; + } + + // Display notification + if (Semver.gt(latest, current)) { + if (result.checkedOnline === true && this.options.updateNotification === true) { + this.notify({ + message: `Workflow version ${latest} available. Current version: ${current}.`, + }); + } + if (this.options.updateItem === true) { + this.items.push({ + title: `Workflow update available!`, + subtitle: `Version ${latest} is available. Current version: ${current}.`, + icon: { + path: this.workflowMeta.icon || "", + }, + arg: result.url, + variables: { + task: "wfUpdate", + }, + }); + } + } + }) + .catch((err) => { + if (process.env.alfred_debug === "1") { + console.error(err.message); + } + return; + }); + } + + /** + * Fetch url and parse JSON. Useful for REST APIs. + * + * @see https://www.npmjs.com/package/got + * + * @param url Url to request + * @param options http.request options + * @param ttl Cache lifetime (in seconds). Undefined to disable or false to enable indefinite caching. + */ + public async fetch(url: string, options?: AxiosRequestConfig, ttl?: number | false) { + // Check cache for a hit + if (ttl && ttl > 0) { + if (this.cache.has(url)) { + return this.cache.get(url); + } + } + + // Do request + return Axios.get(url, options) + .then((response) => { + if (ttl && ttl > 0) { + this.cache.set(url, response.data, ttl); + } + + return response.data; + }); + } + + /** + * Flush the output buffer so Alfred shows our items + * @async + */ + public async feedback() { + // Check for updates + if (this.options.checkUpdates === true) { + await this.checkUpdates(); + } + + const output = this.output; + + // Output JSON + console.log(JSON.stringify(output, null, "\t")); + + // Reset everything + this.reset(); + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..f382c75 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,3 @@ +export * from "./types"; +export { Hugo } from "./hugo"; +export { Updater } from "./updater"; diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..5d59b60 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,100 @@ +import { Duration } from "moment"; + +export enum IconType { + fileIcon = "fileicon", + fileType = "filetype", +} + +export enum ItemType { + default = "default", + file = "file", + fileSkipCheck = "file:skipcheck", +} + +export enum UpdateSource { + NPM = "npm" as any, + Packal = "packal" as any, +} + +export interface HugoOptions { + checkUpdates?: boolean; + updateSource?: UpdateSource | string; + updateInterval?: number | Duration; + updateNotification?: boolean; + updateItem?: boolean; +} + +export interface WorkflowMeta { + name?: string; + version?: string; + uid?: string; + bundleId?: string; + data?: string; + cache?: string; + icon?: string; +} + +export interface AlfredMeta { + version?: string; + theme?: string; + themeFile?: string; + themeBackground?: string; + themeSelectionBackground?: string; + themeSubtext?: number; + preferences?: string; + preferencesLocalHash?: string; + debug: boolean; +} + +export interface FilterResults { + rerun?: number; + variables?: { [key: string]: any }; + items: Item[]; +} + +export interface Item { + uid?: string; + title: string; + subtitle?: string; + arg?: string; + icon?: ItemIcon; + valid?: boolean; + match?: string; + autocomplete?: string; + type?: ItemType; + mods?: ItemModifiers; + text?: ItemText; + quicklookurl?: string; + variables?: { [key: string]: any }; +} + +export interface ItemIcon { + type?: IconType; + path: string; +} + +export interface ItemModifiers { + alt?: ItemModifier; + ctrl?: ItemModifier; + cmd?: ItemModifier; + fn?: ItemModifier; + shift?: ItemModifier; +} + +export interface ItemModifier { + valid: boolean; + subtitle: string; + arg: string; + variables?: { [key: string]: any }; +} + +export interface ItemText { + copy?: string; + largetype?: string; +} + +export interface LatestVersion { + version: string; + url: string; + checkedOnline: boolean; +} diff --git a/src/updater.ts b/src/updater.ts new file mode 100644 index 0000000..5304452 --- /dev/null +++ b/src/updater.ts @@ -0,0 +1,160 @@ +import { Cache } from "@cloudstek/cache"; +import moment from "moment"; +import readPkg from "read-pkg"; +import axios from "axios"; +import semver from "semver"; + +import { LatestVersion, UpdateSource } from "./types"; + +/** + * Hugo updater + */ +export class Updater { + private cache: Cache; + private interval: number | moment.Duration; + + /** + * Hugo updater + */ + constructor(cache: Cache, interval: number | moment.Duration) { + this.cache = cache; + this.interval = interval; + } + + /** + * Check for updates + * + * @param source Update source (npm or packal) + * @param pkg Package.json contents. When undefined, will read from file. + */ + public async checkUpdates(source: string, pkg?: any): Promise { + // Check update source + if (!UpdateSource[source as any]) { + throw new Error("Invalid update source."); + } + + const latest = this.cache.get(`latest_version_${source}`) as LatestVersion | undefined; + const lastCheck = moment.unix(this.cache.get(`last_check_${source}`) as number).utc(); + + // Check for updates online + if (!latest) { + // Check if the interval is past + if (lastCheck.isValid() && lastCheck.add(this.interval).isSameOrAfter(moment.utc())) { + return undefined; + } + + switch (source.toLowerCase()) { + case "npm": + return this.checkNpm(pkg); + case "packal": + return this.checkPackal(); + } + } + + // Got it from cache! + latest.checkedOnline = false; + + return latest; + } + + /** + * Check Packal for updates + */ + private async checkPackal(): Promise { + // Bundle ID + const bundleId = process.env.alfred_workflow_bundleid; + + if (!bundleId) { + throw new Error("No bundle ID, not checking Packal for updates."); + } + + // Set last check time + this.cache.set("last_check_packal", moment.utc().unix(), this.interval); + + // Packal URL + const searchParam: string = encodeURIComponent("site:packal.org " + bundleId); + const pkgUrl: string = `https://encrypted.google.com/search?sourceid=chrome&ie=UTF-8&q=${searchParam}&btnI`; + + const latest = await axios.get(`https://github.com/packal/repository/blob/master/${bundleId}/appcast.xml`) + .then((response) => { + // Get version from XML + const versionMatches = response.data.match(/(.+)<\/version>/); + + if (!versionMatches || versionMatches.length !== 2) { + throw new Error("No version found."); + } + + if (!semver.valid(semver.coerce(versionMatches[1]))) { + throw new Error("Invalid version in response."); + } + + return { + version: versionMatches[1], + url: pkgUrl, + checkedOnline: true, + }; + }) + .catch((err) => { + if (err.response && err.response.status === 404) { + return; + } + + throw err; + }); + + // Cache results + this.cache.set("latest_version_packal", latest, this.interval); + + return latest; + } + + /** + * Check NPM for updates + * + * @param pkg Package.json contents. When undefined, will read from file. + */ + private async checkNpm(pkg?: any): Promise { + // Get details from package.json + pkg = pkg || await readPkg({ cwd: process.cwd() }); + + if (!pkg.name || !pkg.version) { + throw new Error("Invalid package.json."); + } + + // Set last check time + this.cache.set("last_check_npm", moment.utc().unix(), this.interval); + + // NPM URL + const pkgUrl: string = `https://www.npmjs.com/package/${pkg.name}`; + + // Check for updates + const latest = await axios.get(`https://registry.npmjs.org/${pkg.name}`) + .then((response) => { + if (!response.data["dist-tags"].latest) { + throw new Error("No latest version found in response."); + } + + if (!semver.valid(semver.coerce(response.data["dist-tags"].latest))) { + throw new Error("Invalid version in response."); + } + + return { + version: response.data["dist-tags"].latest, + url: pkgUrl, + checkedOnline: true, + }; + }) + .catch((err) => { + if (err.response && err.response.status === 404) { + return; + } + + throw err; + }); + + // Cache results + this.cache.set("latest_version_npm", latest, this.interval); + + return latest; + } +} diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..f19875e --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,15 @@ +import * as fs from "fs-extra"; + +/** + * Check if file exists + * + * @param file + */ +export function fileExists(file: string): boolean { + try { + fs.statSync(file); + return true; + } catch (err) { + return false; + } +} diff --git a/test/actions.ts b/test/actions.ts new file mode 100644 index 0000000..cf27cbb --- /dev/null +++ b/test/actions.ts @@ -0,0 +1,86 @@ +import test from "ava"; +import { hugo } from "./helpers/init"; + +test("actions defined but no matching action", (t) => { + process.argv = [ + "node", + "index.js", + "foo", + ]; + + const h = hugo(); + + h.action("bar", (query) => { + t.log(query); + t.fail(); + }); + + h.action("soap", (query) => { + t.log(query); + t.fail(); + }); + + t.is(h.input, "foo"); +}); + +test("actions defined but no action given", (t) => { + process.argv = [ + "node", + "index.js", + ]; + + const h = hugo(); + + h.action("bar", (query) => { + t.log(query); + t.fail(); + }); + + h.action("soap", (query) => { + t.log(query); + t.fail(); + }); + + t.is(h.input, ""); +}); + +test("actions defined and matching action with no query", (t) => { + process.argv = [ + "node", + "index.js", + "foo", + ]; + + const h = hugo(); + + h.action("bar", (query) => { + t.log(query); + t.fail(); + }); + + h.action("foo", (query) => { + t.is(query, ""); + t.pass(); + }); +}); + +test("actions defined and matching action with query", (t) => { + process.argv = [ + "node", + "index.js", + "foo", + "bar", + ]; + + const h = hugo(); + + h.action("bar", (query) => { + t.log(query); + t.fail(); + }); + + h.action("foo", (query) => { + t.is(query, "bar"); + t.pass(); + }); +}); diff --git a/test/feedback.ts b/test/feedback.ts new file mode 100644 index 0000000..54c163c --- /dev/null +++ b/test/feedback.ts @@ -0,0 +1,70 @@ +import test from "ava"; +import sinon from "sinon"; + +import { hugo } from "./helpers/init"; +import * as mock from "./helpers/mock"; + +const backupConsoleLog = console.log; +const backupConsoleError = console.error; + +test.beforeEach(() => { + mock.date(); +}); + +test.serial("feedback without checking for updates", async (t) => { + const consoleStub = sinon.stub(console, "log"); + + const h = hugo({ + checkUpdates: false, + }); + + h.rerun = 3.2; + h.items.push({ + title: "foo", + }); + h.variables.foo = "bar"; + + await h.feedback(); + + // Check output + t.true(consoleStub.calledOnce); + t.snapshot(consoleStub.getCall(0).args[0]); + + // Check if state has been reset + t.is(h.items.length, 0); + t.deepEqual(h.variables, {}); + t.falsy(h.rerun); +}); + +test.serial("check for updates on feedback", async (t) => { + const consoleStub = sinon.stub(console, "log"); + + const h = hugo({ + updateSource: "packal", + updateNotification: false, + }); + + const request = mock.packal(1); + + // Check feedback + await h.feedback(); + + // Check request + t.true(request.isDone()); + + // Feedback again, should not trigger updates + await h.feedback(); + + t.true(consoleStub.calledTwice); + t.is(consoleStub.getCall(0).args[0], consoleStub.getCall(1).args[0]); + t.snapshot(consoleStub.getCall(0).args[0]); +}); + +test.afterEach.always(() => { + console.log = backupConsoleLog; + console.error = backupConsoleError; +}); + +test.after.always(() => { + mock.cleanAll(); +}); diff --git a/test/fetch.ts b/test/fetch.ts new file mode 100644 index 0000000..5e65813 --- /dev/null +++ b/test/fetch.ts @@ -0,0 +1,71 @@ +import Test, { TestInterface } from "ava"; +import nock from "nock"; + +import { hugo } from "./helpers/init"; +import { TestContext } from "./helpers/types"; +import * as mock from "./helpers/mock"; + +const test = Test as TestInterface; + +test.beforeEach((t) => { + t.context.url = "http://foo.bar"; + + // Mock requests + nock(t.context.url) + .get("/") + .once() + .reply(200, {message: "hello" }); + + nock(t.context.url) + .get("/") + .once() + .reply(200, {message: "world"}); + + mock.date(); +}); + +test.serial("fetch uncached", async (t) => { + const h = hugo(); + + // Fetch with caching implicitely disabled + t.deepEqual(await h.fetch(t.context.url), { message: "hello" }); + t.false(h.cache.has(t.context.url)); + + // Fetch with caching explicitely disabled + t.deepEqual(await h.fetch(t.context.url, null, false), { message: "world" }); + t.false(h.cache.has(t.context.url)); +}); + +test.serial("fetch cached", async (t) => { + const h = hugo(); + + // Fetch cached with empty cache + t.false(h.cache.has(t.context.url)); + t.deepEqual(await h.fetch(t.context.url, null, 300), { message: "hello" }); + t.deepEqual(h.cache.get(t.context.url), { message: "hello" }); + + // Fetch cached with warm cache and assert we have the right output. + // Nock is set to only return 'hello' once. So if the request is not cached, it would return 'world'. + t.deepEqual(await h.fetch(t.context.url, null, 300), { message: "hello" }); + t.deepEqual(h.cache.get(t.context.url), { message: "hello" }); + + // Let the cache expire + mock.forwardTime(1, "hour"); + + // Assert cache is expired + t.false(h.cache.has(t.context.url)); + + // Fetch cached with empty cache one more time and assert that the request is done. + // Nock is set to only return 'hello' once, which we received before. This time it should return 'world' to complete + // our sentence. If not, this would indicate the request is still cached somehow. + t.deepEqual(await h.fetch(t.context.url, null, 300), { message: "world" }); + t.deepEqual(h.cache.get(t.context.url), { message: "world" }); + + // Fetch cached with a warm cache again. + t.deepEqual(await h.fetch(t.context.url, null, 300), { message: "world" }); + t.deepEqual(h.cache.get(t.context.url), { message: "world" }); +}); + +test.afterEach.always(() => { + mock.cleanAll(); +}); diff --git a/tests/file-cache.js b/test/file-cache.js similarity index 100% rename from tests/file-cache.js rename to test/file-cache.js diff --git a/test/file-cache.ts b/test/file-cache.ts new file mode 100644 index 0000000..9b895b1 --- /dev/null +++ b/test/file-cache.ts @@ -0,0 +1,86 @@ +import fs from "fs-extra"; +import path from "path"; +import test from "ava"; + +import { hugo } from "./helpers/init"; +import * as mock from "./helpers/mock"; + +test.serial("process file and cache it", (t) => { + const h = hugo(); + const tmpFile = mock.file(); + + // Create file + fs.writeFileSync(tmpFile, "Hello world!"); + + // Get FileCache instance + const cachedFile = h.cacheFile(tmpFile); + + // Listen to change event to process data + cachedFile.once("change", (cache, file, hash) => { + t.is(cache.constructor.name, "Cache"); + t.is(typeof file, "string"); + t.true(file.length > 0); + t.is(typeof hash, "string"); + t.true(hash.length > 0); + + cache.set("hello", "world!"); + }); + + // Fetch data + let data = cachedFile.get(); + + // Verify data + t.is(typeof data, "object"); + t.is(data.hello, "world!"); + t.true(data.hash.length > 0); + + // Listen to change event (which should not be emitted now) + cachedFile.once("change", () => { + t.fail("Data has not been cached."); + }); + + // Fetch data again and verify it + t.deepEqual(cachedFile.get(), data); + + cachedFile.removeAllListeners(); + + // Listen to change event to process data + cachedFile.once("change", (cache, file, hash) => { + t.is(cache.constructor.name, "Cache"); + t.is(typeof file, "string"); + t.true(file.length > 0); + t.is(typeof hash, "string"); + t.true(hash.length > 0); + + cache.set("foo", "bar"); + }); + + // Change file to trigger change on next get + fs.writeFileSync(tmpFile, "Foobar"); + + // Fetch data + data = cachedFile.get(); + + // Verify data + t.is(typeof data, "object"); + t.is(data.foo, "bar"); + t.true(data.hash.length > 0); +}); + +test.serial("process non-existing file", (t) => { + const h = hugo(); + + // Get FileCache instance + const cachedFile = h.cacheFile(path.resolve(__dirname, "idontexist.txt")); + + // Listen to change event to process data + cachedFile.on("change", () => { + t.fail("File does not exist and this should not be called."); + }); + + // Fetch data + const data = cachedFile.get(); + + // Verify data + t.falsy(data); +}); diff --git a/test/helpers/init.ts b/test/helpers/init.ts new file mode 100644 index 0000000..6886212 --- /dev/null +++ b/test/helpers/init.ts @@ -0,0 +1,38 @@ +import { Cache } from "@cloudstek/cache"; +import crypto from "crypto"; +import path from "path"; +import moment from "moment"; +import fs from "fs-extra"; + +import { Updater, Hugo, HugoOptions } from "../../src"; + +export function setAlfredEnv() { + process.env.alfred_version = "3.0.0"; + process.env.alfred_workflow_version = "1.0.0"; + process.env.alfred_workflow_bundleid = "my.work.flow"; + process.env.alfred_workflow_data = path.join("build", "cache", crypto.randomBytes(8).toString("hex")); + process.env.alfred_workflow_cache = path.join("build", "cache", crypto.randomBytes(8).toString("hex")); + process.env.alfred_debug = "0"; + + fs.ensureDirSync(process.env.alfred_workflow_data); + fs.ensureDirSync(process.env.alfred_workflow_cache); + + // Set up fake home dir + process.env.HOME = path.join("build", "cache", crypto.randomBytes(8).toString("hex")); +} + +export function hugo(options?: HugoOptions) { + setAlfredEnv(); + + return new Hugo(options); +} + +export function updater(cacheTtl?: number | moment.Duration) { + setAlfredEnv(); + + const cache = new Cache({ + dir: process.env.alfred_workflow_cache, + }); + + return new Updater(cache, cacheTtl || moment.duration(1, "hour")); +} diff --git a/test/helpers/mock.ts b/test/helpers/mock.ts new file mode 100644 index 0000000..9044c8a --- /dev/null +++ b/test/helpers/mock.ts @@ -0,0 +1,102 @@ +import readPkg from "read-pkg"; +import semver from "semver"; +import nock from "nock"; +import path from "path"; +import fs from "fs-extra"; +import crypto from "crypto"; +import mockdate from "mockdate"; +import moment, { DurationInputArg1, DurationInputArg2 } from "moment"; + +export function date() { + mockdate.set(moment.utc("2019-01-01T14:00:00").valueOf()); +} + +export function forwardTime(amount?: DurationInputArg1, unit?: DurationInputArg2) { + mockdate.set(moment.utc().add(amount, unit)); +} + +export function npm(times: number = 1, pkg?: any, code: number = 200, latestVersion?: string) { + pkg = pkg || readPkg.sync(); + + if (latestVersion !== null) { + latestVersion = latestVersion || semver.parse(pkg.version).inc("major").toString(); + } + + // Build versions response + const versions: { [key: string]: any } = { + "1.0.0": { + name: pkg.name, + version: "1.0.0", + }, + }; + + versions[pkg.version] = { + name: pkg.name, + version: pkg.version, + }; + + versions[latestVersion] = { + name: pkg.name, + version: latestVersion, + }; + + const distTags: { [key: string]: any } = {}; + + if (latestVersion !== null) { + distTags.latest = latestVersion; + } + + // Response body + let body = ""; + + if (code >= 200 && code <= 299) { + body = JSON.stringify({ + "name": pkg.name, + "dist-tags": distTags, + versions, + }); + } + + // Mock requests + return nock("https://registry.npmjs.org") + .get("/" + pkg.name) + .times(times) + .reply(code, body); +} + +export function packal(times: number = 1, code: number = 200, filename: string = "appcast.xml") { + filename = path.join("test", "mocks", filename); + + // Response body + let body = ""; + + if (code >= 200 && code <= 299) { + body = fs.readFileSync(filename, { encoding: "utf8" }); + } + + return nock("https://github.com") + .get("/packal/repository/blob/master/my.work.flow/appcast.xml") + .times(times) + .reply(code, body); +} + +export function file() { + const filePath = path.join("build", "cache", crypto.randomBytes(8).toString("hex")); + + fs.ensureFileSync(filePath); + + return filePath; +} + +export function cleanDate() { + mockdate.reset(); +} + +export function cleanNock() { + nock.cleanAll(); +} + +export function cleanAll() { + cleanDate(); + cleanNock(); +} diff --git a/test/helpers/types.ts b/test/helpers/types.ts new file mode 100644 index 0000000..44c81c9 --- /dev/null +++ b/test/helpers/types.ts @@ -0,0 +1,7 @@ +import { Hugo, Item } from "../../src"; + +export interface TestContext { + hugo?: Hugo; + url?: string; + items?: Item[]; +} diff --git a/test/hugo.ts b/test/hugo.ts new file mode 100644 index 0000000..95f9066 --- /dev/null +++ b/test/hugo.ts @@ -0,0 +1,218 @@ +import test from "ava"; +import moment from "moment"; +import fs from "fs-extra"; +import path from "path"; + +import * as utils from "../src/utils"; + +import { hugo } from "./helpers/init"; + +import { UpdateSource, Hugo } from "../src"; + +test("initialize with options through constructor", (t) => { + const hugoDefaults = (new Hugo() as any).options; + + const h = hugo({ + checkUpdates: false, + updateInterval: moment.duration(2, "hours"), + updateItem: false, + updateNotification: false, + updateSource: UpdateSource.Packal, + }); + + t.notDeepEqual((h as any).options, hugoDefaults); + t.deepEqual((h as any).options, { + checkUpdates: false, + updateInterval: moment.duration(2, "hours"), + updateItem: false, + updateNotification: false, + updateSource: UpdateSource.Packal, + }); +}); + +test("initialize with update interval as number", (t) => { + const hugoDefaults = (new Hugo() as any).options; + + const h = hugo({ + updateInterval: 4010, + }); + + t.deepEqual((h as any).options, Object.assign({}, hugoDefaults, { + updateInterval: moment.duration(4010, "seconds"), + })); +}); + +test("initialize with invalid update interval as number", (t) => { + const h = hugo({ + updateInterval: -100, + }); + + t.falsy((h as any).options.updateInterval); + t.false((h as any).options.checkUpdates); +}); + +test("initialize with update interval as duration", (t) => { + const hugoDefaults = (new Hugo() as any).options; + + const h = hugo({ + updateInterval: moment.duration(3, "hours"), + }); + + t.deepEqual((h as any).options, Object.assign({}, hugoDefaults, { + updateInterval: moment.duration(3, "hours"), + })); +}); + +test("initialize with invalid update interval as duration", (t) => { + const h = hugo({ + updateInterval: moment.duration(-10, "seconds"), + }); + + t.falsy((h as any).options.updateInterval); + t.false((h as any).options.checkUpdates); +}); + +test("test reset", (t) => { + const h = hugo(); + + // Add item + h.items.push({ + title: "foo", + }); + + // Add variable + h.variables.foo = "bar"; + + // Set rerun + h.rerun = 3.1; + + t.is(h.items.length, 1); + t.is(h.variables.foo, "bar"); + t.is(h.rerun, 3.1); + + h.reset(); + + t.is(h.items.length, 0); + t.deepEqual(h.variables, {}); + t.falsy(h.rerun); +}); + +test("input without action", (t) => { + process.argv = [ + "node", + "index.js", + "foobar", + ]; + + const h = hugo(); + + t.is(h.input, "foobar"); +}); + +test("input with action", (t) => { + process.argv = [ + "node", + "index.js", + "myaction", + "foobar", + ]; + + const h = hugo(); + + t.is(h.input, "foobar"); +}); + +test("input with no input", (t) => { + process.argv = [ + "node", + "index.js", + ]; + + const h = hugo(); + + t.is(h.input, ""); +}); + +test("notify", async (t) => { + const h = hugo(); + + await t.notThrowsAsync(async () => { + return h.notify({ + title: "Foo", + message: "Bar", + timeout: 1, + }); + }); +}); + +test("notify with missing options", async (t) => { + const h = hugo(); + + await t.throwsAsync(async () => { + return h.notify({ + title: "Foo", + }); + }); +}); + +test("clear cache dir", async (t) => { + const h = hugo(); + + fs.writeJsonSync(path.join(h.workflowMeta.cache, "foo.json"), { + foo: "bar", + }); + + fs.writeFileSync(path.join(h.workflowMeta.cache, "bar"), "foo"); + + t.true(utils.fileExists(path.join(h.workflowMeta.cache, "foo.json"))); + t.true(utils.fileExists(path.join(h.workflowMeta.cache, "bar"))); + + await h.clearCache(); + + t.false(utils.fileExists(path.join(h.workflowMeta.cache, "foo.json"))); + t.false(utils.fileExists(path.join(h.workflowMeta.cache, "bar"))); + t.true(utils.fileExists(h.workflowMeta.cache)); +}); + +test("clear cache dir sync", (t) => { + const h = hugo(); + + fs.writeJsonSync(path.join(h.workflowMeta.cache, "foo.json"), { + foo: "bar", + }); + + fs.writeFileSync(path.join(h.workflowMeta.cache, "bar"), "foo"); + + t.true(utils.fileExists(path.join(h.workflowMeta.cache, "foo.json"))); + t.true(utils.fileExists(path.join(h.workflowMeta.cache, "bar"))); + + h.clearCacheSync(); + + t.false(utils.fileExists(path.join(h.workflowMeta.cache, "foo.json"))); + t.false(utils.fileExists(path.join(h.workflowMeta.cache, "bar"))); + t.true(utils.fileExists(h.workflowMeta.cache)); +}); + +test.serial("clear cache dir without cache dir set", async (t) => { + const h = hugo(); + + delete process.env.alfred_workflow_cache; + + t.falsy(h.workflowMeta.cache); + + await t.notThrowsAsync(async () => { + return h.clearCache(); + }); +}); + +test.serial("clear cache dir sync without cache dir set", async (t) => { + const h = hugo(); + + delete process.env.alfred_workflow_cache; + + t.falsy(h.workflowMeta.cache); + + t.notThrows(() => { + h.clearCacheSync(); + }); +}); diff --git a/test/matching.ts b/test/matching.ts new file mode 100644 index 0000000..3f09ef5 --- /dev/null +++ b/test/matching.ts @@ -0,0 +1,77 @@ +import Test, { TestInterface } from "ava"; + +import { hugo } from "./helpers/init"; +import { TestContext } from "./helpers/types"; + +const test = Test as TestInterface; + +test.beforeEach((t) => { + t.context.items = [ + { + title: "Foo", + subtitle: "foo bar", + }, + { + title: "Bar", + subtitle: "foo bar bleep", + }, + { + title: "Eep", + subtitle: "eep foo blep", + }, + { + title: "Foo bar", + subtitle: "ploop", + }, + { + title: "Abra", + subtitle: "cadabra", + }, + ]; +}); + +test("exact match", (t) => { + const h = hugo(); + + const matches = h.search(t.context.items, "foo bar bleep", { + keys: ["subtitle"], + threshold: 0, + }); + + t.true(Array.isArray(matches)); + t.is(matches.length, 1); + t.deepEqual(matches[0], t.context.items[1]); +}); + +test("exact match multiple keys", (t) => { + const h = hugo(); + + const matches = h.search(t.context.items, "foo", { + keys: ["title", "subtitle"], + }); + + t.true(Array.isArray(matches)); + t.is(matches.length, 4); + t.snapshot(matches); +}); + +test("no matches", (t) => { + const h = hugo(); + + const matches = h.search(t.context.items, "nope", { + threshold: 0, + }); + + t.true(Array.isArray(matches)); + t.is(matches.length, 0); +}); + +test("no query should return all items", (t) => { + const h = hugo(); + + const matches = h.search(t.context.items, ""); + + t.true(Array.isArray(matches)); + t.is(matches.length, 5); + t.snapshot(matches); +}); diff --git a/test/meta/alfred.ts b/test/meta/alfred.ts new file mode 100644 index 0000000..d7af0e9 --- /dev/null +++ b/test/meta/alfred.ts @@ -0,0 +1,120 @@ +import test from "ava"; +import fs from "fs-extra"; +import path from "path"; +import sinon from "sinon"; + +import { hugo } from "../helpers/init"; + +const backupConsoleError = console.error; + +test.serial("valid version", (t) => { + const h = hugo(); + + process.env.alfred_version = "3.0.0"; + + // Check version number + t.is(typeof h.alfredMeta, "object"); + t.is(h.alfredMeta.version, "3.0.0"); +}); + +test.serial("single digit version", (t) => { + const h = hugo(); + + process.env.alfred_version = "3"; + + // Check version number + t.is(typeof h.alfredMeta, "object"); + t.is(h.alfredMeta.version, "3.0.0"); +}); + +test.serial("two digit version", (t) => { + const h = hugo(); + + process.env.alfred_version = "3.0"; + + // Check version number + t.is(typeof h.alfredMeta, "object"); + t.is(h.alfredMeta.version, "3.0.0"); +}); + +test.serial("no version", (t) => { + const consoleStub = sinon.stub(console, "error"); + const h = hugo(); + + process.env.alfred_debug = "0"; + delete process.env.alfred_version; + + // Check version number + t.is(typeof h.alfredMeta, "object"); + t.falsy(h.alfredMeta.version); + t.false(consoleStub.called); + + // Check if debug message is output + process.env.alfred_debug = "1"; + + t.is(typeof h.alfredMeta, "object"); + t.falsy(h.alfredMeta.version); + t.true(consoleStub.calledWith("Invalid Alfred version: undefined")); +}); + +test.serial("invalid version", (t) => { + const consoleStub = sinon.stub(console, "error"); + const h = hugo(); + + process.env.alfred_debug = "0"; + process.env.alfred_version = "foobar"; + + // Check version number + t.is(typeof h.alfredMeta, "object"); + t.falsy(h.alfredMeta.version); + t.false(consoleStub.called); + + // Check if debug message is output + process.env.alfred_debug = "1"; + + t.is(typeof h.alfredMeta, "object"); + t.falsy(h.alfredMeta.version); + t.true(consoleStub.calledWith("Invalid Alfred version: foobar")); +}); + +test.serial("existing theme", (t) => { + const h = hugo(); + + process.env.alfred_theme = "default"; + + const themeFilePath = path.resolve(process.env.HOME, "Library", "Application Support", "Alfred 3", + "Alfred.alfredpreferences", "themes", process.env.alfred_theme, "theme.json"); + + fs.ensureFileSync(themeFilePath); + fs.writeJsonSync(themeFilePath, { + foo: "bar", + }); + + t.is(typeof h.alfredMeta, "object"); + t.is(h.alfredMeta.themeFile, themeFilePath); +}); + +test.serial("non-existing theme", (t) => { + const consoleStub = sinon.stub(console, "error"); + const h = hugo(); + + // Valid theme name but directory doesn't exist. + process.env.alfred_debug = "0"; + process.env.alfred_theme = "default"; + + t.is(typeof h.alfredMeta, "object"); + t.falsy(h.alfredMeta.themeFile); + t.false(consoleStub.called); + + // Check if debug message is output + process.env.alfred_debug = "1"; + + t.is(typeof h.alfredMeta, "object"); + t.falsy(h.alfredMeta.themeFile); + t.true(consoleStub.called); + t.regex(consoleStub.getCall(0).args[0], /^Could not find theme file /); +}); + +test.afterEach.always(() => { + console.error = backupConsoleError; +}); diff --git a/test/meta/theme.ts b/test/meta/theme.ts new file mode 100644 index 0000000..4032214 --- /dev/null +++ b/test/meta/theme.ts @@ -0,0 +1,34 @@ +import test from "ava"; +import fs from "fs-extra"; +import path from "path"; + +import { hugo } from "../helpers/init"; + +test("existing theme", (t) => { + const h = hugo(); + + process.env.alfred_theme = "default"; + + const themeFilePath = path.resolve(process.env.HOME, "Library", "Application Support", "Alfred 3", + "Alfred.alfredpreferences", "themes", process.env.alfred_theme, "theme.json"); + + fs.ensureFileSync(themeFilePath); + fs.writeJsonSync(themeFilePath, { + foo: "bar", + }); + + t.is(typeof h.alfredTheme, "object"); + t.deepEqual(h.alfredTheme, { + foo: "bar", + }); +}); + +test("non-existing theme", (t) => { + const h = hugo(); + + // Valid theme name but directory doesn't exist. + process.env.alfred_theme = "default"; + + t.is(typeof h.alfredTheme, "object"); + t.deepEqual(h.alfredTheme, {}); +}); diff --git a/test/meta/workflow.ts b/test/meta/workflow.ts new file mode 100644 index 0000000..392dfc0 --- /dev/null +++ b/test/meta/workflow.ts @@ -0,0 +1,80 @@ +import test from "ava"; +import sinon from "sinon"; + +import { hugo } from "../helpers/init"; + +const backupConsoleError = console.error; + +test.serial("valid version", (t) => { + const h = hugo(); + + process.env.alfred_workflow_version = "3.0.0"; + + // Check version number + t.is(typeof h.workflowMeta, "object"); + t.is(h.workflowMeta.version, "3.0.0"); +}); + +test.serial("single digit version", (t) => { + const h = hugo(); + + process.env.alfred_workflow_version = "3"; + + // Check version number + t.is(typeof h.workflowMeta, "object"); + t.is(h.workflowMeta.version, "3.0.0"); +}); + +test.serial("two digit version", (t) => { + const h = hugo(); + + process.env.alfred_workflow_version = "3.0"; + + // Check version number + t.is(typeof h.workflowMeta, "object"); + t.is(h.workflowMeta.version, "3.0.0"); +}); + +test.serial("no version", (t) => { + const consoleStub = sinon.stub(console, "error"); + const h = hugo(); + + process.env.alfred_debug = "0"; + delete process.env.alfred_workflow_version; + + // Check version number + t.is(typeof h.workflowMeta, "object"); + t.falsy(h.workflowMeta.version); + t.false(consoleStub.called); + + // Check if debug message is output + process.env.alfred_debug = "1"; + + t.is(typeof h.workflowMeta, "object"); + t.falsy(h.workflowMeta.version); + t.true(consoleStub.calledWith("Invalid workflow version: undefined")); +}); + +test.serial("invalid version", (t) => { + const consoleStub = sinon.stub(console, "error"); + const h = hugo(); + + process.env.alfred_debug = "0"; + process.env.alfred_workflow_version = "foobar"; + + // Check version number + t.is(typeof h.workflowMeta, "object"); + t.falsy(h.workflowMeta.version); + t.false(consoleStub.called); + + // Check if debug message is output + process.env.alfred_debug = "1"; + + t.is(typeof h.workflowMeta, "object"); + t.falsy(h.workflowMeta.version); + t.true(consoleStub.calledWith("Invalid workflow version: foobar")); +}); + +test.afterEach.always(() => { + console.error = backupConsoleError; +}); diff --git a/test/mocks/appcast-invalidversion.xml b/test/mocks/appcast-invalidversion.xml new file mode 100644 index 0000000..ed280ef --- /dev/null +++ b/test/mocks/appcast-invalidversion.xml @@ -0,0 +1,9 @@ + + + My Workflow + foobar + my.work.flow + 1486081099 + myworkflow.alfredworkflow + + diff --git a/test/mocks/appcast-noversion.xml b/test/mocks/appcast-noversion.xml new file mode 100644 index 0000000..82a0f19 --- /dev/null +++ b/test/mocks/appcast-noversion.xml @@ -0,0 +1,8 @@ + + + My Workflow + my.work.flow + 1486081099 + myworkflow.alfredworkflow + + diff --git a/tests/mocks/appcast.xml b/test/mocks/appcast.xml similarity index 89% rename from tests/mocks/appcast.xml rename to test/mocks/appcast.xml index 04c4857..c9800e0 100644 --- a/tests/mocks/appcast.xml +++ b/test/mocks/appcast.xml @@ -1,7 +1,7 @@ My Workflow - 2.1.0 + 2.0.0 my.work.flow 1486081099 myworkflow.alfredworkflow diff --git a/test/output.ts b/test/output.ts new file mode 100644 index 0000000..12476b5 --- /dev/null +++ b/test/output.ts @@ -0,0 +1,106 @@ +import test from "ava"; + +import { hugo } from "./helpers/init"; + +test("items only", (t) => { + const h = hugo(); + + h.items.push( + { + title: "foo", + }, + { + title: "bar", + subtitle: "foo", + }, + { + title: "boop", + subtitle: "bleep", + }, + ); + + t.snapshot(h.output); +}); + +test("variables only", (t) => { + const h = hugo(); + + h.variables = { + bleep: "bloop", + boop: { + tap: "top", + }, + }; + + t.snapshot(h.output); +}); + +test("variables and items combined", (t) => { + const h = hugo(); + + h.variables.foo = "bar"; + h.items.push({ + title: "foo", + }); + + t.snapshot(h.output); +}); + +test("items with variables", (t) => { + const h = hugo(); + + h.items.push( + { + title: "Test 1", + variables: { + foo: "bar", + }, + }, + { + title: "Test 2", + arg: "foobar", + variables: { + bar: "foo", + }, + }, + ); + + h.variables = { + bloop: "bleep", + flooble: "flab", + flabby: "flop", + }; + + t.snapshot(h.output); +}); + +test("rerun parameter", (t) => { + const h = hugo(); + + h.rerun = 1.4; + h.variables.foo = "bar"; + h.items.push({ + title: "foo", + }); + + t.snapshot(h.output); +}); + +test("invalid rerun parameter", (t) => { + const h = hugo(); + + h.rerun = 10.5; + h.variables.foo = "bar"; + h.items.push({ + title: "foo", + }); + + try { + const contents = h.output; + + t.falsy(contents); + t.fail(); + } catch (e) { + t.pass(); + } +}); diff --git a/test/snapshots/feedback.ts.md b/test/snapshots/feedback.ts.md new file mode 100644 index 0000000..0e43ac5 --- /dev/null +++ b/test/snapshots/feedback.ts.md @@ -0,0 +1,42 @@ +# Snapshot report for `test/feedback.ts` + +The actual snapshot is saved in `feedback.ts.snap`. + +Generated by [AVA](https://ava.li). + +## check for updates on feedback + +> Snapshot 1 + + `{␊ + "items": [␊ + {␊ + "title": "Workflow update available!",␊ + "subtitle": "Version 2.0.0 is available. Current version: 1.0.0.",␊ + "icon": {␊ + "path": "/Users/maarten/Projects/Alfred/alfred-hugo/icon.png"␊ + },␊ + "arg": "https://encrypted.google.com/search?sourceid=chrome&ie=UTF-8&q=site%3Apackal.org%20my.work.flow&btnI",␊ + "variables": {␊ + "task": "wfUpdate"␊ + }␊ + }␊ + ],␊ + "variables": {}␊ + }` + +## feedback without checking for updates + +> Snapshot 1 + + `{␊ + "rerun": 3.2,␊ + "items": [␊ + {␊ + "title": "foo"␊ + }␊ + ],␊ + "variables": {␊ + "foo": "bar"␊ + }␊ + }` diff --git a/test/snapshots/feedback.ts.snap b/test/snapshots/feedback.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..73dffc84352f7120cd4161063a0fc1b97053a8eb GIT binary patch literal 447 zcmV;w0YLsiRzVElU%yj%LOI@Biwynpu?J2Gz zraN9o2v2uLj(ujx9tBQY5i_(Q^SQ=a6f`z+MnCT=+*-r`)lUR;JCW$SS=y$GxwJ=l zWb~K3^_-Mh>kB?+Ah}4~GA`kg%jGwX-R%s3CCcrMnVP$4AUsjwzDOp9b(K;T8a>jK znkF%&pjbloL0m9jNz#Zqz}kf7$3~b1f*1juCV`2<9*spQ1V$xPDwQ=tSmMJVRjiEz zAp-5m7cr5Hf*)>4k%7;6yY7b|Vpim=-aOjbs1`5lQm3<0X{6Ne(g+I(R?4M#fcrWa pY?3LqRI)dD#_#Y=l2mq$i+-n>Cpb3v*N5r<`2+^RJex)W002oh%zyv@ literal 0 HcmV?d00001 diff --git a/test/snapshots/matching.ts.md b/test/snapshots/matching.ts.md new file mode 100644 index 0000000..11ff301 --- /dev/null +++ b/test/snapshots/matching.ts.md @@ -0,0 +1,55 @@ +# Snapshot report for `test/matching.ts` + +The actual snapshot is saved in `matching.ts.snap`. + +Generated by [AVA](https://ava.li). + +## exact match multiple keys + +> Snapshot 1 + + [ + { + subtitle: 'foo bar', + title: 'Foo', + }, + { + subtitle: 'ploop', + title: 'Foo bar', + }, + { + subtitle: 'foo bar bleep', + title: 'Bar', + }, + { + subtitle: 'eep foo blep', + title: 'Eep', + }, + ] + +## no query should return all items + +> Snapshot 1 + + [ + { + subtitle: 'foo bar', + title: 'Foo', + }, + { + subtitle: 'foo bar bleep', + title: 'Bar', + }, + { + subtitle: 'eep foo blep', + title: 'Eep', + }, + { + subtitle: 'ploop', + title: 'Foo bar', + }, + { + subtitle: 'cadabra', + title: 'Abra', + }, + ] diff --git a/test/snapshots/matching.ts.snap b/test/snapshots/matching.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..70b6e52bb04dd0d585b5de4330cf1043add919a4 GIT binary patch literal 451 zcmV;!0X+UeRzV0zOmPGs-99mEW7iSSIv})_1b`Wt=NZJUMNJ?5k2R9uB2M4Dvc5@Ub z2e*QYga4wIPP!BvJU8~krqFb&fx|uAJURCbIay|m32bNm`#O^P%EewEBUf7Wff&CI z1;(Z;^@G}Ctv;JBFHEt^I=Q<^i7}BWE=56-maxX4O=y=t35}CHMpE2y^mC$?Q&p8w zh*5yi2vP1g0PdErNsKfDtx+>sP8-K&rbt5DYMSPvSs=&IjTaSr z&?g|zP}PeDde9JFTZ2{w4=Qz|VRv{Hj4;7x$L(O@)F|ePmf6}+j%+(>=#Gbzx*#!W z+k?ePdCRu*eZ!Pw>%>6)Y`^3Z$v4{9`|A4tjQS>15-zL9}Ah#z7wAIX3P007aI&>{c; literal 0 HcmV?d00001 diff --git a/test/snapshots/output.ts.md b/test/snapshots/output.ts.md new file mode 100644 index 0000000..c9b4755 --- /dev/null +++ b/test/snapshots/output.ts.md @@ -0,0 +1,102 @@ +# Snapshot report for `test/output.ts` + +The actual snapshot is saved in `output.ts.snap`. + +Generated by [AVA](https://ava.li). + +## items only + +> Snapshot 1 + + { + items: [ + { + title: 'foo', + }, + { + subtitle: 'foo', + title: 'bar', + }, + { + subtitle: 'bleep', + title: 'boop', + }, + ], + rerun: undefined, + variables: {}, + } + +## items with variables + +> Snapshot 1 + + { + items: [ + { + title: 'Test 1', + variables: { + foo: 'bar', + }, + }, + { + arg: 'foobar', + title: 'Test 2', + variables: { + bar: 'foo', + }, + }, + ], + rerun: undefined, + variables: { + bloop: 'bleep', + flabby: 'flop', + flooble: 'flab', + }, + } + +## rerun parameter + +> Snapshot 1 + + { + items: [ + { + title: 'foo', + }, + ], + rerun: 1.4, + variables: { + foo: 'bar', + }, + } + +## variables and items combined + +> Snapshot 1 + + { + items: [ + { + title: 'foo', + }, + ], + rerun: undefined, + variables: { + foo: 'bar', + }, + } + +## variables only + +> Snapshot 1 + + { + items: [], + rerun: undefined, + variables: { + bleep: 'bloop', + boop: { + tap: 'top', + }, + }, + } diff --git a/test/snapshots/output.ts.snap b/test/snapshots/output.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..2069093af79f03b9af6910d1bda699c25c444129 GIT binary patch literal 753 zcmVZYWmZrE(ZUOadZ5o$pc zq(~J+5mXAb;7wGJqToTqAFu>0So}#LkseA*(YF)xH@nHEUJ`iZ&CEA5?|t*$x0eYa zGMU_XZFc0%eCF`v8F}VJW)z6?>!XC+h|=-gvyp9`&+j}6C=0E?XRk9t79LCuUJQb| zcf-VyTfJK~;Is1*A+PTCXWnl)`R7#j>VY3)J63?tE~K{; z;Og*{>hRX^@PYu#h3wGVgyaHn_mJaK=R$fO-3uV(%Bl|w0K1KlduXpksN{nFL`V*; zg9=dD#UO}O*>O8z6h|y(njA(2SRj?wJ&^T|(lx8Gqhx#vBU$$_NjJ@8GwSAkt-7gK zCcxg|wohnFVra}2nn+K9jfxRw&O?bnITX$ZFQ#6c-R)B$9?#BfEm`)P!|g=Po}?df zX{LTJ0-ZxZR*X+_HD#gyf?Vf3slZCEE?PXh8{vIEJ=#z=HG|kEHHl@jxbz+Ew-33} z3IZ4suo>;3NQCMlnR1ecps0K||0!P~4Y9znc; + +test.beforeEach(() => { + mock.date(); +}); + +test.serial("check for updates uncached", async (t) => { + const u = updater(); + + const pkg = readPkg.sync(); + const request = mock.npm(); + + const update = await u.checkUpdates("npm"); + + if (!update) { + t.fail("Update is undefined or false."); + return; + } + + t.is(update.version, semver.parse(pkg.version).inc("major").toString()); + t.is(update.url, `https://www.npmjs.com/package/${pkg.name}`); + t.true(update.checkedOnline); + t.true(request.isDone()); +}); + +test.serial("check for updates uncached with custom package.json", async (t) => { + const u = updater(); + + const pkg = { + name: "alfred-my-workflow", + version: "1.0.0", + }; + const request = mock.npm(1, pkg); + + const update = await u.checkUpdates("npm", pkg); + + if (!update) { + t.fail("Update is undefined or false."); + return; + } + + t.is(update.version, "2.0.0"); + t.is(update.url, `https://www.npmjs.com/package/${pkg.name}`); + t.true(update.checkedOnline); + t.true(request.isDone()); +}); + +test.serial("check for updates cached", async (t) => { + const u = updater(); + + const pkg = readPkg.sync(); + const request = mock.npm(2); + + // Check for updates + let update = await u.checkUpdates("npm"); + + if (!update) { + t.fail("Update is undefined or false."); + return; + } + + t.is(update.version, semver.parse(pkg.version).inc("major").toString()); + t.is(update.url, `https://www.npmjs.com/package/${pkg.name}`); + t.true(update.checkedOnline); + t.is(request.pendingMocks().length, 1); + + // Forward time + mock.forwardTime(30, "minutes"); + + // Check for updates again, should be cached. + update = await u.checkUpdates("npm"); + + if (!update) { + t.fail("Update is undefined or false."); + return; + } + + t.false(update.checkedOnline); + t.is(request.pendingMocks().length, 1); + + // Forward time + mock.forwardTime(30, "minutes"); + + // Check for updates again, should be checked online + update = await u.checkUpdates("npm"); + + if (!update) { + t.fail("Update is undefined or false."); + return; + } + + t.true(update.checkedOnline); + t.true(request.isDone()); +}); + +test.serial("check for updates cached with custom package.json", async (t) => { + const u = updater(); + + const pkg = { + name: "alfred-my-workflow", + version: "1.0.0", + }; + const request = mock.npm(2, pkg); + + // Check for updates + let update = await u.checkUpdates("npm", pkg); + + if (!update) { + t.fail("Update is undefined or false."); + return; + } + + t.is(update.version, "2.0.0"); + t.is(update.url, `https://www.npmjs.com/package/${pkg.name}`); + t.true(update.checkedOnline); + t.is(request.pendingMocks().length, 1); + + // Forward time + mock.forwardTime(30, "minutes"); + + // Check for updates again, should be cached. + update = await u.checkUpdates("npm", pkg); + + if (!update) { + t.fail("Update is undefined or false."); + return; + } + + t.false(update.checkedOnline); + t.is(request.pendingMocks().length, 1); + + // Forward time + mock.forwardTime(30, "minutes"); + + // Check for updates again, should be checked online + update = await u.checkUpdates("npm", pkg); + + if (!update) { + t.fail("Update is undefined or false."); + return; + } + + t.true(update.checkedOnline); + t.true(request.isDone()); +}); + +test("check for updates with no package name set", async (t) => { + const u = updater(); + + await t.throwsAsync(async () => { + return u.checkUpdates("npm", { + version: "1.0.0", + }); + }, "Invalid package.json."); +}); + +test("check for updates with no package version set", async (t) => { + const u = updater(); + + await t.throwsAsync(async () => { + return u.checkUpdates("npm", { + name: "alfred-my-workflow", + }); + }, "Invalid package.json."); +}); + +test.serial("check for updates with unpublished package", async (t) => { + const u = updater(); + + const pkg = readPkg.sync(); + + // Mock request + const request = mock.npm(1, pkg, 404); + + const update = await u.checkUpdates("npm"); + + t.is(typeof update, "undefined"); + t.true(request.isDone()); +}); + +test.serial("check for updates with unpublished package from custom package.json", async (t) => { + const u = updater(); + + const pkg = { + name: "alfred-my-workflow", + version: "1.0.0", + }; + + // Mock request + const request = mock.npm(1, pkg, 404); + + const update = await u.checkUpdates("npm", pkg); + + t.is(typeof update, "undefined"); + t.true(request.isDone()); +}); + +test.serial("check for updates with package without latest dist-tag", async (t) => { + const u = updater(); + + const pkg = readPkg.sync(); + + // Mock request + const request = nock("https://registry.npmjs.org") + .get("/" + pkg.name) + .once() + .reply(200, JSON.stringify({ + "name": pkg.name, + "dist-tags": {}, + "versions": { + "1.0.0": { + name: pkg.name, + version: "1.0.0", + }, + "2.0.0": { + name: pkg.name, + version: "2.0.0", + }, + }, + })); + + await t.throwsAsync(async () => { + return u.checkUpdates("npm"); + }, "No latest version found in response."); + + t.true(request.isDone()); +}); + +test.serial("check for updates with package without latest dist-tag from custom package.json", async (t) => { + const u = updater(); + + const pkg = { + name: "alfred-my-workflow", + version: "1.0.0", + }; + + // Mock request + const request = mock.npm(1, pkg, 200, null); + + await t.throwsAsync(async () => { + return u.checkUpdates("npm", pkg); + }, "No latest version found in response."); + + t.true(request.isDone()); +}); + +test.serial("check for updates when invalid version is returned", async (t) => { + const u = updater(); + + const pkg = readPkg.sync(); + + // Mock request + const request = mock.npm(1, pkg, 200, "foobar"); + + await t.throwsAsync(async () => { + return u.checkUpdates("npm"); + }, "Invalid version in response."); + + t.true(request.isDone()); +}); + +test.afterEach.always(() => { + mock.cleanAll(); +}); diff --git a/test/updates/packal.ts b/test/updates/packal.ts new file mode 100644 index 0000000..cb6e024 --- /dev/null +++ b/test/updates/packal.ts @@ -0,0 +1,129 @@ +import test from "ava"; + +import { updater, hugo } from "../helpers/init"; +import * as mock from "../helpers/mock"; + +test.beforeEach(() => { + mock.date(); +}); + +test("check for updates uncached", async (t) => { + const u = updater(); + + const request = mock.packal(); + + const update = await u.checkUpdates("packal"); + + if (!update) { + t.fail("Update is undefined or false."); + return; + } + + t.is(update.version, "2.0.0"); + t.regex(update.url, /^https:\/\/encrypted\.google\.com\//); + t.regex(update.url, /my\.work\.flow/); + t.true(update.checkedOnline); + t.true(request.isDone()); +}); + +test("check for updates cached", async (t) => { + const u = updater(); + + const request = mock.packal(2); + + let update = await u.checkUpdates("packal"); + + if (!update) { + t.fail("Update is undefined or false."); + return; + } + + t.is(update.version, "2.0.0"); + t.regex(update.url, /^https:\/\/encrypted\.google\.com\//); + t.regex(update.url, /my\.work\.flow/); + t.true(update.checkedOnline); + t.is(request.pendingMocks().length, 1); + + // Forward time + mock.forwardTime(30, "minutes"); + + // Check for updates again, should be cached. + update = await u.checkUpdates("packal"); + + if (!update) { + t.fail("Update is undefined or false."); + return; + } + + t.false(update.checkedOnline); + t.is(request.pendingMocks().length, 1); + + // Forward time + mock.forwardTime(30, "minutes"); + + // Check for updates again, should be checked online + update = await u.checkUpdates("packal"); + + if (!update) { + t.fail("Update is undefined or false."); + return; + } + + t.true(update.checkedOnline); + t.true(request.isDone()); +}); + +test.serial("check for updates with no bundle id set", async (t) => { + const u = updater(); + + await t.throwsAsync(async () => { + process.env.alfred_workflow_bundleid = undefined; + delete process.env.alfred_workflow_bundleid; + + return u.checkUpdates("packal"); + }, "No bundle ID, not checking Packal for updates."); +}); + +test.serial("check for updates when no version is returned", async (t) => { + const u = updater(); + + const request = mock.packal(1, 200, "appcast-noversion.xml"); + + await t.throwsAsync(async () => { + return u.checkUpdates("packal"); + }, "No version found."); + + t.true(request.isDone()); +}); + +test.serial("check for updates when invalid version is returned", async (t) => { + const u = updater(); + + const request = mock.packal(1, 200, "appcast-invalidversion.xml"); + + await t.throwsAsync(async () => { + return u.checkUpdates("packal"); + }, "Invalid version in response."); + + t.true(request.isDone()); +}); + +test.serial("check for updates with unpublished workflow", async (t) => { + const u = updater(); + + // Mock request + const request = mock.packal(1, 404); + + const update = await u.checkUpdates("packal"); + + t.is(typeof update, "undefined"); + t.true(request.isDone()); +}); + +test.afterEach.always(() => { + mock.cleanDate(); +}); + +test.after.always(() => { + mock.cleanAll(); +}); diff --git a/test/updates/snapshots/updater.ts.md b/test/updates/snapshots/updater.ts.md new file mode 100644 index 0000000..1b2b905 --- /dev/null +++ b/test/updates/snapshots/updater.ts.md @@ -0,0 +1,21 @@ +# Snapshot report for `test/updates/updater.ts` + +The actual snapshot is saved in `updater.ts.snap`. + +Generated by [AVA](https://ava.li). + +## check update notification item + +> Snapshot 1 + + { + arg: 'https://encrypted.google.com/search?sourceid=chrome&ie=UTF-8&q=site%3Apackal.org%20my.work.flow&btnI', + icon: { + path: '/Users/maarten/Projects/Alfred/alfred-hugo/icon.png', + }, + subtitle: 'Version 2.0.0 is available. Current version: 1.0.0.', + title: 'Workflow update available!', + variables: { + task: 'wfUpdate', + }, + } diff --git a/test/updates/snapshots/updater.ts.snap b/test/updates/snapshots/updater.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..388ed27150cb7c9616f6ade8d03ae2e52ca7e471 GIT binary patch literal 440 zcmV;p0Z0BpRzVKPnEIs{i|L5=bpKXK?p!)=QI#N4? zu+Wj0k!CLTgzy4}9Wfw^QR(=5O2pD(+-*3%6a!Y_tkF4XRkte_4aGGp*P9V_`ZT~o zdgZO!;1Z97?BiY_MwPA(4-qT^TpOX2SF_v^VM&mwLSdi?AV(L38#9_%`{v)GpZ6%b{x4>v!8zJV}-ZB6c&b5@}#5^ z=dEW`dQCfR%{pypW%FShR*IJS^C6IunT@FSr(=_jGDDF8rBbtyw53SyD$)#klDUMA iL)DKxK@uBr6ng)6)l~JT?v8q$@z7t{uT#Nr0ssJGLCD_# literal 0 HcmV?d00001 diff --git a/test/updates/updater.ts b/test/updates/updater.ts new file mode 100644 index 0000000..11bec0a --- /dev/null +++ b/test/updates/updater.ts @@ -0,0 +1,214 @@ +import test from "ava"; +import sinon from "sinon"; + +import { UpdateSource } from "../../src"; + +import { hugo, updater } from "../helpers/init"; +import * as mock from "../helpers/mock"; + +const backupConsoleError = console.error; + +test.beforeEach(() => { + mock.date(); +}); + +test.serial("check with valid update source NPM", async (t) => { + t.notThrows(() => { + hugo({ + updateSource: "npm", + }); + }); + + t.notThrows(() => { + hugo({ + updateSource: "NPM", + }); + }); + + t.notThrows(() => { + hugo({ + updateSource: UpdateSource.NPM, + }); + }); + + // Mock requests + mock.npm(2); + + await t.notThrowsAsync(async () => { + return updater().checkUpdates("npm"); + }); + + await t.notThrowsAsync(async () => { + return updater().checkUpdates("NPM"); + }); +}); + +test.serial("check with valid update source Packal", async (t) => { + t.notThrows(() => { + hugo({ + updateSource: "packal", + }); + }); + + t.notThrows(() => { + hugo({ + updateSource: "Packal", + }); + }); + + t.notThrows(() => { + hugo({ + updateSource: UpdateSource.Packal, + }); + }); + + mock.packal(2); + + await t.notThrowsAsync(async () => { + return updater().checkUpdates("packal"); + }); + + await t.notThrowsAsync(async () => { + return updater().checkUpdates("Packal"); + }); +}); + +test("check with invalid update source as string", async (t) => { + t.throws(() => { + hugo({ + updateSource: "foobar", + }); + }, "Invalid update source."); + + await t.throwsAsync(async () => { + return updater().checkUpdates("foobar"); + }, "Invalid update source."); +}); + +test("check update notification item", async (t) => { + const h = hugo({ + updateSource: "packal", + }); + + const request = mock.packal(); + + // Check for updates + await h.checkUpdates(); + t.true(request.isDone()); + + // Check output buffer + t.true(Array.isArray(h.output.items)); + t.is(h.output.items.length, 1); + + // Check update item + const item = h.output.items.pop(); + + t.snapshot(item); +}); + +test.serial("check for unpublished workflow twice within interval", async (t) => { + const u = updater(); + + // Mock request + const request = mock.packal(1, 404); + + // Check for update + let update = await u.checkUpdates("packal"); + + t.is(typeof update, "undefined"); + t.true(request.isDone()); + + // Check for update the second time shortly after. No request should be made. + update = await u.checkUpdates("packal"); + + t.is(typeof update, "undefined"); +}); + +test("check for updates with updates disabled", async (t) => { + const h = hugo({ + checkUpdates: false, + }); + + const update = await h.checkUpdates(); + + t.falsy(update); +}); + +test("check for updates with update notification and item disabled", async (t) => { + const h = hugo({ + updateNotification: false, + updateItem: false, + }); + + const update = await h.checkUpdates(); + + t.falsy(update); +}); + +test.serial("check for updates with invalid workflow version", async (t) => { + const h = hugo({ + updateSource: "packal", + }); + + process.env.alfred_workflow_version = "foobar"; + + const request = mock.packal(); + + const update = await h.checkUpdates(); + + t.falsy(update); + t.true(request.isDone()); +}); + +test.serial("check for updates with updates with unpublished package", async (t) => { + const h = hugo({ + updateSource: "packal", + }); + + // Mock request + const request = mock.packal(1, 404); + + const update = await h.checkUpdates(); + + t.falsy(update); + t.true(request.isDone()); +}); + +test.serial("check for updates with updates when exception occurs", async (t) => { + const consoleStub = sinon.stub(console, "error"); + + const h = hugo({ + updateSource: "packal", + }); + + // Mock request + const request = mock.packal(2, 500); + + let update = await h.checkUpdates(); + + t.falsy(update); + t.is(request.pendingMocks().length, 1); + t.false(consoleStub.called); + + // Clear cache + h.cache.clear(); + + // Check if debug message is output + process.env.alfred_debug = "1"; + + update = await h.checkUpdates(); + + t.falsy(update); + t.true(request.isDone()); + t.true(consoleStub.calledWith("Request failed with status code 500")); +}); + +test.afterEach.always(() => { + console.error = backupConsoleError; + + mock.cleanDate(); +}); + +test.after.always(() => { + mock.cleanAll(); +}); diff --git a/tests/__snapshots__/cache.js.snap b/tests/__snapshots__/cache.js.snap deleted file mode 100644 index 39fabf6..0000000 --- a/tests/__snapshots__/cache.js.snap +++ /dev/null @@ -1,7 +0,0 @@ -exports[`cleaning cache dir 1`] = `"{\"foo\":\"bar\"}"`; - -exports[`cleaning cache dir 2`] = `"{"foo":"bar"}"`; - -exports[`standard cache dir 1`] = `"{\"foo\":\"bar\"}"`; - -exports[`tmp cache dir 1`] = `"{\"foo\":\"bar\"}"`; diff --git a/tests/__snapshots__/file-cache.js.snap b/tests/__snapshots__/file-cache.js.snap deleted file mode 100644 index 36b9840..0000000 --- a/tests/__snapshots__/file-cache.js.snap +++ /dev/null @@ -1,15 +0,0 @@ -exports[`clear cache 1`] = `"{\"foo\":\"bar\"}"`; - -exports[`clear cache 2`] = `"{}"`; - -exports[`clear cache 3`] = `"{}"`; - -exports[`process file and cache it 1`] = `"{\"foo\":\"bar\",\"hello\":\"world!\"}"`; - -exports[`process file and cache it 2`] = `"{\"foo\":\"bar\",\"hello\":\"world!\"}"`; - -exports[`process file with no cache dir set 1`] = `"{\"foo\":\"bar\"}"`; - -exports[`process file with no cache dir set 2`] = `"{}"`; - -exports[`process file with no cache dir set 3`] = `"{}"`; diff --git a/tests/__snapshots__/output.js.snap b/tests/__snapshots__/output.js.snap deleted file mode 100644 index 75ca18f..0000000 --- a/tests/__snapshots__/output.js.snap +++ /dev/null @@ -1,15 +0,0 @@ -exports[`invalid items 1`] = `"{"items":[{"title":"foo"}]}"`; - -exports[`invalid rerun parameter 1`] = `"{\"variables\":{\"foo\":\"bar\"},\"items\":[{\"title\":\"foo\"}]}"`; - -exports[`items only 1`] = `"{\"items\":[{\"title\":\"foo\"},{\"title\":\"bar\",\"subtitle\":\"foo\"},{\"title\":\"boop\",\"subtitle\":\"bleep\"}]}"`; - -exports[`items with legacy variables (< 3.4.1) 1`] = `"{\"items\":[{\"title\":\"Test 1\",\"arg\":\"{\\\"alfredworkflow\\\":{\\\"variables\\\":{\\\"foo\\\":\\\"bar\\\"}}}\"},{\"title\":\"Test 2\",\"arg\":\"{\\\"alfredworkflow\\\":{\\\"arg\\\":\\\"foobar\\\",\\\"variables\\\":{\\\"bar\\\":\\\"foo\\\"}}}\"},{\"title\":\"Test 3\",\"arg\":\"{\\\"alfredworkflow\\\":{\\\"variables\\\":{\\\"foo\\\":\\\"bar\\\"}}}\"},{\"title\":\"Test 4\",\"arg\":\"{\\\"alfredworkflow\\\":{\\\"arg\\\":\\\"foobar\\\",\\\"variables\\\":{\\\"bar\\\":\\\"foo\\\"}}}\"},{\"title\":\"Test 5\",\"arg\":\"{\\\"alfredworkflow\\\":{\\\"arg\\\":\\\"foobar\\\",\\\"variables\\\":{\\\"bar\\\":\\\"foo\\\",\\\"foo\\\":\\\"bar\\\"}}}\"}],\"variables\":{\"bloop\":\"bleep\",\"flooble\":\"flab\",\"flabby\":\"flop\"}}"`; - -exports[`items with variables 1`] = `"{\"items\":[{\"title\":\"Test 1\",\"variables\":{\"foo\":\"bar\"}},{\"title\":\"Test 2\",\"arg\":\"foobar\",\"variables\":{\"bar\":\"foo\"}},{\"title\":\"Test 3\",\"variables\":{\"foo\":\"bar\"}},{\"title\":\"Test 4\",\"arg\":\"foobar\",\"variables\":{\"bar\":\"foo\"}},{\"title\":\"Test 5\",\"variables\":{\"foo\":\"bar\",\"bar\":\"foo\"},\"arg\":\"foobar\"}],\"variables\":{\"bloop\":\"bleep\",\"flooble\":\"flab\",\"flabby\":\"flop\"}}"`; - -exports[`rerun parameter 1`] = `"{\"variables\":{\"foo\":\"bar\"},\"items\":[{\"title\":\"foo\"}],\"rerun\":1.4}"`; - -exports[`variables and items combined 1`] = `"{\"variables\":{\"foo\":\"bar\"},\"items\":[{\"title\":\"foo\"}]}"`; - -exports[`variables only 1`] = `"{\"variables\":{\"foo\":\"bar\",\"bleep\":\"bloop\",\"boop\":{\"tap\":\"top\"}}}"`; diff --git a/tests/_init.js b/tests/_init.js deleted file mode 100644 index fc5bdfb..0000000 --- a/tests/_init.js +++ /dev/null @@ -1,26 +0,0 @@ -/* eslint-disable camelcase */ -'use strict'; -const path = require('path'); -const tempy = require('tempy'); - -exports.hugo = () => { - delete require.cache[path.resolve(__dirname, '../index.js')]; - - process.env.alfred_workflow_version = '1.0.0'; - process.env.alfred_workflow_bundleid = 'my.work.flow'; - process.env.alfred_workflow_cache = tempy.directory(); - process.env.alfred_debug = false; - - return require('../index'); -}; - -exports.updater = () => { - delete require.cache[path.resolve(__dirname, '../updater.js')]; - - process.env.alfred_workflow_version = '1.0.0'; - process.env.alfred_workflow_bundleid = 'my.work.flow'; - process.env.alfred_workflow_cache = tempy.directory(); - process.env.alfred_debug = false; - - return require('../updater'); -}; diff --git a/tests/cache.js b/tests/cache.js deleted file mode 100644 index 9f3e80f..0000000 --- a/tests/cache.js +++ /dev/null @@ -1,135 +0,0 @@ -import fs from 'fs-extra'; -import os from 'os'; -import path from 'path'; -import test from 'ava'; - -import {hugo} from './_init'; - -/** - * Clean-up - */ -function cleanUp() { - fs.emptyDirSync(path.resolve(path.join(os.tmpdir(), 'my.work.flow'))); - fs.emptyDirSync(process.env.alfred_workflow_cache); -} - -/** - * Set-up - */ -test.beforeEach('setup', t => { - const h = hugo(); - - const testData = { - foo: 'bar' - }; - - h.options({ - checkUpdates: false, - useTmpCache: false - }); - - t.context.hugo = h; - t.context.testData = testData; - - cleanUp(); -}); - -/** - * Check tmp cache directory - */ -test.serial('tmp cache dir', t => { - const h = t.context.hugo; - - // Set options - h.options({ - useTmpCache: true - }); - - // Check cache path - t.is(path.resolve(path.join(os.tmpdir(), 'my.work.flow')), h.workflowMeta.cache); - - // Set cache data - h.cache.set('test', t.context.testData); - - // Assert cache data we just set - t.snapshot(h.cache.get('test')); -}); - -/** - * Check standard cache directory - */ -test.serial('standard cache dir', t => { - const h = t.context.hugo; - - // Check cache path - t.is(process.env.alfred_workflow_cache, h.workflowMeta.cache); - - // Set cache data - h.cache.set('test', t.context.testData); - - // Assert cache data we just set - t.snapshot(h.cache.get('test')); -}); - -/** - * Check cache instance is reinitialized on cache dir change - */ -test.serial('changing cache dir', t => { - const h = t.context.hugo; - - // Check cache path - t.is(process.env.alfred_workflow_cache, h.workflowMeta.cache); - - // Set cache data - h.cache.set('test', t.context.testData); - - // Change cache option - h.options({ - useTmpCache: true - }); - - // Check cache again - t.is(path.resolve(path.join(os.tmpdir(), 'my.work.flow')), h.workflowMeta.cache); - t.false(h.cache.has('test')); -}); - -/** - * Check cache is properly cleaned - */ -test.serial('cleaning cache dir', async t => { - const h = t.context.hugo; - - // Set cache data - h.cache.set('test', t.context.testData); - t.snapshot(h.cache.get('test')); - - // Clear cache - await h.clearCache(); - - // Check cache - t.falsy(h.cache.get('test')); - - // Change cache option - h.options({ - useTmpCache: false - }); - - // Set cache data - h.cache.set('test', t.context.testData); - - // Assert cache data we just set - t.snapshot(h.cache.get('test')); - - // Clear cache - h.clearCacheSync(); - - // Assert cache is empty - t.falsy(h.cache.get('test')); -}); - -/** - * Tear-down - */ -test.afterEach.always('cleanup', () => { - cleanUp(); -}); diff --git a/tests/fetch.js b/tests/fetch.js deleted file mode 100644 index 216d114..0000000 --- a/tests/fetch.js +++ /dev/null @@ -1,101 +0,0 @@ -import delay from 'delay'; -import fs from 'fs-extra'; -import nock from 'nock'; -import test from 'ava'; - -import {hugo} from './_init'; - -const URL = 'http://foo.bar'; - -/** - * Clean-up - */ -function cleanUp() { - fs.emptyDirSync(process.env.alfred_workflow_cache); -} - -/** - * Set-up - */ -test.before('mock requests with nock', () => { - // Uncached URL - nock(URL).persist().get('/no-cache').reply(200, {foo: 'bar'}); - - // URL which returns 'hello' only once. - nock(URL).get('/cache').once().reply(200, {message: 'hello'}); - - // URL which returns 'world' only once. - nock(URL).get('/cache').once().reply(200, {message: 'world!'}); -}); - -test.beforeEach('setup', t => { - const h = hugo(); - - h.options({ - checkUpdates: false, - useTmpCache: false - }); - - t.context.hugo = h; - - cleanUp(); -}); - -/** - * Fetch uncached - */ -test('fetch uncached', async t => { - const h = t.context.hugo; - - // Fetch with caching implicitely disabled - t.deepEqual(await h.fetch(`${URL}/no-cache`), {foo: 'bar'}); - t.falsy(h.cache.get(`${URL}/no-cache`)); - - // Fetch with caching explicitely disabled - t.deepEqual(await h.fetch(`${URL}/no-cache`, {}, null), {foo: 'bar'}); - t.falsy(h.cache.get(`${URL}/no-cache`)); -}); - -/** - * Fetch cached - */ -test('fetch cached', async t => { - const h = t.context.hugo; - - // Fetch cached with empty cache - t.falsy(h.cache.get(`${URL}/cache`)); - t.deepEqual(await h.fetch(`${URL}/cache`, {}, 2), {message: 'hello'}); - t.deepEqual(h.cache.get(`${URL}/cache`), {message: 'hello'}); - - // Fetch cached with warm cache and assert we have the right output. - // Nock is set to only return 'hello' once. So if the request is not cached, it would return 'world'. - t.deepEqual(await h.fetch(`${URL}/cache`, {}, 2), {message: 'hello'}); - t.deepEqual(h.cache.get(`${URL}/cache`), {message: 'hello'}); - - // Wait until cache is expired - await delay(2500); - - // Assert cache is expired - t.falsy(h.cache.get(`${URL}/cache`)); - - // Fetch cached with empty cache one more time and assert that the request is done. - // Nock is set to only return 'hello' once, which we received before. This time it should return 'world' to complete - // our sentence. If not, this would indicate the request is still cached somehow. - t.deepEqual(await h.fetch(`${URL}/cache`, {}, 2), {message: 'world!'}); - t.deepEqual(h.cache.get(`${URL}/cache`), {message: 'world!'}); - - // Fetch cached with a warm cache again. - t.deepEqual(await h.fetch(`${URL}/cache`, {}, 2), {message: 'world!'}); - t.deepEqual(h.cache.get(`${URL}/cache`), {message: 'world!'}); -}); - -/** - * Tear-down - */ -test.afterEach.always('cleanup', () => { - cleanUp(); -}); - -test.after.always('nock cleanup', () => { - nock.cleanAll(); -}); diff --git a/tests/index.js b/tests/index.js deleted file mode 100644 index 167a6a3..0000000 --- a/tests/index.js +++ /dev/null @@ -1,31 +0,0 @@ -import test from 'ava'; - -import {hugo} from './_init'; - -/** - * Set-up - */ -test.beforeEach('setup', t => { - const h = hugo(); - - h.options({ - checkUpdates: false, - useTmpCache: false - }); - - t.context.hugo = h; -}); - -/** - * Check alfred meta with invalid version number - */ -test('alfred meta with invalid version', t => { - const h = t.context.hugo; - - // Set alfred version - process.env.alfred_version = '3.0'; // eslint-disable-line camelcase - - // Check version number - t.is(typeof h.alfredMeta, 'object'); - t.is(h.alfredMeta.version, '3.0.0'); -}); diff --git a/tests/matching.js b/tests/matching.js deleted file mode 100644 index 8cb1458..0000000 --- a/tests/matching.js +++ /dev/null @@ -1,145 +0,0 @@ -import test from 'ava'; - -import {hugo} from './_init'; - -/** - * Set-up - */ -test.beforeEach('setup', t => { - const h = hugo(); - const items = [ - { - title: 'Michael Blob', - email: 'bla@test.com' - }, - { - title: 'Harry Test', - email: 'bla@test.net' - }, - { - title: 'Pinguin Test', - email: 'bla@test.org' - } - ]; - - h.options({ - checkUpdates: false - }); - - t.context.hugo = h; - t.context.items = items; -}); - -/** - * Exact match - */ -test('exact match', t => { - const h = t.context.hugo; - - let matches = h.matches(t.context.items, 'bla@test.org', { - keys: ['email'], - threshold: 0 - }); - - t.true(Array.isArray(matches)); - t.is(matches.length, 1); - t.is(matches[0].title, 'Pinguin Test'); - t.is(matches[0].email, 'bla@test.org'); -}); - -/** - * Exact match from output buffer (existing items) - */ -test('exact match from output buffer', t => { - const h = t.context.hugo; - - // Add items to output buffer - t.is(h.itemCount, 0); - h.addItems(t.context.items); - t.is(h.itemCount, 3); - - // Filter items - h.filterItems('bla@test.org', { - keys: ['email'], - threshold: 0 - }); - - let matches = h.outputBuffer.items; - t.true(Array.isArray(matches)); - t.is(matches.length, 1); - t.is(matches[0].title, 'Pinguin Test'); - t.is(matches[0].email, 'bla@test.org'); -}); - -/** - * Match multiple keys - */ -test('match multiple keys', t => { - const h = t.context.hugo; - - let matches = h.matches(t.context.items, 'test', { - keys: ['email', 'title'] - }); - - t.true(Array.isArray(matches)); - t.true(matches.length === 3); -}); - -/** - * Match multiple keys from output buffer (existing items) - */ -test('match multiple keys from output buffer', t => { - const h = t.context.hugo; - - // Add items to output buffer - t.is(h.itemCount, 0); - h.addItems(t.context.items); - t.is(h.itemCount, 3); - - // Filter items - h.filterItems('test', { - keys: ['email', 'title'] - }); - - let matches = h.outputBuffer.items; - t.true(Array.isArray(matches)); - t.true(matches.length === 3); -}); - -/** - * No matches - */ -test('no matches', t => { - const h = t.context.hugo; - - let matches = h.matches(t.context.items, 'bla@test.it', { - keys: ['email'], - threshold: 0 - }); - - t.true(Array.isArray(matches)); - t.true(matches.length === 0); -}); - -/** - * No matches from output buffer (existing items) - */ -test('no matches from output buffer', t => { - const h = t.context.hugo; - - // Add items to output buffer - t.is(h.itemCount, 0); - h.addItems(t.context.items); - t.is(h.itemCount, 3); - - // Filter items - h.filterItems('bla@test.it', { - keys: ['email'], - threshold: 0 - }); - - let matches = h.outputBuffer.items; - t.true(Array.isArray(matches)); - t.is(matches.length, 0); - t.is(h.itemCount, 0); -}); diff --git a/tests/output.js b/tests/output.js deleted file mode 100644 index 6985bd5..0000000 --- a/tests/output.js +++ /dev/null @@ -1,298 +0,0 @@ -import test from 'ava'; -import hookStd from 'hook-std'; - -import {hugo} from './_init'; - -/** - * Set-up - */ -test.beforeEach('setup', t => { - const h = hugo(); - - h.options({ - checkUpdates: false - }); - - t.context.hugo = h; -}); - -/** - * Items only - */ -test('items only', t => { - const h = t.context.hugo; - - h.addItem({ - title: 'foo' - }); - - h.addItems([ - { - title: 'bar', - subtitle: 'foo' - }, - { - title: 'boop', - subtitle: 'bleep' - } - ]); - - // Assert output - t.snapshot(h._outputBuffer); -}); - -/** - * Variables only - */ -test('variables only', t => { - const h = t.context.hugo; - - h.addVariable('foo', 'bar'); - h.addVariables({ - bleep: 'bloop', - boop: { - tap: 'top' - } - }); - - // Assert output - t.snapshot(h._outputBuffer); -}); - -/** - * Variables and items combined - */ -test('variables and items combined', t => { - const h = t.context.hugo; - - h.addVariable('foo', 'bar'); - h.addItem({ - title: 'foo' - }); - - // Assert output - t.snapshot(h._outputBuffer); -}); - -/** - * Item variables - */ -test('items with variables', t => { - const h = t.context.hugo; - - // Set Alfred version to 3.4.1 or later - process.env.alfred_version = '3.4.1'; // eslint-disable-line camelcase - - // Add items - h.addItems([ - { - title: 'Test 1', - variables: { - foo: 'bar' - } - }, - { - title: 'Test 2', - arg: 'foobar', - variables: { - bar: 'foo' - } - }, - { - title: 'Test 3', - arg: { - variables: { - foo: 'bar' - } - } - }, - { - title: 'Test 4', - arg: { - arg: 'foobar', - variables: { - bar: 'foo' - } - } - }, - { - title: 'Test 5', - arg: { - arg: 'foobar', - variables: { - bar: 'foo' - } - }, - variables: { - foo: 'bar' - } - } - ]); - - // Add variables - h.addVariable('bloop', 'bleep'); - h.addVariables({ - flooble: 'flab', - flabby: 'flop' - }); - - // Assert output - t.is(h.alfredMeta.version, '3.4.1'); - t.snapshot(h._outputBuffer); -}); - -/** - * Item variables (legacy, < 3.4.1) - */ -test('items with legacy variables (< 3.4.1)', t => { - const h = t.context.hugo; - - // Set Alfred version to pre 3.4.1 - process.env.alfred_version = '3.4.0'; // eslint-disable-line camelcase - - // Add items - h.addItems([ - { - title: 'Test 1', - variables: { - foo: 'bar' - } - }, - { - title: 'Test 2', - arg: 'foobar', - variables: { - bar: 'foo' - } - }, - { - title: 'Test 3', - arg: { - variables: { - foo: 'bar' - } - } - }, - { - title: 'Test 4', - arg: { - arg: 'foobar', - variables: { - bar: 'foo' - } - } - }, - { - title: 'Test 5', - arg: { - arg: 'foobar', - variables: { - bar: 'foo' - } - }, - variables: { - foo: 'bar' - } - } - ]); - - // Add variables - h.addVariable('bloop', 'bleep'); - h.addVariables({ - flooble: 'flab', - flabby: 'flop' - }); - - // Assert output - t.is(h.alfredMeta.version, '3.4.0'); - t.snapshot(h._outputBuffer); -}); - -/** - * Retun parameter - * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json - */ -test.cb('rerun parameter', t => { - const h = t.context.hugo; - - t.plan(1); - - const unhook = hookStd.stdout(output => { - unhook(); - - output = JSON.parse(output); - - t.snapshot(output); - t.end(); - }); - - h.rerun(1.4); - h.addVariable('foo', 'bar'); - h.addItem({ - title: 'foo' - }); - - h.feedback(); -}); - -/** - * Invalid rerun parameter - * @see https://www.alfredapp.com/help/workflows/inputs/script-filter/json - */ -test.cb('invalid rerun parameter', t => { - const h = t.context.hugo; - - t.plan(2); - - const unhook = hookStd.stdout(output => { - unhook(); - - output = JSON.parse(output); - - // Output should not contain rerun - t.falsy(output.rerun); - t.snapshot(output); - - t.end(); - }); - - // Rerun is out of bounds - h.rerun(100); - - // Add some variables and items - h.addVariable('foo', 'bar'); - h.addItem({ - title: 'foo' - }); - - h.feedback(); -}); - -/** - * Invalid items - */ -test('invalid items', t => { - const h = t.context.hugo; - - // Add invalid items - h.addItem({ - foo: 'bar' - }); - - h.addItems([ - { - bloop: 'bleep' - }, - { - fleeble: 'flap' - } - ]); - - // Add valid item - h.addItem({ - title: 'foo' - }); - - // Assert output - t.snapshot(h._outputBuffer); -}); diff --git a/tests/updates.js b/tests/updates.js deleted file mode 100644 index 410ddbc..0000000 --- a/tests/updates.js +++ /dev/null @@ -1,171 +0,0 @@ -import fs from 'fs-extra'; -import path from 'path'; -import test from 'ava'; -import nock from 'nock'; -import delay from 'delay'; -import moment from 'moment'; - -import {hugo, updater} from './_init'; - -/** - * Set-up - */ -test.before('mock requests with nock', () => { - nock('https://github.com') - .persist() - .get('/packal/repository/blob/master/my.work.flow/appcast.xml') - .reply(200, fs.readFileSync(path.join(__dirname, 'mocks/appcast.xml'))); - - nock('https://registry.npmjs.org') - .persist() - .get('/alfred-my-workflow') - .reply(200, JSON.stringify({ - name: 'alfred-my-workflow', - 'dist-tags': { - latest: '2.1.0' - }, - versions: { - '1.0.0': { - name: 'alfred-my-workflow', - version: '1.0.0' - }, - '2.1.0': { - name: 'alfred-my-workflow', - version: '2.1.0' - } - } - })); -}); - -test.beforeEach('setup', t => { - const h = hugo(); - const u = updater(); - - h.options({ - checkUpdates: true, - updateNotification: false, - updateItem: true - }); - - const pkg = { - name: 'alfred-my-workflow', - version: '1.0.0' - }; - - t.context.hugo = h; - t.context.updater = u; - t.context.pkg = pkg; -}); - -/** - * Check Packal for updates uncached - */ -test('check packal for updates uncached', async t => { - const u = t.context.updater; - - let update = await u.checkUpdates('packal', moment.duration(1, 'day')); - - t.is(update.version, '2.1.0'); - t.regex(update.url, /^https:\/\/encrypted\.google\.com\//); - t.regex(update.url, /my\.work\.flow/); - t.true(update.checkedOnline); -}); - -/** - * Check Packal for updates cached - */ -test('check packal for updates cached', async t => { - const u = t.context.updater; - - // Check for updates - let update = await u.checkUpdates('packal', moment.duration(2, 'seconds')); - - t.is(update.version, '2.1.0'); - t.regex(update.url, /^https:\/\/encrypted\.google\.com\//); - t.regex(update.url, /my\.work\.flow/); - t.true(update.checkedOnline); - - // Check for updates again, should be cached. - update = await u.checkUpdates('packal', moment.duration(1, 'milliseconds')); - - t.false(update.checkedOnline); - - // Let cache expire - await delay(2500); - - // Check for updates again, should be checked online - update = await u.checkUpdates('packal', moment.duration(1, 'milliseconds')); - - t.true(update.checkedOnline); -}); - -/** - * Check NPM for updates uncached - */ -test('check npm for updates uncached', async t => { - const u = t.context.updater; - - let update = await u.checkUpdates('npm', moment.duration(1, 'day'), t.context.pkg); - - t.is(update.version, '2.1.0'); - t.is(update.url, `https://www.npmjs.com/package/${t.context.pkg.name}`); - t.true(update.checkedOnline); -}); - -/** - * Check NPM for updates cached - */ -test('check npm for updates cached', async t => { - const u = t.context.updater; - - // Check for updates - let update = await u.checkUpdates('npm', moment.duration(2, 'seconds'), t.context.pkg); - - t.is(update.version, '2.1.0'); - t.is(update.url, `https://www.npmjs.com/package/${t.context.pkg.name}`); - t.true(update.checkedOnline); - - // Check for updates again, should be cached. - update = await u.checkUpdates('npm', moment.duration(1, 'milliseconds'), t.context.pkg); - - t.false(update.checkedOnline); - - // Let cache expire - await delay(2500); - - // Check for updates again, should be checked online - update = await u.checkUpdates('npm', moment.duration(1, 'milliseconds'), t.context.pkg); - - t.true(update.checkedOnline); -}); - -/** - * Check update notification item - */ -test.serial('update notification item', async t => { - const h = t.context.hugo; - - h.options({ - updateSource: 'packal' - }); - - // Check for updates - await h.checkUpdates(); - - // Check output buffer - t.true(Array.isArray(h.outputBuffer.items)); - t.is(h.outputBuffer.items.length, 1); - - // Check update item - let item = h.outputBuffer.items.pop(); - - t.is(item.title, `Workflow update available!`); - t.is(h.getItemVariable(item, 'task'), 'wfUpdate'); -}); - -/** - * Tear-down - */ -test.after.always('nock cleanup', () => { - nock.cleanAll(); -}); diff --git a/tsconfig.dist.json b/tsconfig.dist.json new file mode 100644 index 0000000..64f05d3 --- /dev/null +++ b/tsconfig.dist.json @@ -0,0 +1,15 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "declaration": true, + "declarationMap": false, + "sourceMap": false, + "outDir": "dist", + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "test/**/*" + ] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..0098e14 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "target": "es2017", + "module": "commonjs", + "lib": ["es2017"], + "strict": false, + "noImplicitAny": true, + "declaration": true, + "declarationMap": false, + "sourceMap": true, + "esModuleInterop": true, + "outDir": "build", + }, + "include": [ + "src/**/*", + "test/**/*" + ] +} diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..bb79f93 --- /dev/null +++ b/tslint.json @@ -0,0 +1,15 @@ +{ + "defaultSeverity": "error", + "extends": [ + "tslint:recommended" + ], + "jsRules": {}, + "rules": { + "object-literal-sort-keys": false, + "no-console": false, + "interface-name": false, + "ordered-imports": false, + "variable-name": false + }, + "rulesDirectory": [] +} diff --git a/updater.js b/updater.js deleted file mode 100644 index 6276137..0000000 --- a/updater.js +++ /dev/null @@ -1,2 +0,0 @@ -'use strict';var _regenerator=require('babel-runtime/regenerator');var _regenerator2=_interopRequireDefault(_regenerator);var _asyncToGenerator2=require('babel-runtime/helpers/asyncToGenerator');var _asyncToGenerator3=_interopRequireDefault(_asyncToGenerator2);var _classCallCheck2=require('babel-runtime/helpers/classCallCheck');var _classCallCheck3=_interopRequireDefault(_classCallCheck2);var _createClass2=require('babel-runtime/helpers/createClass');var _createClass3=_interopRequireDefault(_createClass2);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{default:obj};}var CacheConf=require('cache-conf');var moment=require('moment');var readPkg=require('read-pkg');var latestVersion=require('latest-version');var got=require('got');var Updater=function(){function Updater(){(0,_classCallCheck3.default)(this,Updater);this.cache=new CacheConf({configName:'updater',cwd:process.env.alfred_workflow_cache,version:process.env.alfred_workflow_version});}(0,_createClass3.default)(Updater,[{key:'checkPackal',value:function(){var _ref=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(interval){var bundleId,searchParam,pkgUrl,latest;return _regenerator2.default.wrap(function _callee$(_context){while(1){switch(_context.prev=_context.next){case 0:bundleId=process.env.alfred_workflow_bundleid;if(bundleId){_context.next=4;break;}console.error('No bundle ID, not checking Packal for updates.');return _context.abrupt('return');case 4:searchParam=encodeURIComponent('site:packal.org '+bundleId);pkgUrl=`https://encrypted.google.com/search?sourceid=chrome&ie=UTF-8&q=${searchParam}&btnI`;_context.next=8;return got(`https://github.com/packal/repository/blob/master/${bundleId}/appcast.xml`).catch(function(err){console.error(err);return false;}).then(function(response){var versionMatches=response.body.match(/(.+)<\/version>/);if(versionMatches&&versionMatches.length>0){return{version:versionMatches[1],url:pkgUrl,checkedOnline:false};}return false;});case 8:latest=_context.sent;this.cache.set('latest_version_packal',latest,{maxAge:interval.as('milliseconds')});if(latest){latest.checkedOnline=true;}return _context.abrupt('return',latest);case 12:case'end':return _context.stop();}}},_callee,this);}));function checkPackal(_x){return _ref.apply(this,arguments);}return checkPackal;}()},{key:'checkNpm',value:function(){var _ref2=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2(interval){var pkg=arguments.length>1&&arguments[1]!==undefined?arguments[1]:null;var url,latest;return _regenerator2.default.wrap(function _callee2$(_context2){while(1){switch(_context2.prev=_context2.next){case 0:_context2.t0=pkg;if(_context2.t0){_context2.next=5;break;}_context2.next=4;return readPkg(process.cwd());case 4:_context2.t0=_context2.sent;case 5:pkg=_context2.t0;url=`https://www.npmjs.com/package/${pkg.name}`;_context2.next=9;return latestVersion(pkg.name).catch(function(err){console.error(err);return false;}).then(function(version){return{version:version,url:url,checkedOnline:false};});case 9:latest=_context2.sent;this.cache.set('latest_version_npm',latest,{maxAge:interval.as('milliseconds')});if(latest){latest.checkedOnline=true;}return _context2.abrupt('return',latest);case 13:case'end':return _context2.stop();}}},_callee2,this);}));function checkNpm(_x3){return _ref2.apply(this,arguments);}return checkNpm;}()},{key:'checkUpdates',value:function(){var _ref3=(0,_asyncToGenerator3.default)(_regenerator2.default.mark(function _callee3(source,interval){var pkg=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var latest;return _regenerator2.default.wrap(function _callee3$(_context3){while(1){switch(_context3.prev=_context3.next){case 0:latest=this.cache.get(`latest_version_${source}`);if(!(latest===false)){_context3.next=3;break;}return _context3.abrupt('return');case 3:if(latest){_context3.next=10;break;}_context3.t0=source.toLowerCase();_context3.next=_context3.t0==='npm'?7:_context3.t0==='packal'?8:9;break;case 7:return _context3.abrupt('return',this.checkNpm(interval,pkg));case 8:return _context3.abrupt('return',this.checkPackal(interval));case 9:return _context3.abrupt('return');case 10:latest.checkedOnline=false;return _context3.abrupt('return',latest);case 12:case'end':return _context3.stop();}}},_callee3,this);}));function checkUpdates(_x5,_x6){return _ref3.apply(this,arguments);}return checkUpdates;}()}]);return Updater;}();module.exports=new Updater(); -//# sourceMappingURL=updater.js.map diff --git a/updater.js.flow b/updater.js.flow deleted file mode 100644 index f90613b..0000000 --- a/updater.js.flow +++ /dev/null @@ -1,157 +0,0 @@ -// @flow - -const CacheConf = require('cache-conf'); -const moment = require('moment'); -const readPkg = require('read-pkg'); -const latestVersion = require('latest-version'); -const got = require('got'); - -/** - * Hugo Updater - */ -class Updater { - /** - * Cache store - * @see https://www.npmjs.com/package/cache-conf - * @type {CacheConf} - */ - cache: CacheConf; - - /** - * Hugo updater constructor - * @constructor - */ - constructor() { - // Configure cache store - this.cache = new CacheConf({ - configName: 'updater', - cwd: process.env.alfred_workflow_cache, - version: process.env.alfred_workflow_version - }); - } - - /** - * Check Packal for updates - * @param {moment.Duration} interval Update interval - * @async - */ - async checkPackal(interval: moment.Duration): Object { - // Bundle ID - const bundleId: ?string = process.env.alfred_workflow_bundleid; - - if (!bundleId) { - console.error('No bundle ID, not checking Packal for updates.'); - return; - } - - // Packal URL - const searchParam: string = encodeURIComponent('site:packal.org ' + bundleId); - const pkgUrl: string = `https://encrypted.google.com/search?sourceid=chrome&ie=UTF-8&q=${searchParam}&btnI`; - - let latest = await got(`https://github.com/packal/repository/blob/master/${bundleId}/appcast.xml`) - .catch(err => { - // Set to false on failure (e.g. not found). - console.error(err); - return false; - }) - .then(response => { - // Get version from XML - let versionMatches = response.body.match(/(.+)<\/version>/); - - if (versionMatches && versionMatches.length > 0) { - return { - version: versionMatches[1], - url: pkgUrl, - checkedOnline: false - }; - } - - return false; - }); - - // Cache results - this.cache.set('latest_version_packal', latest, { - maxAge: interval.as('milliseconds') - }); - - // Got it from the internet! - if (latest) { - latest.checkedOnline = true; - } - - return latest; - } - - /** - * Check NPM for updates - * @param {moment.Duration} interval Update interval - * @async - */ - async checkNpm(interval: moment.Duration, pkg: ?Object = null): Object { - // Get details from package.json - pkg = pkg || await readPkg(process.cwd()); - - // NPM URL - const url: string = `https://www.npmjs.com/package/${pkg.name}`; - - // Check for updates - let latest = await latestVersion(pkg.name) - .catch(err => { - // Set to false on failure (e.g. not found). - console.error(err); - return false; - }) - .then(version => ({ - version: version, - url: url, - checkedOnline: false - })); - - // Cache results - this.cache.set('latest_version_npm', latest, { - maxAge: interval.as('milliseconds') - }); - - // Got it from the internet! - if (latest) { - latest.checkedOnline = true; - } - - return latest; - } - - /** - * Check for updates - * @param {string} source Update source (npm or packal) - * @param {moment.Duration} interval Update interval - * @async - */ - async checkUpdates(source: string, interval: moment.Duration, pkg: ?Object = null): Object { - // Get from cache - let latest = this.cache.get(`latest_version_${source}`); - - // Don't do anything if the package wasn't found last time. - if (latest === false) { - return; - } - - // Check for updates online - if (!latest) { - switch (source.toLowerCase()) { - case 'npm': - return this.checkNpm(interval, pkg); - case 'packal': - return this.checkPackal(interval); - default: - return; - } - } - - // Got it from cache! - latest.checkedOnline = false; - - return latest; - } -} - -module.exports = new Updater(); diff --git a/updater.js.map b/updater.js.map deleted file mode 100644 index 929166a..0000000 --- a/updater.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["updater.js.flow"],"names":["CacheConf","require","moment","readPkg","latestVersion","got","Updater","cache","configName","cwd","process","env","alfred_workflow_cache","version","alfred_workflow_version","interval","bundleId","alfred_workflow_bundleid","console","error","searchParam","encodeURIComponent","pkgUrl","catch","err","then","versionMatches","response","body","match","length","url","checkedOnline","latest","set","maxAge","as","pkg","name","source","get","toLowerCase","checkNpm","checkPackal","module","exports"],"mappings":"klBAEA,GAAMA,WAAYC,QAAQ,YAAR,CAAlB,CACA,GAAMC,QAASD,QAAQ,QAAR,CAAf,CACA,GAAME,SAAUF,QAAQ,UAAR,CAAhB,CACA,GAAMG,eAAgBH,QAAQ,gBAAR,CAAtB,CACA,GAAMI,KAAMJ,QAAQ,KAAR,CAAZ,C,GAKMK,Q,YAYF,kBAAc,4CAEV,KAAKC,KAAL,CAAa,GAAIP,UAAJ,CAAc,CACvBQ,WAAY,SADW,CAEvBC,IAAKC,QAAQC,GAAR,CAAYC,qBAFM,CAGvBC,QAASH,QAAQC,GAAR,CAAYG,uBAHE,CAAd,CAAb,CAKH,C,2JAOiBC,Q,2JAERC,Q,CAAoBN,QAAQC,GAAR,CAAYM,wB,IAEjCD,Q,yBACDE,QAAQC,KAAR,CAAc,gDAAd,E,wCAKEC,W,CAAsBC,mBAAmB,mBAAqBL,QAAxC,C,CACtBM,M,CAAkB,kEAAiEF,WAAY,O,uBAElFf,KAAK,oDAAmDW,QAAS,cAAjE,EACdO,KADc,CACR,aAAO,CAEVL,QAAQC,KAAR,CAAcK,GAAd,EACA,MAAO,MAAP,CACH,CALc,EAMdC,IANc,CAMT,kBAAY,CAEd,GAAIC,gBAAiBC,SAASC,IAAT,CAAcC,KAAd,CAAoB,0BAApB,CAArB,CAEA,GAAIH,gBAAkBA,eAAeI,MAAf,CAAwB,CAA9C,CAAiD,CAC7C,MAAO,CACHjB,QAASa,eAAe,CAAf,CADN,CAEHK,IAAKT,MAFF,CAGHU,cAAe,KAHZ,CAAP,CAKH,CAED,MAAO,MAAP,CACH,CAnBc,C,QAAfC,M,eAsBJ,KAAK1B,KAAL,CAAW2B,GAAX,CAAe,uBAAf,CAAwCD,MAAxC,CAAgD,CAC5CE,OAAQpB,SAASqB,EAAT,CAAY,cAAZ,CADoC,CAAhD,EAKA,GAAIH,MAAJ,CAAY,CACRA,OAAOD,aAAP,CAAuB,IAAvB,CACH,C,gCAEMC,M,4QAQIlB,Q,KAA2BsB,I,2DAAe,I,mJAE/CA,G,iEAAalC,SAAQO,QAAQD,GAAR,EAAR,C,2CAAnB4B,G,cAGMN,G,CAAe,iCAAgCM,IAAIC,IAAK,E,wBAG3ClC,eAAciC,IAAIC,IAAlB,EACdf,KADc,CACR,aAAO,CAEVL,QAAQC,KAAR,CAAcK,GAAd,EACA,MAAO,MAAP,CACH,CALc,EAMdC,IANc,CAMT,wBAAY,CACdZ,QAASA,OADK,CAEdkB,IAAKA,GAFS,CAGdC,cAAe,KAHD,CAAZ,EANS,C,QAAfC,M,gBAaJ,KAAK1B,KAAL,CAAW2B,GAAX,CAAe,oBAAf,CAAqCD,MAArC,CAA6C,CACzCE,OAAQpB,SAASqB,EAAT,CAAY,cAAZ,CADiC,CAA7C,EAKA,GAAIH,MAAJ,CAAY,CACRA,OAAOD,aAAP,CAAuB,IAAvB,CACH,C,iCAEMC,M,8QASQM,M,CAAgBxB,Q,KAA2BsB,I,2DAAe,I,kIAErEJ,M,CAAS,KAAK1B,KAAL,CAAWiC,GAAX,CAAgB,kBAAiBD,MAAO,EAAxC,C,MAGTN,SAAW,K,uEAKVA,M,wCACOM,OAAOE,WAAP,E,+BACC,K,kBAEA,Q,mDADM,KAAKC,QAAL,CAAc3B,QAAd,CAAwBsB,GAAxB,C,0CAEA,KAAKM,WAAL,CAAiB5B,QAAjB,C,mDAOnBkB,OAAOD,aAAP,CAAuB,KAAvB,C,iCAEOC,M,oLAIfW,OAAOC,OAAP,CAAiB,GAAIvC,QAAJ,EAAjB","file":"updater.js","sourcesContent":["// @flow\n\nconst CacheConf = require('cache-conf');\nconst moment = require('moment');\nconst readPkg = require('read-pkg');\nconst latestVersion = require('latest-version');\nconst got = require('got');\n\n/**\n * Hugo Updater\n */\nclass Updater {\n /**\n * Cache store\n * @see https://www.npmjs.com/package/cache-conf\n * @type {CacheConf}\n */\n cache: CacheConf;\n\n /**\n * Hugo updater constructor\n * @constructor\n */\n constructor() {\n // Configure cache store\n this.cache = new CacheConf({\n configName: 'updater',\n cwd: process.env.alfred_workflow_cache,\n version: process.env.alfred_workflow_version\n });\n }\n\n /**\n * Check Packal for updates\n * @param {moment.Duration} interval Update interval\n * @async\n */\n async checkPackal(interval: moment.Duration): Object {\n // Bundle ID\n const bundleId: ?string = process.env.alfred_workflow_bundleid;\n\n if (!bundleId) {\n console.error('No bundle ID, not checking Packal for updates.');\n return;\n }\n\n // Packal URL\n const searchParam: string = encodeURIComponent('site:packal.org ' + bundleId);\n const pkgUrl: string = `https://encrypted.google.com/search?sourceid=chrome&ie=UTF-8&q=${searchParam}&btnI`;\n\n let latest = await got(`https://github.com/packal/repository/blob/master/${bundleId}/appcast.xml`)\n .catch(err => {\n // Set to false on failure (e.g. not found).\n console.error(err);\n return false;\n })\n .then(response => {\n // Get version from XML\n let versionMatches = response.body.match(/(.+)<\\/version>/);\n\n if (versionMatches && versionMatches.length > 0) {\n return {\n version: versionMatches[1],\n url: pkgUrl,\n checkedOnline: false\n };\n }\n\n return false;\n });\n\n // Cache results\n this.cache.set('latest_version_packal', latest, {\n maxAge: interval.as('milliseconds')\n });\n\n // Got it from the internet!\n if (latest) {\n latest.checkedOnline = true;\n }\n\n return latest;\n }\n\n /**\n * Check NPM for updates\n * @param {moment.Duration} interval Update interval\n * @async\n */\n async checkNpm(interval: moment.Duration, pkg: ?Object = null): Object {\n // Get details from package.json\n pkg = pkg || await readPkg(process.cwd());\n\n // NPM URL\n const url: string = `https://www.npmjs.com/package/${pkg.name}`;\n\n // Check for updates\n let latest = await latestVersion(pkg.name)\n .catch(err => {\n // Set to false on failure (e.g. not found).\n console.error(err);\n return false;\n })\n .then(version => ({\n version: version,\n url: url,\n checkedOnline: false\n }));\n\n // Cache results\n this.cache.set('latest_version_npm', latest, {\n maxAge: interval.as('milliseconds')\n });\n\n // Got it from the internet!\n if (latest) {\n latest.checkedOnline = true;\n }\n\n return latest;\n }\n\n /**\n * Check for updates\n * @param {string} source Update source (npm or packal)\n * @param {moment.Duration} interval Update interval\n * @async\n */\n async checkUpdates(source: string, interval: moment.Duration, pkg: ?Object = null): Object {\n // Get from cache\n let latest = this.cache.get(`latest_version_${source}`);\n\n // Don't do anything if the package wasn't found last time.\n if (latest === false) {\n return;\n }\n\n // Check for updates online\n if (!latest) {\n switch (source.toLowerCase()) {\n case 'npm':\n return this.checkNpm(interval, pkg);\n case 'packal':\n return this.checkPackal(interval);\n default:\n return;\n }\n }\n\n // Got it from cache!\n latest.checkedOnline = false;\n\n return latest;\n }\n}\n\nmodule.exports = new Updater();\n"]} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..154ffc1 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,4404 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@ava/babel-plugin-throws-helper@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@ava/babel-plugin-throws-helper/-/babel-plugin-throws-helper-3.0.0.tgz#2c933ec22da0c4ce1fc5369f2b95452c70420586" + integrity sha512-mN9UolOs4WX09QkheU1ELkVy2WPnwonlO3XMdN8JF8fQqRVgVTR21xDbvEOUsbwz6Zwjq7ji9yzyjuXqDPalxg== + +"@ava/babel-preset-stage-4@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@ava/babel-preset-stage-4/-/babel-preset-stage-4-3.0.0.tgz#32c46b22b640d1ba0c6e38ae4abd58efab965558" + integrity sha512-uI5UBx++UsckkfnbF0HH6jvTIvM4r/Kxt1ROO2YXKu5H15sScAtxUIAHiUVbPIw24zPqz/PlF3xxlIDuyFzlQw== + dependencies: + "@babel/plugin-proposal-async-generator-functions" "^7.2.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.2.0" + "@babel/plugin-transform-dotall-regex" "^7.4.3" + "@babel/plugin-transform-modules-commonjs" "^7.4.3" + +"@ava/babel-preset-transform-test-files@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@ava/babel-preset-transform-test-files/-/babel-preset-transform-test-files-5.0.0.tgz#e06fc762069511e597531cc1120e22216aac6981" + integrity sha512-rqgyQwkT0+j2JzYP51dOv80u33rzAvjBtXRzUON+7+6u26mjoudRXci2+1s18rat8r4uOlZfbzm114YS6pwmYw== + dependencies: + "@ava/babel-plugin-throws-helper" "^3.0.0" + babel-plugin-espower "^3.0.1" + +"@babel/code-frame@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" + integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== + dependencies: + "@babel/highlight" "^7.0.0" + +"@babel/core@^7.4.5": + version "7.4.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.4.5.tgz#081f97e8ffca65a9b4b0fdc7e274e703f000c06a" + integrity sha512-OvjIh6aqXtlsA8ujtGKfC7LYWksYSX8yQcM8Ay3LuvVeQ63lcOKgoZWVqcpFwkd29aYU9rVx7jxhfhiEDV9MZA== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.4.4" + "@babel/helpers" "^7.4.4" + "@babel/parser" "^7.4.5" + "@babel/template" "^7.4.4" + "@babel/traverse" "^7.4.5" + "@babel/types" "^7.4.4" + convert-source-map "^1.1.0" + debug "^4.1.0" + json5 "^2.1.0" + lodash "^4.17.11" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.0.0", "@babel/generator@^7.4.0", "@babel/generator@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.4.4.tgz#174a215eb843fc392c7edcaabeaa873de6e8f041" + integrity sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ== + dependencies: + "@babel/types" "^7.4.4" + jsesc "^2.5.1" + lodash "^4.17.11" + source-map "^0.5.0" + trim-right "^1.0.1" + +"@babel/helper-annotate-as-pure@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" + integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-function-name@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" + integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw== + dependencies: + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-get-function-arity@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" + integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-module-imports@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d" + integrity sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A== + dependencies: + "@babel/types" "^7.0.0" + +"@babel/helper-module-transforms@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz#96115ea42a2f139e619e98ed46df6019b94414b8" + integrity sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@babel/helper-simple-access" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/template" "^7.4.4" + "@babel/types" "^7.4.4" + lodash "^4.17.11" + +"@babel/helper-plugin-utils@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" + integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== + +"@babel/helper-regex@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.4.4.tgz#a47e02bc91fb259d2e6727c2a30013e3ac13c4a2" + integrity sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q== + dependencies: + lodash "^4.17.11" + +"@babel/helper-remap-async-to-generator@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f" + integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.0.0" + "@babel/helper-wrap-function" "^7.1.0" + "@babel/template" "^7.1.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-simple-access@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" + integrity sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w== + dependencies: + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + +"@babel/helper-split-export-declaration@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz#ff94894a340be78f53f06af038b205c49d993677" + integrity sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q== + dependencies: + "@babel/types" "^7.4.4" + +"@babel/helper-wrap-function@^7.1.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz#c4e0012445769e2815b55296ead43a958549f6fa" + integrity sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ== + dependencies: + "@babel/helper-function-name" "^7.1.0" + "@babel/template" "^7.1.0" + "@babel/traverse" "^7.1.0" + "@babel/types" "^7.2.0" + +"@babel/helpers@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.4.4.tgz#868b0ef59c1dd4e78744562d5ce1b59c89f2f2a5" + integrity sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A== + dependencies: + "@babel/template" "^7.4.4" + "@babel/traverse" "^7.4.4" + "@babel/types" "^7.4.4" + +"@babel/highlight@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" + integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + +"@babel/parser@^7.0.0", "@babel/parser@^7.4.3", "@babel/parser@^7.4.4", "@babel/parser@^7.4.5": + version "7.4.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.5.tgz#04af8d5d5a2b044a2a1bffacc1e5e6673544e872" + integrity sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew== + +"@babel/plugin-proposal-async-generator-functions@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" + integrity sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-remap-async-to-generator" "^7.1.0" + "@babel/plugin-syntax-async-generators" "^7.2.0" + +"@babel/plugin-proposal-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5" + integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + +"@babel/plugin-syntax-async-generators@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f" + integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-object-rest-spread@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" + integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c" + integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + +"@babel/plugin-transform-dotall-regex@^7.4.3": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz#361a148bc951444312c69446d76ed1ea8e4450c3" + integrity sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-regex" "^7.4.4" + regexpu-core "^4.5.4" + +"@babel/plugin-transform-modules-commonjs@^7.4.3": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz#0bef4713d30f1d78c2e59b3d6db40e60192cac1e" + integrity sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw== + dependencies: + "@babel/helper-module-transforms" "^7.4.4" + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-simple-access" "^7.1.0" + +"@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.4.tgz#f4b88d1225689a08f5bc3a17483545be9e4ed237" + integrity sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.4.4" + "@babel/types" "^7.4.4" + +"@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5": + version "7.4.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.4.5.tgz#4e92d1728fd2f1897dafdd321efbff92156c3216" + integrity sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/generator" "^7.4.4" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/parser" "^7.4.5" + "@babel/types" "^7.4.4" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.11" + +"@babel/types@^7.0.0", "@babel/types@^7.2.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.4.tgz#8db9e9a629bb7c29370009b4b779ed93fe57d5f0" + integrity sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ== + dependencies: + esutils "^2.0.2" + lodash "^4.17.11" + to-fast-properties "^2.0.0" + +"@cloudstek/cache@^1.0.1": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@cloudstek/cache/-/cache-1.0.2.tgz#f28759ee8a1e11e05f39467fff004db13309d1c0" + integrity sha512-KjsqkajPc73XYyU2QTicWEGGOsiqOdDtS/JctlUTwjT5id2piAnFhpDQXJhInvcnm1AXRZEjq6Tfeoboc/WeTg== + dependencies: + fs-extra "^8.0.1" + moment "^2.24.0" + +"@concordance/react@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@concordance/react/-/react-2.0.0.tgz#aef913f27474c53731f4fd79cc2f54897de90fde" + integrity sha512-huLSkUuM2/P+U0uy2WwlKuixMsTODD8p4JVQBI4VKeopkiN0C7M3N9XYVawb4M+4spN5RrO/eLhk7KoQX6nsfA== + dependencies: + arrify "^1.0.1" + +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== + +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + +"@sinonjs/commons@^1", "@sinonjs/commons@^1.0.2", "@sinonjs/commons@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.4.0.tgz#7b3ec2d96af481d7a0321252e7b1c94724ec5a78" + integrity sha512-9jHK3YF/8HtJ9wCAbG+j8cD0i0+ATS9A7gXFqS36TblLPNy6rEEc+SB0imo91eCboGaBYGV/MT1/br/J+EE7Tw== + dependencies: + type-detect "4.0.8" + +"@sinonjs/formatio@^3.1.0", "@sinonjs/formatio@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-3.2.1.tgz#52310f2f9bcbc67bdac18c94ad4901b95fde267e" + integrity sha512-tsHvOB24rvyvV2+zKMmPkZ7dXX6LSLKZ7aOtXY6Edklp0uRcgGpOsQTTGTcWViFyx4uhWc6GV8QdnALbIbIdeQ== + dependencies: + "@sinonjs/commons" "^1" + "@sinonjs/samsam" "^3.1.0" + +"@sinonjs/samsam@^3.1.0", "@sinonjs/samsam@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-3.3.1.tgz#e88c53fbd9d91ad9f0f2b0140c16c7c107fe0d07" + integrity sha512-wRSfmyd81swH0hA1bxJZJ57xr22kC07a1N4zuIL47yTS04bDk6AoCkczcqHEjcRPmJ+FruGJ9WBQiJwMtIElFw== + dependencies: + "@sinonjs/commons" "^1.0.2" + array-from "^2.1.1" + lodash "^4.17.11" + +"@sinonjs/text-encoding@^0.7.1": + version "0.7.1" + resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5" + integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ== + +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + +"@types/events@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" + integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== + +"@types/fs-extra@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-7.0.0.tgz#9c4ad9e1339e7448a76698829def1f159c1b636c" + integrity sha512-ndoMMbGyuToTy4qB6Lex/inR98nPiNHacsgMPvy+zqMLgSxbt8VtWpDArpGp69h1fEDQHn1KB+9DWD++wgbwYA== + dependencies: + "@types/node" "*" + +"@types/glob@^7.1.1": + version "7.1.1" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" + integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w== + dependencies: + "@types/events" "*" + "@types/minimatch" "*" + "@types/node" "*" + +"@types/got@^9.4.4": + version "9.4.4" + resolved "https://registry.yarnpkg.com/@types/got/-/got-9.4.4.tgz#78129553f6a41715df601db43532cd0b87a55d3f" + integrity sha512-IGAJokJRE9zNoBdY5csIwN4U5qQn+20HxC0kM+BbUdfTKIXa7bOX/pdhy23NnLBRP8Wvyhx7X5e6EHJs+4d8HA== + dependencies: + "@types/node" "*" + "@types/tough-cookie" "*" + +"@types/minimatch@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== + +"@types/mockdate@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/mockdate/-/mockdate-2.0.0.tgz#aaf388a1ead3b0f5ed6dc1611956ea7b40a57d3c" + integrity sha1-qvOIoerTsPXtbcFhGVbqe0ClfTw= + +"@types/nock@^10.0.3": + version "10.0.3" + resolved "https://registry.yarnpkg.com/@types/nock/-/nock-10.0.3.tgz#dab1d18ffbccfbf2db811dab9584304eeb6e1c4c" + integrity sha512-OthuN+2FuzfZO3yONJ/QVjKmLEuRagS9TV9lEId+WHL9KhftYG+/2z+pxlr0UgVVXSpVD8woie/3fzQn8ft/Ow== + dependencies: + "@types/node" "*" + +"@types/node-notifier@^5.4.0": + version "5.4.0" + resolved "https://registry.yarnpkg.com/@types/node-notifier/-/node-notifier-5.4.0.tgz#4e66c85eb41cce8387b4cd9c6c67852be41a99db" + integrity sha512-M1XvCG6Rwej6+W0+kWultE46YS7erOy+W7suRmXtKwLGT3ytj6YEe9lqo47nRfL1xILzg9xJpKeNczIsWR8ymw== + dependencies: + "@types/node" "*" + +"@types/node@*", "@types/node@^12.0.2": + version "12.0.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.4.tgz#46832183115c904410c275e34cf9403992999c32" + integrity sha512-j8YL2C0fXq7IONwl/Ud5Kt0PeXw22zGERt+HSSnwbKOJVsAGkEz3sFCYwaF9IOuoG1HOtE0vKCj6sXF7Q0+Vaw== + +"@types/normalize-package-data@*", "@types/normalize-package-data@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" + integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== + +"@types/read-pkg@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/read-pkg/-/read-pkg-4.0.0.tgz#773457698f405b53a73471538e76e433e04cb786" + integrity sha512-mnQ7ukQhFGkbErwioo+ahHhkdIhw/llqW97ijWi6l3JYKXAokElLZxlEOtlYYmPKLUJxRKhplOa514n2TyVxjg== + dependencies: + "@types/normalize-package-data" "*" + +"@types/semver@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-6.0.0.tgz#86ba89f02a414e39c68d02b351872e4ed31bd773" + integrity sha512-OO0srjOGH99a4LUN2its3+r6CBYcplhJ466yLqs+zvAWgphCpS8hYZEZ797tRDP/QKcqTdb/YCN6ifASoAWkrQ== + +"@types/sinon@^7.0.12": + version "7.0.12" + resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-7.0.12.tgz#18412939ae45b225bd38715a25c1040cbad80f42" + integrity sha512-fo0MWpVPSUrnZZhp9wyu+hhI3VJ9+Jhs+PWrokBTg3d2ryNPDOAWF1csIhQuYWBTn7KdZzXpRgpX2o6cwOlPWg== + +"@types/tough-cookie@*": + version "2.3.5" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-2.3.5.tgz#9da44ed75571999b65c37b60c9b2b88db54c585d" + integrity sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg== + +alfred-link@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/alfred-link/-/alfred-link-0.3.0.tgz#d7afce495c04d85c6293c9a5abefbe7506ef8dd5" + integrity sha512-35Ezi7chQWndog9DETavKBA9Ka6PFR/PvubhgR02WXNGftGsjL58D/mhFL8cQsx+gZojEVfBarNMLpSQRKNe4Q== + dependencies: + del "^2.2.2" + make-dir "^1.3.0" + path-exists "^3.0.0" + pify "^2.3.0" + plist "^2.0.1" + read-pkg-up "^1.0.1" + resolve-alfred-prefs "^1.0.0" + sudo-block "^1.2.0" + user-home "^2.0.0" + +ansi-align@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" + integrity sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw== + dependencies: + string-width "^3.0.0" + +ansi-escapes@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.1.0.tgz#62a9e5fa78e99c5bb588b1796855f5d729231b53" + integrity sha512-2VY/iCUZTDLD/qxptS3Zn3c6k2MeIbYqjRXqM8T5oC7N2mMjh3xIU3oYru6cHGbldFa9h5i8N0fP65UaUqrMWA== + dependencies: + type-fest "^0.3.0" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.0.0.tgz#f6b84e8fc97ea7add7a53b7530ef28f3fde0e048" + integrity sha512-8zjUtFJ3db/QoPXuuEMloS2AUf79/yeyttJ7Abr3hteopJu9HK8vsgGviGUMq+zyA6cZZO6gAyZoMTF6TgaEjA== + dependencies: + color-convert "^2.0.0" + +anymatch@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.0.2.tgz#ddb3a8495d44875423af7b919aace11e91732a41" + integrity sha512-rUe9SxpRQlVg4EM8It7JMNWWYHAirTPpbTuvaSKybb5IejNgWB3PGBBX9rrPKDx2pM/p3Wh+7+ASaWRyyAbxmQ== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +append-transform@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" + integrity sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw== + dependencies: + default-require-extensions "^2.0.0" + +archy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" + integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA= + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-filter@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" + integrity sha1-fajPLiZijtcygDWB/SH2fKzS7uw= + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-from@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195" + integrity sha1-z+nYwmYoudxa7MYqn12PHzUsEZU= + +array-map@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" + integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI= + +array-reduce@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" + integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys= + +array-union@^1.0.1, array-union@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= + dependencies: + array-uniq "^1.0.1" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= + +array-uniq@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-2.1.0.tgz#46603d5e28e79bfd02b046fcc1d77c6820bd8e98" + integrity sha512-bdHxtev7FN6+MXI1YFW0Q8mQ8dTJc2S8AMfju+ZR77pbg2yAdVyDlwkaUI7Har0LyOMRFPHrJ9lYdyjZZswdlQ== + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +arrify@^1.0.0, arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= + +arrify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" + integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== + +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +async-each@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" + integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== + +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +ava@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ava/-/ava-2.0.0.tgz#265f9a094f83d0a78c05654e37302645d59ca1fa" + integrity sha512-tOfO3yQhKiSECIjST8Xi99l7Bja9EG5hgZFKc92xNZh/6pnct97vWDKENyATBvZIXpdCClSMtGgOX2UaGq+OJA== + dependencies: + "@ava/babel-preset-stage-4" "^3.0.0" + "@ava/babel-preset-transform-test-files" "^5.0.0" + "@babel/core" "^7.4.5" + "@babel/generator" "^7.4.4" + "@babel/plugin-syntax-async-generators" "^7.2.0" + "@babel/plugin-syntax-object-rest-spread" "^7.2.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + "@concordance/react" "^2.0.0" + ansi-escapes "^4.1.0" + ansi-styles "^4.0.0" + arr-flatten "^1.1.0" + array-union "^2.1.0" + array-uniq "^2.1.0" + arrify "^2.0.1" + bluebird "^3.5.5" + chalk "^2.4.2" + chokidar "^3.0.0" + chunkd "^1.0.0" + ci-parallel-vars "^1.0.0" + clean-stack "^2.1.0" + clean-yaml-object "^0.1.0" + cli-cursor "^3.0.0" + cli-truncate "^1.1.0" + code-excerpt "^2.1.1" + common-path-prefix "^1.0.0" + concordance "^4.0.0" + convert-source-map "^1.6.0" + currently-unhandled "^0.4.1" + debug "^4.1.1" + del "^4.1.1" + dot-prop "^5.0.0" + emittery "^0.4.1" + empower-core "^1.2.0" + equal-length "^1.0.0" + escape-string-regexp "^2.0.0" + esm "^3.2.25" + figures "^3.0.0" + find-up "^4.0.0" + get-port "^5.0.0" + globby "^9.2.0" + ignore-by-default "^1.0.0" + import-local "^2.0.0" + indent-string "^4.0.0" + is-ci "^2.0.0" + is-error "^2.2.2" + is-observable "^2.0.0" + is-plain-object "^3.0.0" + is-promise "^2.1.0" + lodash "^4.17.11" + loud-rejection "^2.1.0" + make-dir "^3.0.0" + matcher "^2.0.0" + md5-hex "^3.0.0" + meow "^5.0.0" + micromatch "^4.0.2" + ms "^2.1.1" + observable-to-promise "^1.0.0" + ora "^3.4.0" + package-hash "^4.0.0" + pkg-conf "^3.1.0" + plur "^3.1.1" + pretty-ms "^5.0.0" + require-precompiled "^0.1.0" + resolve-cwd "^3.0.0" + slash "^3.0.0" + source-map-support "^0.5.12" + stack-utils "^1.0.2" + strip-ansi "^5.2.0" + strip-bom-buf "^2.0.0" + supertap "^1.0.0" + supports-color "^6.1.0" + trim-off-newlines "^1.0.1" + trim-right "^1.0.1" + unique-temp-dir "^1.0.0" + update-notifier "^3.0.0" + write-file-atomic "^3.0.0" + +axios@^0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8" + integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ== + dependencies: + follow-redirects "1.5.10" + is-buffer "^2.0.2" + +babel-plugin-espower@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/babel-plugin-espower/-/babel-plugin-espower-3.0.1.tgz#180db17126f88e754105b8b5216d21e520a6bd4e" + integrity sha512-Ms49U7VIAtQ/TtcqRbD6UBmJBUCSxiC3+zPc+eGqxKUIFO1lTshyEDRUjhoAbd2rWfwYf3cZ62oXozrd8W6J0A== + dependencies: + "@babel/generator" "^7.0.0" + "@babel/parser" "^7.0.0" + call-matcher "^1.0.0" + core-js "^2.0.0" + espower-location-detector "^1.0.0" + espurify "^1.6.0" + estraverse "^4.1.1" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base64-js@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1" + integrity sha1-o5mS1yNYSBGYK+XikLtqU9hnAPE= + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +big-integer@^1.6.7: + version "1.6.43" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.43.tgz#8ac15bf13e93e509500859061233e19d8d0d99d1" + integrity sha512-9dULc9jsKmXl0Aeunug8wbF+58n+hQoFjqClN7WeZwGLh0XJUWyJJ9Ee+Ep+Ql/J9fRsTVaeThp8MhiCCrY0Jg== + +binary-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c" + integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow== + +bluebird@^3.5.5: + version "3.5.5" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.5.tgz#a8d0afd73251effbbd5fe384a77d73003c17a71f" + integrity sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w== + +boxen@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-3.2.0.tgz#fbdff0de93636ab4450886b6ff45b92d098f45eb" + integrity sha512-cU4J/+NodM3IHdSL2yN8bqYqnmlBTidDR4RC7nJs61ZmtGz8VZzM3HLQX0zY5mrSmPtR3xWwsq2jOUQqFZN8+A== + dependencies: + ansi-align "^3.0.0" + camelcase "^5.3.1" + chalk "^2.4.2" + cli-boxes "^2.2.0" + string-width "^3.0.0" + term-size "^1.2.0" + type-fest "^0.3.0" + widest-line "^2.0.0" + +bplist-parser@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.1.1.tgz#d60d5dcc20cba6dc7e1f299b35d3e1f95dafbae6" + integrity sha1-1g1dzCDLptx+HymbNdPh+V2vuuY= + dependencies: + big-integer "^1.6.7" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +braces@^3.0.1, braces@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +builtin-modules@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +cacheable-request@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.0.0.tgz#4a1727414e02ac4af82560c4da1b61daa3fa2b63" + integrity sha512-2N7AmszH/WPPpl5Z3XMw1HAP+8d+xugnKQAeKvxFZ/04dbT/CAznqwbl+7eSr3HkwdepNwtb2yx3CAMQWvG01Q== + dependencies: + clone-response "^1.0.2" + get-stream "^4.0.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^1.0.1" + normalize-url "^3.1.0" + responselike "^1.0.2" + +caching-transform@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-3.0.2.tgz#601d46b91eca87687a281e71cef99791b0efca70" + integrity sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w== + dependencies: + hasha "^3.0.0" + make-dir "^2.0.0" + package-hash "^3.0.0" + write-file-atomic "^2.4.2" + +call-matcher@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/call-matcher/-/call-matcher-1.1.0.tgz#23b2c1bc7a8394c8be28609d77ddbd5786680432" + integrity sha512-IoQLeNwwf9KTNbtSA7aEBb1yfDbdnzwjCetjkC8io5oGeOmK2CBNdg0xr+tadRYKO0p7uQyZzvon0kXlZbvGrw== + dependencies: + core-js "^2.0.0" + deep-equal "^1.0.0" + espurify "^1.6.0" + estraverse "^4.0.0" + +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity sha1-JtII6onje1y95gJQoV8DHBak1ms= + +call-signature@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/call-signature/-/call-signature-0.0.2.tgz#a84abc825a55ef4cb2b028bd74e205a65b9a4996" + integrity sha1-qEq8glpV70yysCi9dOIFpluaSZY= + +camelcase-keys@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" + integrity sha1-oqpfsa9oh1glnDLBQUJteJI7m3c= + dependencies: + camelcase "^4.1.0" + map-obj "^2.0.0" + quick-lru "^1.0.0" + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= + +camelcase@^5.0.0, camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +chai@^4.1.2: + version "4.2.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" + integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.2" + deep-eql "^3.0.1" + get-func-name "^2.0.0" + pathval "^1.1.0" + type-detect "^4.0.5" + +chalk@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +check-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= + +chokidar@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.0.1.tgz#98fe9aa476c55d9aea7841d6325ffdb30e95b40c" + integrity sha512-2ww34sJWehnbpV0Q4k4V5Hh7juo7po6z7LUWkcIQnSGN1lHOL8GGtLtfwabKvLFQw/hbSUQ0u6V7OgGYgBzlkQ== + dependencies: + anymatch "^3.0.1" + async-each "^1.0.3" + braces "^3.0.2" + glob-parent "^5.0.0" + is-binary-path "^2.1.0" + is-glob "^4.0.1" + normalize-path "^3.0.0" + readdirp "^3.0.2" + optionalDependencies: + fsevents "^2.0.6" + +chunkd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/chunkd/-/chunkd-1.0.0.tgz#4ead4a3704bcce510c4bb4d4a8be30c557836dd1" + integrity sha512-xx3Pb5VF9QaqCotolyZ1ywFBgyuJmu6+9dLiqBxgelEse9Xsr3yUlpoX3O4Oh11M00GT2kYMsRByTKIMJW2Lkg== + +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +ci-parallel-vars@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ci-parallel-vars/-/ci-parallel-vars-1.0.0.tgz#af97729ed1c7381911ca37bcea263d62638701b3" + integrity sha512-u6dx20FBXm+apMi+5x7UVm6EH7BL1gc4XrcnQewjcB7HWRcor/V5qWc3RG2HwpgDJ26gIi2DSEu3B7sXynAw/g== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clean-stack@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.1.0.tgz#9e7fec7f3f8340a2ab4f127c80273085e8fbbdd0" + integrity sha512-uQWrpRm+iZZUCAp7ZZJQbd4Za9I3AjR/3YTjmcnAtkauaIm/T5CT6U8zVI6e60T6OANqBFAzuR9/HB3NzuZCRA== + +clean-yaml-object@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz#63fb110dc2ce1a84dc21f6d9334876d010ae8b68" + integrity sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g= + +cli-boxes@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.0.tgz#538ecae8f9c6ca508e3c3c95b453fe93cb4c168d" + integrity sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w== + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-cursor@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.0.0.tgz#f6cc68b8ae372a18894e59fbf2ae3bd659731c15" + integrity sha512-m7avcYLWHHQVU+cFxu301q3kKZJlcZcKXQSL9kffYnIvRNtqX+a7gJKXqOKusHoKXr4oquSgiMlAo1R0dDkSZA== + dependencies: + restore-cursor "^2.0.0" + +cli-spinners@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.1.0.tgz#22c34b4d51f573240885b201efda4e4ec9fff3c7" + integrity sha512-8B00fJOEh1HPrx4fo5eW16XmE1PcL1tGpGrxy63CXGP9nHdPBN63X75hA1zhvQuhVztJWLqV58Roj2qlNM7cAA== + +cli-truncate@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-1.1.0.tgz#2b2dfd83c53cfd3572b87fc4d430a808afb04086" + integrity sha512-bAtZo0u82gCfaAGfSNxUdTI9mNyza7D8w4CVCcaOsy7sgwDzvx6ekr6cuWJqY3UGzgnQ1+4wgENup5eIhgxEYA== + dependencies: + slice-ansi "^1.0.0" + string-width "^2.0.0" + +cliui@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" + integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== + dependencies: + string-width "^3.1.0" + strip-ansi "^5.2.0" + wrap-ansi "^5.1.0" + +clone-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + +code-excerpt@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/code-excerpt/-/code-excerpt-2.1.1.tgz#5fe3057bfbb71a5f300f659ef2cc0a47651ba77c" + integrity sha512-tJLhH3EpFm/1x7heIW0hemXJTUU5EWl2V0EIX558jp05Mt1U6DVryCgkp3l37cxqs+DNbNgxG43SkwJXpQ14Jw== + dependencies: + convert-to-spaces "^1.0.1" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.0.tgz#9851ac61cc0d3898a8a3088650d5bf447bf69d97" + integrity sha512-hzTicsCJIHdxih9+2aLR1tNGZX5qSJGRHDPVwSY26tVrEf55XNajLOBWz2UuWSIergszA09/bqnOiHyqx9fxQg== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +commander@^2.12.1, commander@~2.20.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" + integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== + +common-path-prefix@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-1.0.0.tgz#cd52f6f0712e0baab97d6f9732874f22f47752c0" + integrity sha1-zVL28HEuC6q5fW+XModPIvR3UsA= + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs= + +component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concordance@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/concordance/-/concordance-4.0.0.tgz#5932fdee397d129bdbc3a1885fbe69839b1b7e15" + integrity sha512-l0RFuB8RLfCS0Pt2Id39/oCPykE01pyxgAFypWTlaGRgvLkZrtczZ8atEHpTeEIW+zYWXTBuA9cCSeEOScxReQ== + dependencies: + date-time "^2.1.0" + esutils "^2.0.2" + fast-diff "^1.1.2" + js-string-escape "^1.0.1" + lodash.clonedeep "^4.5.0" + lodash.flattendeep "^4.4.0" + lodash.islength "^4.0.1" + lodash.merge "^4.6.1" + md5-hex "^2.0.0" + semver "^5.5.1" + well-known-symbols "^2.0.0" + +configstore@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/configstore/-/configstore-4.0.0.tgz#5933311e95d3687efb592c528b922d9262d227e7" + integrity sha512-CmquAXFBocrzaSM8mtGPMM/HiWmyIpr4CcJl/rgY2uCObZ/S7cKU0silxslqJejl+t/T9HS8E0PUNQD81JGUEQ== + dependencies: + dot-prop "^4.1.0" + graceful-fs "^4.1.2" + make-dir "^1.0.0" + unique-string "^1.0.0" + write-file-atomic "^2.0.0" + xdg-basedir "^3.0.0" + +convert-source-map@^1.1.0, convert-source-map@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== + dependencies: + safe-buffer "~5.1.1" + +convert-to-spaces@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz#7e3e48bbe6d997b1417ddca2868204b4d3d85715" + integrity sha1-fj5Iu+bZl7FBfdyihoIEtNPYVxU= + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-js@^2.0.0: + version "2.6.9" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" + integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A== + +cp-file@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-6.2.0.tgz#40d5ea4a1def2a9acdd07ba5c0b0246ef73dc10d" + integrity sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA== + dependencies: + graceful-fs "^4.1.2" + make-dir "^2.0.0" + nested-error-stacks "^2.0.0" + pify "^4.0.1" + safe-buffer "^5.0.1" + +cross-spawn@^4: + version "4.0.2" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" + integrity sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE= + dependencies: + lru-cache "^4.0.1" + which "^1.2.9" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +crypto-random-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" + integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +date-time@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/date-time/-/date-time-2.1.0.tgz#0286d1b4c769633b3ca13e1e62558d2dbdc2eba2" + integrity sha512-/9+C44X7lot0IeiyfgJmETtRMhBidBYM2QFFIkGa0U1k+hSyY87Nw7PY3eDqpvCBm7I3WCSfPeZskW/YYq6m4g== + dependencies: + time-zone "^1.0.0" + +debug@=3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@^4.1.0, debug@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +decamelize-keys@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.0.tgz#d171a87933252807eb3cb61dc1c1445d078df2d9" + integrity sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk= + dependencies: + decamelize "^1.1.0" + map-obj "^1.0.0" + +decamelize@^1.1.0, decamelize@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +deep-eql@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== + dependencies: + type-detect "^4.0.0" + +deep-equal@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +default-require-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" + integrity sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc= + dependencies: + strip-bom "^3.0.0" + +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + dependencies: + clone "^1.0.2" + +defer-to-connect@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.0.2.tgz#4bae758a314b034ae33902b5aac25a8dd6a8633e" + integrity sha512-k09hcQcTDY+cwgiwa6PYKLm3jlagNzQ+RSvhjzESOGOx+MNOuXkxTfEvPrO1IOQ81tArCFYQgi631clB70RpQw== + +define-properties@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +del-cli@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/del-cli/-/del-cli-2.0.0.tgz#e9a778398863c26796d85409b9891f98b0122cd1" + integrity sha512-IREsO6mjSTxxvWLKMMUi1G0izhqEBx7qeDkOJ6H3+TJl8gQl6x5C5hK4Sm1GJ51KodUMR6O7HuIhnF24Edua3g== + dependencies: + del "^4.1.1" + meow "^5.0.0" + +del@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + integrity sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag= + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + +del@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" + integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== + dependencies: + "@types/glob" "^7.1.1" + globby "^6.1.0" + is-path-cwd "^2.0.0" + is-path-in-cwd "^2.0.0" + p-map "^2.0.0" + pify "^4.0.1" + rimraf "^2.6.3" + +delay@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/delay/-/delay-4.2.0.tgz#3f6c39dbd28aef50355e670fecee050ef01242ce" + integrity sha512-EBX+pZE4qSowGAMr6M0cLiPRQu2Kus/qTNLO7c+EoXpTPJH9ApFdHX+cQU1WsSHXgwhLyidfZ5Hxuq6ctWhSdw== + +diff@^3.2.0, diff@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + +dir-glob@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" + integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== + dependencies: + path-type "^3.0.0" + +dot-prop@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" + integrity sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ== + dependencies: + is-obj "^1.0.0" + +dot-prop@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.0.0.tgz#64b7968af349c3a9f966aa12658dbd5829f6b953" + integrity sha512-RTmaF2jx3nOBO2GvtFqjnDLycjFUMqt+2pwRx7JVYa81lDauoj9aNkyrJI2ikR58FbBIchiIlRiGG+muLJ4oHQ== + dependencies: + is-obj "^1.0.0" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= + +emittery@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.4.1.tgz#abe9d3297389ba424ac87e53d1c701962ce7433d" + integrity sha512-r4eRSeStEGf6M5SKdrQhhLK5bOwOBxQhIE3YSTnZE3GpKiLfnnhE+tPtrJE79+eDJgm39BM6LSoI8SCx4HbwlQ== + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +empower-core@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/empower-core/-/empower-core-1.2.0.tgz#ce3fb2484d5187fa29c23fba8344b0b2fdf5601c" + integrity sha512-g6+K6Geyc1o6FdXs9HwrXleCFan7d66G5xSCfSF7x1mJDCes6t0om9lFQG3zOrzh3Bkb/45N0cZ5Gqsf7YrzGQ== + dependencies: + call-signature "0.0.2" + core-js "^2.0.0" + +end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + +equal-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/equal-length/-/equal-length-1.0.1.tgz#21ca112d48ab24b4e1e7ffc0e5339d31fdfc274c" + integrity sha1-IcoRLUirJLTh5//A5TOdMf38J0w= + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +es-abstract@^1.4.3: + version "1.13.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" + integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== + dependencies: + es-to-primitive "^1.2.0" + function-bind "^1.1.1" + has "^1.0.3" + is-callable "^1.1.4" + is-regex "^1.0.4" + object-keys "^1.0.12" + +es-to-primitive@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es6-error@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" + integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +esm@^3.2.25: + version "3.2.25" + resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" + integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== + +espower-location-detector@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/espower-location-detector/-/espower-location-detector-1.0.0.tgz#a17b7ecc59d30e179e2bef73fb4137704cb331b5" + integrity sha1-oXt+zFnTDheeK+9z+0E3cEyzMbU= + dependencies: + is-url "^1.2.1" + path-is-absolute "^1.0.0" + source-map "^0.5.0" + xtend "^4.0.0" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +espurify@^1.6.0: + version "1.8.1" + resolved "https://registry.yarnpkg.com/espurify/-/espurify-1.8.1.tgz#5746c6c1ab42d302de10bd1d5bf7f0e8c0515056" + integrity sha512-ZDko6eY/o+D/gHCWyHTU85mKDgYcS4FJj7S+YD6WIInm7GQ6AnOjmcL4+buFV/JOztVLELi/7MmuGU5NHta0Mg== + dependencies: + core-js "^2.0.0" + +estraverse@^4.0.0, estraverse@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs= + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-glob@^2.2.6: + version "2.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" + integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + +figures@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.0.0.tgz#756275c964646163cc6f9197c7a0295dbfd04de9" + integrity sha512-HKri+WoWoUgr83pehn/SIgLOMZ9nAWC6dcGj26RY2R4F50u4+RTUz0RCrUlOV3nKRAICW1UGzyb+kcX2qK1S/g== + dependencies: + escape-string-regexp "^1.0.5" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= + dependencies: + locate-path "^2.0.0" + +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + +find-up@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.0.0.tgz#c367f8024de92efb75f2d4906536d24682065c3a" + integrity sha512-zoH7ZWPkRdgwYCDVoQTzqjG8JSPANhtvLhh4KVUHyKnaUJJrNeFmWIkTcNuJmR3GLMEmGYEf2S2bjgx26JTF+Q== + dependencies: + locate-path "^5.0.0" + +follow-redirects@1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +foreground-child@^1.5.6: + version "1.5.6" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-1.5.6.tgz#4fd71ad2dfde96789b980a5c0a295937cb2f5ce9" + integrity sha1-T9ca0t/elnibmApcCilZN8svXOk= + dependencies: + cross-spawn "^4" + signal-exit "^3.0.0" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fs-extra@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.0.1.tgz#90294081f978b1f182f347a440a209154344285b" + integrity sha512-W+XLrggcDzlle47X/XnS7FXrXu9sDo+Ze9zpndeBxdgv88FHLm1HtmkhEwavruS6koanBjp098rUpHs65EmG7A== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^2.0.6: + version "2.0.7" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.0.7.tgz#382c9b443c6cbac4c57187cdda23aa3bf1ccfc2a" + integrity sha512-a7YT0SV3RB+DjYcppwVDLtn13UQnmg0SWZS7ezZD0UjnLwXmy8Zm21GMVGLaFGimIqcvyMQaOJBrop8MyOp1kQ== + +function-bind@^1.0.2, function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +fuse.js@^3.4.4: + version "3.4.5" + resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-3.4.5.tgz#8954fb43f9729bd5dbcb8c08f251db552595a7a6" + integrity sha512-s9PGTaQIkT69HaeoTVjwGsLfb8V8ScJLx5XGFcKHg0MqLUH/UZ4EKOtqtXX9k7AFqCGxD1aJmYb8Q5VYDibVRQ== + +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= + +get-port@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.0.0.tgz#aa22b6b86fd926dd7884de3e23332c9f70c031a6" + integrity sha512-imzMU0FjsZqNa6BqOjbbW6w5BivHIuQKopjpPqcnx0AVHJQKCxK1O+Ab3OrVXhrekqfVMjwA9ZYu062R+KcIsQ== + dependencies: + type-fest "^0.3.0" + +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-stream@^4.0.0, get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-parent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.0.0.tgz#1dc99f0f39b006d3e92c2c284068382f0c20e954" + integrity sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg== + dependencies: + is-glob "^4.0.1" + +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= + +glob@^7.0.3, glob@^7.1.1, glob@^7.1.3: + version "7.1.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" + integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-dirs@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-0.1.1.tgz#b319c0dd4607f353f3be9cca4c72fc148c49f445" + integrity sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU= + dependencies: + ini "^1.3.4" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + integrity sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0= + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +globby@^9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" + integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^1.0.2" + dir-glob "^2.2.2" + fast-glob "^2.2.6" + glob "^7.1.3" + ignore "^4.0.3" + pify "^4.0.1" + slash "^2.0.0" + +got@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.1.15" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== + +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + integrity sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE= + +handlebars@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.1.2.tgz#b6b37c1ced0306b221e094fc7aca3ec23b131b67" + integrity sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw== + dependencies: + neo-async "^2.6.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has-yarn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/has-yarn/-/has-yarn-2.1.0.tgz#137e11354a7b5bf11aa5cb649cf0c6f3ff2b2e77" + integrity sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw== + +has@^1.0.1, has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +hasha@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/hasha/-/hasha-3.0.0.tgz#52a32fab8569d41ca69a61ff1a214f8eb7c8bd39" + integrity sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk= + dependencies: + is-stream "^1.0.1" + +hasha@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/hasha/-/hasha-5.0.0.tgz#fdc3785caea03df29535fc8adb512c3d3a709004" + integrity sha512-PqWdhnQhq6tqD32hZv+l1e5mJHNSudjnaAzgAHfkGiU0ABN6lmbZF8abJIulQHbZ7oiHhP8yL6O910ICMc+5pw== + dependencies: + is-stream "^1.1.0" + type-fest "^0.3.0" + +hosted-git-info@^2.1.4: + version "2.7.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== + +http-cache-semantics@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz#495704773277eeef6e43f9ab2c2c7d259dda25c5" + integrity sha512-TcIMG3qeVLgDr1TEd2XvHaTnMPwYQUQMIBLy+5pLSDKYFc7UIqj39w8EGzZkaxoLv/l2K8HaI0t5AVA+YYgUew== + +ignore-by-default@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= + +ignore@^4.0.3: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +import-lazy@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" + integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM= + +import-local@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" + integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== + dependencies: + pkg-dir "^3.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +indent-string@^3.0.0, indent-string@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + integrity sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok= + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@^1.3.4, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + +irregular-plurals@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-2.0.0.tgz#39d40f05b00f656d0b7fa471230dd3b714af2872" + integrity sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-binary-path@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-buffer@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" + integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw== + +is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== + +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-docker@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-1.1.0.tgz#f04374d4eee5310e9a8e113bf1495411e46176a1" + integrity sha1-8EN01O7lMQ6ajhE78UlUEeRhdqE= + +is-error@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/is-error/-/is-error-2.2.2.tgz#c10ade187b3c93510c5470a5567833ee25649843" + integrity sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg== + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0, is-glob@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-installed-globally@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" + integrity sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA= + dependencies: + global-dirs "^0.1.0" + is-path-inside "^1.0.0" + +is-npm@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-3.0.0.tgz#ec9147bfb629c43f494cf67936a961edec7e8053" + integrity sha512-wsigDr1Kkschp2opC4G3yA6r9EgVA6NjRpWzIi9axXqeIaAATPRJc4uLujXe3Nd9uO8KoDyA4MD6aZSeXTADhA== + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" + integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= + +is-observable@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-2.0.0.tgz#327af1e8cdea9cd717f95911b87c5d34301721a6" + integrity sha512-fhBZv3eFKUbyHXZ1oHujdo2tZ+CNbdpdzzlENgCGZUC8keoGxUew2jYFLYcUB4qo7LDD03o4KK11m/QYD7kEjg== + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= + +is-path-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.1.0.tgz#2e0c7e463ff5b7a0eb60852d851a6809347a124c" + integrity sha512-Sc5j3/YnM8tDeyCsVeKlm/0p95075DyLmDEIkSgQ7mXkrOX+uTCtmQFm0CYzVyJwcCCmO3k8qfJt17SxQwB5Zw== + +is-path-in-cwd@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" + integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ== + dependencies: + is-path-inside "^1.0.0" + +is-path-in-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" + integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ== + dependencies: + is-path-inside "^2.1.0" + +is-path-inside@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" + integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= + dependencies: + path-is-inside "^1.0.1" + +is-path-inside@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" + integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== + dependencies: + path-is-inside "^1.0.2" + +is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-plain-object@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-3.0.0.tgz#47bfc5da1b5d50d64110806c199359482e75a928" + integrity sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg== + dependencies: + isobject "^4.0.0" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= + dependencies: + has "^1.0.1" + +is-root@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-root/-/is-root-1.0.0.tgz#07b6c233bc394cd9d02ba15c966bd6660d6342d5" + integrity sha1-B7bCM7w5TNnQK6FclmvWZg1jQtU= + +is-stream@^1.0.1, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= + +is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== + dependencies: + has-symbols "^1.0.0" + +is-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + +is-url@^1.2.1: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" + integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== + +is-utf8@^0.2.0, is-utf8@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + +is-yarn-global@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" + integrity sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw== + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +isobject@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" + integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== + +istanbul-lib-coverage@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" + integrity sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA== + +istanbul-lib-hook@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz#c95695f383d4f8f60df1f04252a9550e15b5b133" + integrity sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA== + dependencies: + append-transform "^1.0.0" + +istanbul-lib-instrument@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz#a5f63d91f0bbc0c3e479ef4c5de027335ec6d630" + integrity sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA== + dependencies: + "@babel/generator" "^7.4.0" + "@babel/parser" "^7.4.3" + "@babel/template" "^7.4.0" + "@babel/traverse" "^7.4.3" + "@babel/types" "^7.4.0" + istanbul-lib-coverage "^2.0.5" + semver "^6.0.0" + +istanbul-lib-report@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz#5a8113cd746d43c4889eba36ab10e7d50c9b4f33" + integrity sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ== + dependencies: + istanbul-lib-coverage "^2.0.5" + make-dir "^2.1.0" + supports-color "^6.1.0" + +istanbul-lib-source-maps@^3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz#284997c48211752ec486253da97e3879defba8c8" + integrity sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^2.0.5" + make-dir "^2.1.0" + rimraf "^2.6.3" + source-map "^0.6.1" + +istanbul-reports@^2.2.4: + version "2.2.6" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-2.2.6.tgz#7b4f2660d82b29303a8fe6091f8ca4bf058da1af" + integrity sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA== + dependencies: + handlebars "^4.1.2" + +js-string-escape@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" + integrity sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8= + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.10.0, js-yaml@^3.13.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0= + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= + +json-parse-better-errors@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + +json-stringify-safe@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= + +json5@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" + integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== + dependencies: + minimist "^1.2.0" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= + +just-extend@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.0.2.tgz#f3f47f7dfca0f989c55410a7ebc8854b07108afc" + integrity sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw== + +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + +latest-version@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" + integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== + dependencies: + package-json "^6.3.0" + +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha1-L19Fq5HjMhYjT9U62rZo607AmTs= + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +load-json-file@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-5.3.0.tgz#4d3c1e01fa1c03ea78a60ac7af932c9ce53403f3" + integrity sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw== + dependencies: + graceful-fs "^4.1.15" + parse-json "^4.0.0" + pify "^4.0.1" + strip-bom "^3.0.0" + type-fest "^0.3.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= + +lodash.flattendeep@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" + integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI= + +lodash.islength@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.islength/-/lodash.islength-4.0.1.tgz#4e9868d452575d750affd358c979543dc20ed577" + integrity sha1-Tpho1FJXXXUK/9NYyXlUPcIO1Xc= + +lodash.merge@^4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.1.tgz#adc25d9cb99b9391c59624f379fbba60d7111d54" + integrity sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ== + +lodash@^4.17.11, lodash@^4.17.5: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== + +log-symbols@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== + dependencies: + chalk "^2.0.1" + +lolex@^2.3.2: + version "2.7.5" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.7.5.tgz#113001d56bfc7e02d56e36291cc5c413d1aa0733" + integrity sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q== + +lolex@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-4.0.1.tgz#4a99c2251579d693c6a083446dae0e5c3844d3fa" + integrity sha512-UHuOBZ5jjsKuzbB/gRNNW8Vg8f00Emgskdq2kvZxgBJCS0aqquAuXai/SkWORlKeZEiNQWZjFZOqIUcH9LqKCw== + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +loud-rejection@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-2.1.0.tgz#4020547ddbc39ed711c8434326df9fc7d2395355" + integrity sha512-g/6MQxUXYHeVqZ4PGpPL1fS1fOvlXoi7bay0pizmjAd/3JhyXwxzwrnr74yzdmhuerlslbRJ3x7IOXzFz0cE5w== + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.2" + +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lru-cache@^4.0.1: + version "4.1.5" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +make-dir@^1.0.0, make-dir@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + +make-dir@^2.0.0, make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + +make-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.0.0.tgz#1b5f39f6b9270ed33f9f054c5c0f84304989f801" + integrity sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw== + dependencies: + semver "^6.0.0" + +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-2.0.0.tgz#a65cd29087a92598b8791257a523e021222ac1f9" + integrity sha1-plzSkIepJZi4eRJXpSPgISIqwfk= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +matcher@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/matcher/-/matcher-2.0.0.tgz#85fe38d97670dbd2a46590cf099401e2ffb4755c" + integrity sha512-nlmfSlgHBFx36j/Pl/KQPbIaqE8Zf0TqmSMjsuddHDg6PMSVgmyW9HpkLs0o0M1n2GIZ/S2BZBLIww/xjhiGng== + dependencies: + escape-string-regexp "^2.0.0" + +md5-hex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-2.0.0.tgz#d0588e9f1c74954492ecd24ac0ac6ce997d92e33" + integrity sha1-0FiOnxx0lUSS7NJKwKxs6ZfZLjM= + dependencies: + md5-o-matic "^0.1.1" + +md5-hex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/md5-hex/-/md5-hex-3.0.0.tgz#96cf5c62cedea41e04124b9473ef7481db6de5fb" + integrity sha512-uA+EX5IV1r5lKBJecwTSec3k6xl4ziBUZihRiOpOHCeHjKA0ai6+eImamXQy/cI3Qep5mQgFTeJld9tcwdBNFw== + dependencies: + md5-o-matic "^0.1.1" + +md5-o-matic@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/md5-o-matic/-/md5-o-matic-0.1.1.tgz#822bccd65e117c514fab176b25945d54100a03c3" + integrity sha1-givM1l4RfFFPqxdrJZRdVBAKA8M= + +mem@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== + dependencies: + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" + +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + integrity sha1-htcJCzDORV1j+64S3aUaR93K+bI= + +meow@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4" + integrity sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig== + dependencies: + camelcase-keys "^4.0.0" + decamelize-keys "^1.0.0" + loud-rejection "^1.0.0" + minimist-options "^3.0.1" + normalize-package-data "^2.3.4" + read-pkg-up "^3.0.0" + redent "^2.0.0" + trim-newlines "^2.0.0" + yargs-parser "^10.0.0" + +merge-source-map@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" + integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== + dependencies: + source-map "^0.6.1" + +merge2@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.3.tgz#7ee99dbd69bb6481689253f018488a1b902b0ed5" + integrity sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA== + +micromatch@^3.1.10: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +micromatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" + integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== + dependencies: + braces "^3.0.1" + picomatch "^2.0.5" + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +mimic-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^1.0.0, mimic-response@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist-options@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-3.0.2.tgz#fba4c8191339e13ecf4d61beb03f070103f3d954" + integrity sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ== + dependencies: + arrify "^1.0.1" + is-plain-obj "^1.1.0" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@^0.5.0, mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +mockdate@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/mockdate/-/mockdate-2.0.2.tgz#5ae0c0eaf8fe23e009cd01f9889b42c4f634af12" + integrity sha1-WuDA6vj+I+AJzQH5iJtCxPY0rxI= + +moment@^2.17.1, moment@^2.24.0: + version "2.24.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" + integrity sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg== + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +ms@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +neo-async@^2.6.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" + integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== + +nested-error-stacks@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz#0fbdcf3e13fe4994781280524f8b96b0cdff9c61" + integrity sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug== + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +nise@^1.4.10: + version "1.4.10" + resolved "https://registry.yarnpkg.com/nise/-/nise-1.4.10.tgz#ae46a09a26436fae91a38a60919356ae6db143b6" + integrity sha512-sa0RRbj53dovjc7wombHmVli9ZihXbXCQ2uH3TNm03DyvOSIQbxg+pbqDKrk2oxMK1rtLGVlKxcB9rrc6X5YjA== + dependencies: + "@sinonjs/formatio" "^3.1.0" + "@sinonjs/text-encoding" "^0.7.1" + just-extend "^4.0.2" + lolex "^2.3.2" + path-to-regexp "^1.7.0" + +nock@^10.0.6: + version "10.0.6" + resolved "https://registry.yarnpkg.com/nock/-/nock-10.0.6.tgz#e6d90ee7a68b8cfc2ab7f6127e7d99aa7d13d111" + integrity sha512-b47OWj1qf/LqSQYnmokNWM8D88KvUl2y7jT0567NB3ZBAZFz2bWp2PC81Xn7u8F2/vJxzkzNZybnemeFa7AZ2w== + dependencies: + chai "^4.1.2" + debug "^4.1.0" + deep-equal "^1.0.0" + json-stringify-safe "^5.0.1" + lodash "^4.17.5" + mkdirp "^0.5.0" + propagate "^1.0.0" + qs "^6.5.1" + semver "^5.5.0" + +node-notifier@^5.0.2: + version "5.4.0" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.0.tgz#7b455fdce9f7de0c63538297354f3db468426e6a" + integrity sha512-SUDEb+o71XR5lXSTyivXd9J7fCloE3SyP4lSgt3lU2oSANiox+SxlNRGPjDKrwU1YN3ix2KN/VGGCg0t01rttQ== + dependencies: + growly "^1.3.0" + is-wsl "^1.1.0" + semver "^5.5.0" + shellwords "^0.1.1" + which "^1.3.0" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-url@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" + integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== + +npm-run-all@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" + integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ== + dependencies: + ansi-styles "^3.2.1" + chalk "^2.4.1" + cross-spawn "^6.0.5" + memorystream "^0.3.1" + minimatch "^3.0.4" + pidtree "^0.3.0" + read-pkg "^3.0.0" + shell-quote "^1.6.1" + string.prototype.padend "^3.0.0" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8= + dependencies: + path-key "^2.0.0" + +nyc@^14.1.1: + version "14.1.1" + resolved "https://registry.yarnpkg.com/nyc/-/nyc-14.1.1.tgz#151d64a6a9f9f5908a1b73233931e4a0a3075eeb" + integrity sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw== + dependencies: + archy "^1.0.0" + caching-transform "^3.0.2" + convert-source-map "^1.6.0" + cp-file "^6.2.0" + find-cache-dir "^2.1.0" + find-up "^3.0.0" + foreground-child "^1.5.6" + glob "^7.1.3" + istanbul-lib-coverage "^2.0.5" + istanbul-lib-hook "^2.0.7" + istanbul-lib-instrument "^3.3.0" + istanbul-lib-report "^2.0.8" + istanbul-lib-source-maps "^3.0.6" + istanbul-reports "^2.2.4" + js-yaml "^3.13.1" + make-dir "^2.1.0" + merge-source-map "^1.1.0" + resolve-from "^4.0.0" + rimraf "^2.6.3" + signal-exit "^3.0.2" + spawn-wrap "^1.4.2" + test-exclude "^5.2.3" + uuid "^3.3.2" + yargs "^13.2.2" + yargs-parser "^13.0.0" + +object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-keys@^1.0.12: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +observable-to-promise@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/observable-to-promise/-/observable-to-promise-1.0.0.tgz#37e136f16a15385ac063411ada0e1202bfff58f4" + integrity sha512-cqnGUrNsE6vdVDTPAX9/WeVzwy/z37vdxupdQXU8vgTXRFH72KCZiZga8aca2ulRPIeem8W3vW9rQHBwfIl2WA== + dependencies: + is-observable "^2.0.0" + symbol-observable "^1.0.4" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +ora@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/ora/-/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318" + integrity sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg== + dependencies: + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-spinners "^2.0.0" + log-symbols "^2.2.0" + strip-ansi "^5.2.0" + wcwidth "^1.0.1" + +os-homedir@^1.0.0, os-homedir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-locale@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== + dependencies: + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" + +os-tmpdir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= + +p-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + +p-limit@^2.0.0, p-limit@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2" + integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ== + dependencies: + p-try "^2.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= + dependencies: + p-limit "^1.1.0" + +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-map@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +package-hash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-3.0.0.tgz#50183f2d36c9e3e528ea0a8605dff57ce976f88e" + integrity sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA== + dependencies: + graceful-fs "^4.1.15" + hasha "^3.0.0" + lodash.flattendeep "^4.4.0" + release-zalgo "^1.0.0" + +package-hash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-4.0.0.tgz#3537f654665ec3cc38827387fc904c163c54f506" + integrity sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ== + dependencies: + graceful-fs "^4.1.15" + hasha "^5.0.0" + lodash.flattendeep "^4.4.0" + release-zalgo "^1.0.0" + +package-json@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.3.0.tgz#5ed793418b8322af7abfb985a19a20c2f40c2fb0" + integrity sha512-XO7WS3EEXd48vmW633Y97Mh9xuENFiOevI9G+ExfTG/k6xuY9cBd3fxkAoDMSEsNZXasaVJIJ1rD/n7GMf18bA== + dependencies: + got "^9.6.0" + registry-auth-token "^3.4.0" + registry-url "^5.0.0" + semver "^5.6.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA= + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-ms@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-2.1.0.tgz#348565a753d4391fa524029956b172cb7753097d" + integrity sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA== + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-is-inside@^1.0.1, path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +path-to-regexp@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" + integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30= + dependencies: + isarray "0.0.1" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + +pathval@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" + integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= + +picomatch@^2.0.4, picomatch@^2.0.5: + version "2.0.7" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6" + integrity sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA== + +pidtree@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.0.tgz#f6fada10fccc9f99bf50e90d0b23d72c9ebc2e6b" + integrity sha512-9CT4NFlDcosssyg8KVFltgokyKZIFjoBxw8CTGy+5F38Y1eQWrt8tRayiUOXE+zVKQnYu5BR8JjCtvK3BcnBhg== + +pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + +pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +pkg-conf@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/pkg-conf/-/pkg-conf-3.1.0.tgz#d9f9c75ea1bae0e77938cde045b276dac7cc69ae" + integrity sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ== + dependencies: + find-up "^3.0.0" + load-json-file "^5.2.0" + +pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + +plist@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/plist/-/plist-2.1.0.tgz#57ccdb7a0821df21831217a3cad54e3e146a1025" + integrity sha1-V8zbeggh3yGDEhejytVOPhRqECU= + dependencies: + base64-js "1.2.0" + xmlbuilder "8.2.2" + xmldom "0.1.x" + +plur@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/plur/-/plur-3.1.1.tgz#60267967866a8d811504fe58f2faaba237546a5b" + integrity sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w== + dependencies: + irregular-plurals "^2.0.0" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + +pretty-ms@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-5.0.0.tgz#6133a8f55804b208e4728f6aa7bf01085e951e24" + integrity sha512-94VRYjL9k33RzfKiGokPBPpsmloBYSf5Ri+Pq19zlsEcUKFob+admeXr5eFDRuPjFmEOcjJvPGdillYOJyvZ7Q== + dependencies: + parse-ms "^2.1.0" + +propagate@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/propagate/-/propagate-1.0.0.tgz#00c2daeedda20e87e3782b344adba1cddd6ad709" + integrity sha1-AMLa7t2iDofjeCs0Stuhzd1q1wk= + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +qs@^6.5.1: + version "6.7.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" + integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== + +quick-lru@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" + integrity sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g= + +rc@^1.1.6, rc@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + integrity sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc= + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + +read-pkg-up@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978" + integrity sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA== + dependencies: + find-up "^3.0.0" + read-pkg "^3.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k= + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +read-pkg@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.1.1.tgz#5cf234dde7a405c90c88a519ab73c467e9cb83f5" + integrity sha512-dFcTLQi6BZ+aFUaICg7er+/usEoqFdQxiEBsEMNGoipenihtxxtdrQuBXvyANCEI8VuUIVYFgeHGx9sLLvim4w== + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^4.0.0" + type-fest "^0.4.1" + +readdirp@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.0.2.tgz#cba63348e9e42fc1bd334b1d2ef895b6a043cbd6" + integrity sha512-LbyJYv48eywrhOlScq16H/VkCiGKGPC2TpOdZCJ7QXnYEjn3NN/Oblh8QEU3vqfSRBB7OGvh5x45NKiVeNujIQ== + dependencies: + picomatch "^2.0.4" + +redent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-2.0.0.tgz#c1b2007b42d57eb1389079b3c8333639d5e1ccaa" + integrity sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo= + dependencies: + indent-string "^3.0.0" + strip-indent "^2.0.0" + +regenerate-unicode-properties@^8.0.2: + version "8.1.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" + integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA== + dependencies: + regenerate "^1.4.0" + +regenerate@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpu-core@^4.5.4: + version "4.5.4" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.4.tgz#080d9d02289aa87fe1667a4f5136bc98a6aebaae" + integrity sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ== + dependencies: + regenerate "^1.4.0" + regenerate-unicode-properties "^8.0.2" + regjsgen "^0.5.0" + regjsparser "^0.6.0" + unicode-match-property-ecmascript "^1.0.4" + unicode-match-property-value-ecmascript "^1.1.0" + +registry-auth-token@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.4.0.tgz#d7446815433f5d5ed6431cd5dca21048f66b397e" + integrity sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A== + dependencies: + rc "^1.1.6" + safe-buffer "^5.0.1" + +registry-url@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" + integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== + dependencies: + rc "^1.2.8" + +regjsgen@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.0.tgz#a7634dc08f89209c2049adda3525711fb97265dd" + integrity sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA== + +regjsparser@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.0.tgz#f1e6ae8b7da2bae96c99399b868cd6c933a2ba9c" + integrity sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ== + dependencies: + jsesc "~0.5.0" + +release-zalgo@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" + integrity sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA= + dependencies: + es6-error "^4.0.1" + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + +require-precompiled@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/require-precompiled/-/require-precompiled-0.1.0.tgz#5a1b52eb70ebed43eb982e974c85ab59571e56fa" + integrity sha1-WhtS63Dr7UPrmC6XTIWrWVceVvo= + +resolve-alfred-prefs@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-alfred-prefs/-/resolve-alfred-prefs-1.0.0.tgz#aae914088578829b584a4e6b72507e8c2096ec37" + integrity sha1-qukUCIV4gptYSk5rclB+jCCW7Dc= + dependencies: + bplist-parser "^0.1.1" + path-exists "^3.0.0" + pify "^2.3.0" + untildify "^3.0.2" + user-home "^2.0.0" + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= + dependencies: + resolve-from "^3.0.0" + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + integrity sha1-six699nWiBvItuZTM17rywoYh0g= + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@^1.10.0, resolve@^1.3.2: + version "1.11.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.0.tgz#4014870ba296176b86343d50b60f3b50609ce232" + integrity sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw== + dependencies: + path-parse "^1.0.6" + +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= + dependencies: + lowercase-keys "^1.0.0" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +rimraf@^2.2.8, rimraf@^2.6.2, rimraf@^2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +safe-buffer@^5.0.1, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +semver-diff@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" + integrity sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY= + dependencies: + semver "^5.0.3" + +"semver@2 || 3 || 4 || 5", semver@^5.0.3, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0: + version "5.7.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" + integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== + +semver@^6.0.0, semver@^6.1.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.1.1.tgz#53f53da9b30b2103cd4f15eab3a18ecbcb210c9b" + integrity sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ== + +serialize-error@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-2.1.0.tgz#50b679d5635cdf84667bdc8e59af4e5b81d5f60a" + integrity sha1-ULZ51WNc34Rme9yOWa9OW4HV9go= + +set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +shell-quote@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" + integrity sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c= + dependencies: + array-filter "~0.0.0" + array-map "~0.0.0" + array-reduce "~0.0.0" + jsonify "~0.0.0" + +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + integrity sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww== + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +sinon@^7.3.2: + version "7.3.2" + resolved "https://registry.yarnpkg.com/sinon/-/sinon-7.3.2.tgz#82dba3a6d85f6d2181e1eca2c10d8657c2161f28" + integrity sha512-thErC1z64BeyGiPvF8aoSg0LEnptSaWE7YhdWWbWXgelOyThent7uKOnnEh9zBxDbKixtr5dEko+ws1sZMuFMA== + dependencies: + "@sinonjs/commons" "^1.4.0" + "@sinonjs/formatio" "^3.2.1" + "@sinonjs/samsam" "^3.3.1" + diff "^3.5.0" + lolex "^4.0.1" + nise "^1.4.10" + supports-color "^5.5.0" + +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" + integrity sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg== + dependencies: + is-fullwidth-code-point "^2.0.0" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-support@^0.5.12: + version "0.5.12" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" + integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@^0.5.0, source-map@^0.5.6: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +spawn-wrap@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-1.4.2.tgz#cff58e73a8224617b6561abdc32586ea0c82248c" + integrity sha512-vMwR3OmmDhnxCVxM8M+xO/FtIp6Ju/mNaDfCMMW7FDcLRTPFWUswec4LXJHTJE2hwTI9O0YBfygu4DalFl7Ylg== + dependencies: + foreground-child "^1.5.6" + mkdirp "^0.5.0" + os-homedir "^1.0.1" + rimraf "^2.6.2" + signal-exit "^3.0.2" + which "^1.3.0" + +spdx-correct@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz#75ecd1a88de8c184ef015eafb51b5b48bfd11bb1" + integrity sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +stack-utils@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" + integrity sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA== + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +string-width@^2.0.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0, string-width@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string.prototype.padend@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.0.0.tgz#f3aaef7c1719f170c5eab1c32bf780d96e21f2f0" + integrity sha1-86rvfBcZ8XDF6rHDK/eA2W4h8vA= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.4.3" + function-bind "^1.0.2" + +strip-ansi@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-bom-buf@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-buf/-/strip-bom-buf-2.0.0.tgz#ff9c223937f8e7154b77e9de9bde094186885c15" + integrity sha512-gLFNHucd6gzb8jMsl5QmZ3QgnUJmp7qn4uUSHNwEXumAp7YizoGYw19ZUVfuq4aBOQUtyn2k8X/CwzWB73W2lQ== + dependencies: + is-utf8 "^0.2.1" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= + +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +sudo-block@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/sudo-block/-/sudo-block-1.2.0.tgz#cc539bf8191624d4f507d83eeb45b4cea27f3463" + integrity sha1-zFOb+BkWJNT1B9g+60W0zqJ/NGM= + dependencies: + chalk "^1.0.0" + is-docker "^1.0.0" + is-root "^1.0.0" + +supertap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supertap/-/supertap-1.0.0.tgz#bd9751c7fafd68c68cf8222a29892206a119fa9e" + integrity sha512-HZJ3geIMPgVwKk2VsmO5YHqnnJYl6bV5A9JW2uzqV43WmpgliNEYbuvukfor7URpaqpxuw3CfZ3ONdVbZjCgIA== + dependencies: + arrify "^1.0.1" + indent-string "^3.2.0" + js-yaml "^3.10.0" + serialize-error "^2.1.0" + strip-ansi "^4.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^5.3.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +symbol-observable@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== + +temp-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" + integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= + +tempy@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/tempy/-/tempy-0.3.0.tgz#6f6c5b295695a16130996ad5ab01a8bd726e8bf8" + integrity sha512-WrH/pui8YCwmeiAoxV+lpRH9HpRtgBhSR2ViBPgpGb/wnYDzp21R4MN45fsCGvLROvY67o3byhJRYRONJyImVQ== + dependencies: + temp-dir "^1.0.0" + type-fest "^0.3.1" + unique-string "^1.0.0" + +term-size@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" + integrity sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk= + dependencies: + execa "^0.7.0" + +test-exclude@^5.2.3: + version "5.2.3" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.2.3.tgz#c3d3e1e311eb7ee405e092dac10aefd09091eac0" + integrity sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g== + dependencies: + glob "^7.1.3" + minimatch "^3.0.4" + read-pkg-up "^4.0.0" + require-main-filename "^2.0.0" + +time-zone@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/time-zone/-/time-zone-1.0.0.tgz#99c5bf55958966af6d06d83bdf3800dc82faec5d" + integrity sha1-mcW/VZWJZq9tBtg73zgA3IL67F0= + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +trim-newlines@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" + integrity sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA= + +trim-off-newlines@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz#9f9ba9d9efa8764c387698bcbfeb2c848f11adb3" + integrity sha1-n5up2e+odkw4dpi8v+sshI8RrbM= + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= + +tslib@^1.8.0, tslib@^1.8.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" + integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== + +tslint@^5.16.0: + version "5.17.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.17.0.tgz#f9f0ce2011d8e90debaa6e9b4975f24cd16852b8" + integrity sha512-pflx87WfVoYepTet3xLfDOLDm9Jqi61UXIKePOuca0qoAZyrGWonDG9VTbji58Fy+8gciUn8Bt7y69+KEVjc/w== + dependencies: + "@babel/code-frame" "^7.0.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^3.2.0" + glob "^7.1.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + mkdirp "^0.5.1" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.8.0" + tsutils "^2.29.0" + +tsutils@^2.29.0: + version "2.29.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.29.0.tgz#32b488501467acbedd4b85498673a0812aca0b99" + integrity sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA== + dependencies: + tslib "^1.8.1" + +type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.3.0, type-fest@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" + integrity sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ== + +type-fest@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8" + integrity sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw== + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +typescript@^3.4.5: + version "3.5.1" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.1.tgz#ba72a6a600b2158139c5dd8850f700e231464202" + integrity sha512-64HkdiRv1yYZsSe4xC1WVgamNigVYjlssIoaH2HcZF0+ijsk5YK2g0G34w9wJkze8+5ow4STd22AynfO6ZYYLw== + +uglify-js@^3.1.4: + version "3.6.0" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.0.tgz#704681345c53a8b2079fb6cec294b05ead242ff5" + integrity sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg== + dependencies: + commander "~2.20.0" + source-map "~0.6.1" + +uid2@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82" + integrity sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I= + +unicode-canonical-property-names-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz#2619800c4c825800efdd8343af7dd9933cbe2818" + integrity sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ== + +unicode-match-property-ecmascript@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz#8ed2a32569961bce9227d09cd3ffbb8fed5f020c" + integrity sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg== + dependencies: + unicode-canonical-property-names-ecmascript "^1.0.4" + unicode-property-aliases-ecmascript "^1.0.4" + +unicode-match-property-value-ecmascript@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277" + integrity sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g== + +unicode-property-aliases-ecmascript@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" + integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw== + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +unique-string@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a" + integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo= + dependencies: + crypto-random-string "^1.0.0" + +unique-temp-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unique-temp-dir/-/unique-temp-dir-1.0.0.tgz#6dce95b2681ca003eebfb304a415f9cbabcc5385" + integrity sha1-bc6VsmgcoAPuv7MEpBX5y6vMU4U= + dependencies: + mkdirp "^0.5.1" + os-tmpdir "^1.0.1" + uid2 "0.0.3" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +untildify@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.3.tgz#1e7b42b140bcfd922b22e70ca1265bfe3634c7c9" + integrity sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA== + +update-notifier@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-3.0.0.tgz#e9bbf8f0f5b7a2ce6666ca46334fdb29492e8fab" + integrity sha512-6Xe3oF2bvuoj4YECUc52yxVs94yWrxwqHbzyveDktTS1WhnlTRpNcQMxUshcB7nRVGi1jEXiqL5cW1S5WSyzKg== + dependencies: + boxen "^3.0.0" + chalk "^2.0.1" + configstore "^4.0.0" + has-yarn "^2.1.0" + import-lazy "^2.1.0" + is-ci "^2.0.0" + is-installed-globally "^0.1.0" + is-npm "^3.0.0" + is-yarn-global "^0.3.0" + latest-version "^5.0.0" + semver-diff "^2.0.0" + xdg-basedir "^3.0.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +user-home@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" + integrity sha1-nHC/2Babwdy/SGBODwS4tJzenp8= + dependencies: + os-homedir "^1.0.0" + +uuid@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +wcwidth@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= + dependencies: + defaults "^1.0.3" + +well-known-symbols@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/well-known-symbols/-/well-known-symbols-2.0.0.tgz#e9c7c07dbd132b7b84212c8174391ec1f9871ba5" + integrity sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q== + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= + +which@^1.2.9, which@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +widest-line@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" + integrity sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA== + dependencies: + string-width "^2.1.1" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= + +wrap-ansi@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" + integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== + dependencies: + ansi-styles "^3.2.0" + string-width "^3.0.0" + strip-ansi "^5.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write-file-atomic@^2.0.0, write-file-atomic@^2.4.2: + version "2.4.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" + integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +write-file-atomic@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.0.tgz#1b64dbbf77cb58fd09056963d63e62667ab4fb21" + integrity sha512-EIgkf60l2oWsffja2Sf2AL384dx328c0B+cIYPTQq5q2rOYuDV00/iPFBOUiDKKwKMOhkymH8AidPaRvzfxY+Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +xdg-basedir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" + integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= + +xmlbuilder@8.2.2: + version "8.2.2" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-8.2.2.tgz#69248673410b4ba42e1a6136551d2922335aa773" + integrity sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M= + +xmldom@0.1.x: + version "0.1.27" + resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9" + integrity sha1-1QH5ezvbQDr4757MIFcxh6rawOk= + +xtend@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= + +y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= + +yargs-parser@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" + integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== + dependencies: + camelcase "^4.1.0" + +yargs-parser@^13.0.0, yargs-parser@^13.1.0: + version "13.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.0.tgz#7016b6dd03e28e1418a510e258be4bff5a31138f" + integrity sha512-Yq+32PrijHRri0vVKQEm+ys8mbqWjLiwQkMFNXEENutzLPP0bE4Lcd4iA3OQY5HF+GD3xXxf0MEHb8E4/SA3AA== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + +yargs@^13.2.2: + version "13.2.4" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" + integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + os-locale "^3.1.0" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.0" From 23e07826c3f49988928bb7a42d060086aff287ab Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Tue, 4 Jun 2019 02:50:10 +0200 Subject: [PATCH 03/35] Remove unneeded files --- .DS_Store | Bin 6148 -> 0 bytes .gitignore | 1 + 2 files changed, 1 insertion(+) delete mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 9bc15b6920bb330e92f0d4c657fbdac720b62c04..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKF-`+P47A~jlW0;>?icvMDhe;)10;klC`btsDIf);fE17d7b{SmbiBK`f{0Q;3S6rK{5~`|u@_E>@#(-4 zBLHwfI1KxkC4h|qU@x2!5rKJ9fl2imF+Ayrx612$Djo>oh|QuWr^%dyus_%ob2UvL`sLBSI3 k7#Qss2e#w;NXop%J)ZZ%DKY4X2OX%N0qP=?0{^YRH(q5Lx&QzG diff --git a/.gitignore b/.gitignore index aba05ba..ce40699 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ node_modules/ yarn-error.log +.DS_Store /.nyc_output /build From 0fbef6583631fbe2ada1e3a9fd147dd3710f3f5c Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Tue, 4 Jun 2019 21:59:23 +0200 Subject: [PATCH 04/35] Clean up --- package.json | 2 - test/file-cache.js | 179 ------------------ test/helpers/mock.ts | 2 +- .../mocks/appcast-invalidversion.xml | 0 .../{ => helpers}/mocks/appcast-noversion.xml | 0 test/{ => helpers}/mocks/appcast.xml | 0 yarn.lock | 21 +- 7 files changed, 2 insertions(+), 202 deletions(-) delete mode 100644 test/file-cache.js rename test/{ => helpers}/mocks/appcast-invalidversion.xml (100%) rename test/{ => helpers}/mocks/appcast-noversion.xml (100%) rename test/{ => helpers}/mocks/appcast.xml (100%) diff --git a/package.json b/package.json index 6220b81..bb0dd87 100644 --- a/package.json +++ b/package.json @@ -32,13 +32,11 @@ "@types/sinon": "^7.0.12", "ava": "^2.0.0", "del-cli": "^2.0.0", - "delay": "^4.2.0", "mockdate": "^2.0.2", "nock": "^10.0.6", "npm-run-all": "^4.1.5", "nyc": "^14.1.1", "sinon": "^7.3.2", - "tempy": "^0.3.0", "tslint": "^5.16.0", "typescript": "^3.4.5" }, diff --git a/test/file-cache.js b/test/file-cache.js deleted file mode 100644 index 3fb4094..0000000 --- a/test/file-cache.js +++ /dev/null @@ -1,179 +0,0 @@ -import fs from 'fs-extra'; -import os from 'os'; -import path from 'path'; -import tempy from 'tempy'; -import test from 'ava'; - -import {hugo} from './_init'; -import FileCache from './../file-cache'; - -/** - * Clean-up - */ -function cleanUp() { - fs.emptyDirSync(path.resolve(path.join(os.tmpdir(), 'my.work.flow'))); - fs.emptyDirSync(process.env.alfred_workflow_cache); -} - -/** - * Set-up - */ -test.beforeEach('setup', t => { - const h = hugo(); - - const testData = { - foo: 'bar' - }; - - h.options({ - checkUpdates: false, - useTmpCache: false - }); - - t.context.hugo = h; - t.context.testData = testData; - - cleanUp(); -}); - -/** - * Process file and store results in file cache - */ -test.serial('process file and cache it', t => { - const h = t.context.hugo; - const tmpFile = tempy.file(); - - // Create file - fs.writeFileSync(tmpFile, 'Hello world!'); - - // Get FileCache instance - let cachedFile = h.cacheFile(tmpFile, 'foo'); - - // Listen to change event to process data - cachedFile.on('change', (cache, file, hash) => { - t.is(cache.constructor.name, 'FileCacheStore'); - t.is(typeof file, 'string'); - t.true(file.length > 0); - t.is(typeof hash, 'string'); - t.true(hash.length > 0); - - cache.store(t.context.testData); - cache.set('hello', 'world!'); - }); - - // Fetch data - let data = cachedFile.get(); - - // Verify data - t.snapshot(data); - - // Listen to change event (which should not be emitted now) - cachedFile.once('change', () => { - t.fail('Data has not been cached.'); - }); - - // Fetch data again - data = cachedFile.get(); - - // Verify data - t.snapshot(data); -}); - -test.serial('process file with no cache dir set', t => { - const tmpFile = tempy.file(); - - t.plan(4); - - // Create file - fs.writeFileSync(tmpFile, 'Hello world!'); - - // Get FileCache instance - let cachedFile = new FileCache(tmpFile, 'foo', null); - - // Listen to change event to process data - cachedFile.once('change', cache => { - t.is(cache.constructor.name, 'FileCacheStore'); - cache.store(t.context.testData); - }); - - // Fetch data - let data = cachedFile.get(); - - // Verify data - t.snapshot(data); - - // Listen to change event again (cache should be empty) - cachedFile.once('change', cache => { - t.snapshot(cache.contents); - }); - - // Fetch data again (should be empty as well as this time we didn't store anything after processing) - data = cachedFile.get(); - - // Verify data - t.snapshot(data); -}); - -test.serial('clear cache', async t => { - const h = t.context.hugo; - const tmpFile = tempy.file(); - - t.plan(4); - - // Create file - fs.writeFileSync(tmpFile, 'Hello world!'); - - // Get FileCache instance - let cachedFile = h.cacheFile(tmpFile, 'foo'); - - // Listen to change event to process data - cachedFile.once('change', cache => { - t.is(cache.constructor.name, 'FileCacheStore'); - cache.store(t.context.testData); - }); - - // Fetch data - let data = cachedFile.get(); - - // Verify data - t.snapshot(data); - - // Clear cache - await cachedFile.clearCache(); - - // Listen to change event again (cache should be empty) - cachedFile.once('change', cache => { - t.snapshot(cache.contents); - }); - - // Fetch data again (should be empty) - data = cachedFile.get(); - - // Verify data - t.snapshot(data); -}); - -test.serial('process non-existing file', t => { - const h = t.context.hugo; - - // Get FileCache instance - let cachedFile = h.cacheFile(path.resolve(__dirname, 'idontexist.txt'), 'foo'); - - // Listen to change event to process data - cachedFile.on('change', () => { - t.fail('File does not exist and this should not be called.'); - }); - - // Fetch data - let data = cachedFile.get(); - - // Verify data - t.falsy(data); -}); - -/** - * Tear-down - */ -test.afterEach.always('cleanup', () => { - cleanUp(); -}); diff --git a/test/helpers/mock.ts b/test/helpers/mock.ts index 9044c8a..b4eb979 100644 --- a/test/helpers/mock.ts +++ b/test/helpers/mock.ts @@ -65,7 +65,7 @@ export function npm(times: number = 1, pkg?: any, code: number = 200, latestVers } export function packal(times: number = 1, code: number = 200, filename: string = "appcast.xml") { - filename = path.join("test", "mocks", filename); + filename = path.join("test", "helpers", "mocks", filename); // Response body let body = ""; diff --git a/test/mocks/appcast-invalidversion.xml b/test/helpers/mocks/appcast-invalidversion.xml similarity index 100% rename from test/mocks/appcast-invalidversion.xml rename to test/helpers/mocks/appcast-invalidversion.xml diff --git a/test/mocks/appcast-noversion.xml b/test/helpers/mocks/appcast-noversion.xml similarity index 100% rename from test/mocks/appcast-noversion.xml rename to test/helpers/mocks/appcast-noversion.xml diff --git a/test/mocks/appcast.xml b/test/helpers/mocks/appcast.xml similarity index 100% rename from test/mocks/appcast.xml rename to test/helpers/mocks/appcast.xml diff --git a/yarn.lock b/yarn.lock index 154ffc1..266ba72 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1345,11 +1345,6 @@ del@^4.1.1: pify "^4.0.1" rimraf "^2.6.3" -delay@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/delay/-/delay-4.2.0.tgz#3f6c39dbd28aef50355e670fecee050ef01242ce" - integrity sha512-EBX+pZE4qSowGAMr6M0cLiPRQu2Kus/qTNLO7c+EoXpTPJH9ApFdHX+cQU1WsSHXgwhLyidfZ5Hxuq6ctWhSdw== - diff@^3.2.0, diff@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -3986,20 +3981,6 @@ symbol-observable@^1.0.4: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ== -temp-dir@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" - integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= - -tempy@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/tempy/-/tempy-0.3.0.tgz#6f6c5b295695a16130996ad5ab01a8bd726e8bf8" - integrity sha512-WrH/pui8YCwmeiAoxV+lpRH9HpRtgBhSR2ViBPgpGb/wnYDzp21R4MN45fsCGvLROvY67o3byhJRYRONJyImVQ== - dependencies: - temp-dir "^1.0.0" - type-fest "^0.3.1" - unique-string "^1.0.0" - term-size@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" @@ -4115,7 +4096,7 @@ type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5: resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== -type-fest@^0.3.0, type-fest@^0.3.1: +type-fest@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" integrity sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ== From 13b897ca93d19a045fa565e29deb6c362ea95e79 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Tue, 4 Jun 2019 23:22:25 +0200 Subject: [PATCH 05/35] Rename search to match --- src/hugo.ts | 2 +- test/matching.ts | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hugo.ts b/src/hugo.ts index 12e5676..dd4825c 100644 --- a/src/hugo.ts +++ b/src/hugo.ts @@ -289,7 +289,7 @@ export class Hugo { * @param {string} query Search string * @param {Object} options fuse.js options */ - public search(candidates: Item[], query: string, options?: Fuse.FuseOptions): Item[] { + public match(candidates: Item[], query: string, options?: Fuse.FuseOptions): Item[] { options = Object.assign({}, this.fuseDefaults, options || {}); if (query.trim().length === 0) { diff --git a/test/matching.ts b/test/matching.ts index 3f09ef5..71954ba 100644 --- a/test/matching.ts +++ b/test/matching.ts @@ -33,7 +33,7 @@ test.beforeEach((t) => { test("exact match", (t) => { const h = hugo(); - const matches = h.search(t.context.items, "foo bar bleep", { + const matches = h.match(t.context.items, "foo bar bleep", { keys: ["subtitle"], threshold: 0, }); @@ -46,7 +46,7 @@ test("exact match", (t) => { test("exact match multiple keys", (t) => { const h = hugo(); - const matches = h.search(t.context.items, "foo", { + const matches = h.match(t.context.items, "foo", { keys: ["title", "subtitle"], }); @@ -58,7 +58,7 @@ test("exact match multiple keys", (t) => { test("no matches", (t) => { const h = hugo(); - const matches = h.search(t.context.items, "nope", { + const matches = h.match(t.context.items, "nope", { threshold: 0, }); @@ -69,7 +69,7 @@ test("no matches", (t) => { test("no query should return all items", (t) => { const h = hugo(); - const matches = h.search(t.context.items, ""); + const matches = h.match(t.context.items, ""); t.true(Array.isArray(matches)); t.is(matches.length, 5); From 19c147b8309344f42366584e0e796c87bc349c23 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sat, 8 Jun 2019 19:43:08 +0200 Subject: [PATCH 06/35] Improve tests and make actions support nesting --- docs/metadata.md | 70 +++++++ src/action.ts | 44 +++++ src/hugo.ts | 85 +++++--- test/actions.ts | 258 ++++++++++++++++++++++++- test/feedback.ts | 2 +- test/fetch.ts | 14 +- test/helpers/init.ts | 13 ++ test/helpers/mock.ts | 51 ++++- test/helpers/types.ts | 1 + test/hugo.ts | 28 ++- test/updates/npm.ts | 96 ++++++--- test/updates/packal.ts | 77 ++++++-- test/updates/snapshots/updater.ts.md | 32 +++ test/updates/snapshots/updater.ts.snap | Bin 440 -> 516 bytes test/updates/updater.ts | 210 +++++++++++++------- yarn.lock | 77 ++++---- 16 files changed, 832 insertions(+), 226 deletions(-) create mode 100644 docs/metadata.md create mode 100644 src/action.ts diff --git a/docs/metadata.md b/docs/metadata.md new file mode 100644 index 0000000..2b32f5d --- /dev/null +++ b/docs/metadata.md @@ -0,0 +1,70 @@ +# Metadata + +Alfred exposes some useful metadata to the script using environment variables. This for example gives you information about Alfred's version, prefrerences and more. Alfred also exposes metadata about the workflow. + +Hugo makes it easy for you to access both Alfred's metadata and your workflow metadata. + +## Alfred metadata + +Alfred metadata can be accessed using the `alfredMeta` property of Hugo and is an object containing the following items: + +```json +{ + debug: true, // True when debug panel is opened + preferences: // Path to Alfred preferences file, + preferencesLocalHash: // Contains hash from alfred_preferences_localhash, + theme: // Theme file name, + themeBackground: // Theme background colour, + themeSelectionBackground: // Colour of the selected result, + themeSubtext: // Contains value from alfred_theme_subtext, + themeFile: // Absolute path to theme file (if found), + version: // Alfred version +} +``` + +For background information, see: https://www.alfredapp.com/help/workflows/script-environment-variables + +## Workflow metadata + +Workflow metadata can be accessed through the `workflowMeta` property of Hugo. + +```json +{ + bundleId: // The bundle ID of the current running workflow, + cache: // Path to workflow cache directory, + data: // Path to workflow data directory, + icon: // Path to workflow icon, + name: // Workflow name, + uid: // Unique ID of the workflow, + version: // Workflow version +} +``` + +## Theme data + +To save you some effort when you really want to blend in, Hugo has an easy way of loading the theme file for you (if it was found). You can access the active theme data using the `alfredTheme` property of Hugo. + +```js +import { Hugo } from "alfred-hugo"; + +const hugo = new Hugo(); + +const themeData = hugo.alfredTheme; + +// themeData will contain the parsed JSON contents of the active Alfred theme +``` + +## Example + +```js +import { Hugo } from "alfred-hugo"; + +const hugo = new Hugo(); + +console.log(`Alfred version ${hugo.alfredMeta.version}`); +console.log(`Workflow ${hugo.workflowMeta.name} version ${hugo.workflowMeta.version}`); + +// Alfred version 3.4.1 +// Workflow alfred-foobar version 1.0.0 +``` + diff --git a/src/action.ts b/src/action.ts new file mode 100644 index 0000000..990e472 --- /dev/null +++ b/src/action.ts @@ -0,0 +1,44 @@ +export class Action { + private actions: Action[]; + private name: string; + private callback?: (query: string[]) => void; + + public constructor(name: string, callback?: (query: string[]) => void) { + this.name = name; + this.callback = callback; + this.actions = []; + } + + public action(name: string, callback: (query: string[]) => void): Action { + const action = new Action(name, callback); + + this.actions.push(action); + + return action; + } + + public run(args: string[]) { + if (args.length === 0) { + return false; + } + + if (args[0] === this.name) { + const subargs = args.slice(1); + + // Check sub actions first + for (const action of this.actions) { + if (action.run(subargs) === true) { + return true; + } + } + + // Run self + if (this.callback) { + this.callback(args.slice(1)); + return true; + } + } + + return false; + } +} diff --git a/src/hugo.ts b/src/hugo.ts index dd4825c..bb4f13a 100644 --- a/src/hugo.ts +++ b/src/hugo.ts @@ -1,6 +1,7 @@ import { Cache } from "@cloudstek/cache"; import { ICacheOptions } from "@cloudstek/cache"; import fs from "fs-extra"; +import crypto from "crypto"; import Fuse from "fuse.js"; import Axios, { AxiosRequestConfig } from "axios"; import moment from "moment"; @@ -8,10 +9,11 @@ import path from "path"; import Semver from "semver"; import NotificationCenter from "node-notifier/notifiers/notificationcenter"; +import { Action } from "./action"; import { FileCache } from "./file-cache"; -import { AlfredMeta, FilterResults, HugoOptions, WorkflowMeta, UpdateSource, Item } from "./types"; import { Updater } from "./updater"; import * as utils from "./utils"; +import { AlfredMeta, FilterResults, HugoOptions, WorkflowMeta, UpdateSource, Item } from "./types"; export class Hugo { public cache: Cache; @@ -20,6 +22,7 @@ export class Hugo { public variables: { [key: string]: any } = {}; public items: Item[] = []; + private actions: Action[]; private fuseDefaults: Fuse.FuseOptions; private options: HugoOptions; private updater: Updater; @@ -29,7 +32,7 @@ export class Hugo { // Save options this.options = { checkUpdates: true, - updateInterval: moment.duration(1, "days"), + updateInterval: moment.duration(1, "day"), updateItem: true, updateNotification: true, updateSource: UpdateSource.NPM, @@ -60,6 +63,9 @@ export class Hugo { // Notofier this.notifier = new NotificationCenter(); + + // Actions + this.actions = []; } /** @@ -76,17 +82,15 @@ export class Hugo { if (!moment.isDuration(options.updateInterval)) { options.updateInterval = moment.duration(options.updateInterval, "seconds"); } + } - if (options.updateInterval.asSeconds() < 1) { - options.checkUpdates = false; - delete options.updateInterval; - } + if (!options.updateInterval || (options.updateInterval as moment.Duration).asSeconds() < 1) { + options.checkUpdates = false; + delete options.updateInterval; } - if (typeof options.updateSource === "string") { - if (!UpdateSource[options.updateSource as any]) { - throw new Error("Invalid update source."); - } + if (typeof options.updateSource !== "string" || !UpdateSource[options.updateSource.toLowerCase() as any]) { + throw new Error("Invalid update source."); } this.options = options; @@ -196,15 +200,8 @@ export class Hugo { /** * Alfred user input */ - public get input(): string { - // User input with the action name stripped off - // node index.js myaction "myquery" - if (process.argv.length > 3) { - return process.argv[3]; - } - - // User input when not inside an action - return process.argv[2] || ""; + public get input(): string[] { + return process.argv.slice(2); } /** @@ -227,18 +224,40 @@ export class Hugo { } /** - * Run a callback when first script argument matches keyword. Callback will have third argument as query parameter. + * Run a callback when first script argument matches keyword. Callback will have second argument as query parameter. * * @example node index.js myaction "my query" * * @param keyword Action name * @param callback Callback to execute when query matches action name */ - public action(keyword: string, callback: (query: string) => void): Hugo { - const action = process.argv[2] || ""; + public action( + keyword: string, + callback?: (query: string[]) => void, + ): Action { + const action = new Action(keyword, callback); + + this.actions.push(action); + + return action; + } - if (action === keyword) { - callback(process.argv[3] || ""); + /** + * Find defined action from arguments and run it. + * + * @param args + * + * @return Hugo + */ + public run(args?: string[]) { + if (!args) { + args = process.argv.slice(2); + } + + for (const action of this.actions) { + if (action.run(args) === true) { + break; + } } return this; @@ -300,7 +319,7 @@ export class Hugo { const fuse = new Fuse(candidates, options); // Return results - return fuse.search(query) || []; + return fuse.search(query); } /** @@ -369,8 +388,13 @@ export class Hugo { }); } if (this.options.updateItem === true) { + // Make sure update item is only added once + this.items = this.items.filter((item) => { + return item.title !== "Workflow update available!"; + }); + this.items.push({ - title: `Workflow update available!`, + title: "Workflow update available!", subtitle: `Version ${latest} is available. Current version: ${current}.`, icon: { path: this.workflowMeta.icon || "", @@ -401,10 +425,12 @@ export class Hugo { * @param ttl Cache lifetime (in seconds). Undefined to disable or false to enable indefinite caching. */ public async fetch(url: string, options?: AxiosRequestConfig, ttl?: number | false) { + const urlHash = crypto.createHash("md5").update(url).digest("hex"); + // Check cache for a hit if (ttl && ttl > 0) { - if (this.cache.has(url)) { - return this.cache.get(url); + if (this.cache.has(urlHash)) { + return this.cache.get(urlHash); } } @@ -412,7 +438,8 @@ export class Hugo { return Axios.get(url, options) .then((response) => { if (ttl && ttl > 0) { - this.cache.set(url, response.data, ttl); + this.cache.set(urlHash, response.data, ttl); + this.cache.commit(); } return response.data; diff --git a/test/actions.ts b/test/actions.ts index cf27cbb..3c91b98 100644 --- a/test/actions.ts +++ b/test/actions.ts @@ -1,7 +1,27 @@ import test from "ava"; import { hugo } from "./helpers/init"; -test("actions defined but no matching action", (t) => { +test.serial("no actions defined", (t) => { + process.argv = [ + "node", + "index.js", + "foo", + ]; + + const h = hugo(); + + t.is(h.input.length, 1); + t.is(h.input[0], "foo"); + + h.run(); + + // Now run with custom args + process.argv = []; + + h.run(["foo"]); +}); + +test.serial("actions defined but no matching action", (t) => { process.argv = [ "node", "index.js", @@ -20,10 +40,18 @@ test("actions defined but no matching action", (t) => { t.fail(); }); - t.is(h.input, "foo"); + t.is(h.input.length, 1); + t.is(h.input[0], "foo"); + + h.run(); + + // Now run with custom args + process.argv = []; + + h.run(["foo"]); }); -test("actions defined but no action given", (t) => { +test.serial("actions defined but no action given", (t) => { process.argv = [ "node", "index.js", @@ -41,10 +69,19 @@ test("actions defined but no action given", (t) => { t.fail(); }); - t.is(h.input, ""); + t.is(h.input.length, 0); + + h.run(); + + // Now run with custom args + process.argv = []; + + h.run([]); }); -test("actions defined and matching action with no query", (t) => { +test.serial("actions defined and matching action with no query", (t) => { + t.plan(2); + process.argv = [ "node", "index.js", @@ -59,12 +96,20 @@ test("actions defined and matching action with no query", (t) => { }); h.action("foo", (query) => { - t.is(query, ""); - t.pass(); + t.is(query.length, 0); }); + + h.run(); + + // Now run with custom args + process.argv = []; + + h.run(["foo"]); }); -test("actions defined and matching action with query", (t) => { +test.serial("actions defined and matching action with query", (t) => { + t.plan(4); + process.argv = [ "node", "index.js", @@ -80,7 +125,200 @@ test("actions defined and matching action with query", (t) => { }); h.action("foo", (query) => { - t.is(query, "bar"); - t.pass(); + t.is(query.length, 1); + t.is(query[0], "bar"); }); + + h.run(); + + // Now run with custom args + process.argv = []; + + h.run(["foo", "bar"]); +}); + +test("run actions with custom arguments instead of argv", (t) => { + t.plan(2); + const h = hugo(); + + h.action("bar", (query) => { + t.log(query); + t.fail(); + }); + + h.action("foo", (query) => { + t.is(query.length, 1); + t.is(query[0], "bar"); + }); + + h.run(["foo", "bar"]); +}); + +test.serial("main action without callback and no matching sub-action", (t) => { + process.argv = [ + "node", + "index.js", + "foo", + "hello", + "world", + ]; + + const h = hugo(); + + // Foo with bar sub-action + h + .action("foo") + .action("bar", (query) => { + t.fail(); + }) + ; + + t.is(h.input.length, 3); + t.is(h.input[0], "foo"); + t.is(h.input[1], "hello"); + t.is(h.input[2], "world"); + + h.run(); + + // Now run with custom args + process.argv = []; + + h.run(["foo", "hello", "world"]); +}); + +test.serial("main action with matching sub-action", (t) => { + t.plan(6); + + process.argv = [ + "node", + "index.js", + "foo", + "bar", + "hello", + "world", + ]; + + const h = hugo(); + + // Foo action with bar sub-action + const fooAction = h.action("foo", (query) => { + t.fail(); + }); + + // Bar sub-action with floop sub-action + const barAction = fooAction.action("bar", (query) => { + t.is(query.length, 2); + t.is(query[0], "hello"); + t.is(query[1], "world"); + }); + + barAction.action("floop", (query) => { + t.fail(); + }); + + h.run(); + + // Now run with custom args + process.argv = []; + + h.run(["foo", "bar", "hello", "world"]); +}); + +test.serial("main action with matching sub-sub-action", (t) => { + t.plan(6); + + process.argv = [ + "node", + "index.js", + "foo", + "bar", + "floop", + "hello", + "world", + ]; + + const h = hugo(); + + // Foo action with bar sub-action + const fooAction = h.action("foo", (query) => { + t.fail(); + }); + + // Bar sub-action with floop sub-action + const barAction = fooAction.action("bar", (query) => { + t.fail(); + }); + + barAction.action("floop", (query) => { + t.is(query.length, 2); + t.is(query[0], "hello"); + t.is(query[1], "world"); + }); + + h.run(); + + // Now run with custom args + process.argv = []; + + h.run(["foo", "bar", "floop", "hello", "world"]); +}); + +test.serial("main action with sub-actions defined, without query", (t) => { + t.plan(2); + + process.argv = [ + "node", + "index.js", + "foo", + ]; + + const h = hugo(); + + // Foo with bar sub-action + h + .action("foo", (query) => { + t.is(query.length, 0); + }) + .action("bar", (query) => { + t.fail(); + }) + ; + + h.run(); + + // Now run with custom args + process.argv = []; + + h.run(["foo"]); +}); + +test.serial("main action with sub-actions defined, with query but no sub-action match", (t) => { + t.plan(4); + + process.argv = [ + "node", + "index.js", + "foo", + "hello", + ]; + + const h = hugo(); + + // Foo with bar sub-action + h + .action("foo", (query) => { + t.is(query.length, 1); + t.is(query[0], "hello"); + }) + .action("bar", (query) => { + t.fail(); + }) + ; + + h.run(); + + // Now run with custom args + process.argv = []; + + h.run(["foo", "hello"]); }); diff --git a/test/feedback.ts b/test/feedback.ts index 54c163c..2412433 100644 --- a/test/feedback.ts +++ b/test/feedback.ts @@ -50,7 +50,7 @@ test.serial("check for updates on feedback", async (t) => { await h.feedback(); // Check request - t.true(request.isDone()); + // t.true(request.isDone()); // Feedback again, should not trigger updates await h.feedback(); diff --git a/test/fetch.ts b/test/fetch.ts index 5e65813..5fbeee9 100644 --- a/test/fetch.ts +++ b/test/fetch.ts @@ -1,5 +1,6 @@ import Test, { TestInterface } from "ava"; import nock from "nock"; +import crypto from "crypto"; import { hugo } from "./helpers/init"; import { TestContext } from "./helpers/types"; @@ -9,6 +10,7 @@ const test = Test as TestInterface; test.beforeEach((t) => { t.context.url = "http://foo.bar"; + t.context.urlHash = crypto.createHash("md5").update(t.context.url).digest("hex"); // Mock requests nock(t.context.url) @@ -29,11 +31,11 @@ test.serial("fetch uncached", async (t) => { // Fetch with caching implicitely disabled t.deepEqual(await h.fetch(t.context.url), { message: "hello" }); - t.false(h.cache.has(t.context.url)); + t.false(h.cache.has(t.context.urlHash)); // Fetch with caching explicitely disabled t.deepEqual(await h.fetch(t.context.url, null, false), { message: "world" }); - t.false(h.cache.has(t.context.url)); + t.false(h.cache.has(t.context.urlHash)); }); test.serial("fetch cached", async (t) => { @@ -42,12 +44,12 @@ test.serial("fetch cached", async (t) => { // Fetch cached with empty cache t.false(h.cache.has(t.context.url)); t.deepEqual(await h.fetch(t.context.url, null, 300), { message: "hello" }); - t.deepEqual(h.cache.get(t.context.url), { message: "hello" }); + t.deepEqual(h.cache.get(t.context.urlHash), { message: "hello" }); // Fetch cached with warm cache and assert we have the right output. // Nock is set to only return 'hello' once. So if the request is not cached, it would return 'world'. t.deepEqual(await h.fetch(t.context.url, null, 300), { message: "hello" }); - t.deepEqual(h.cache.get(t.context.url), { message: "hello" }); + t.deepEqual(h.cache.get(t.context.urlHash), { message: "hello" }); // Let the cache expire mock.forwardTime(1, "hour"); @@ -59,11 +61,11 @@ test.serial("fetch cached", async (t) => { // Nock is set to only return 'hello' once, which we received before. This time it should return 'world' to complete // our sentence. If not, this would indicate the request is still cached somehow. t.deepEqual(await h.fetch(t.context.url, null, 300), { message: "world" }); - t.deepEqual(h.cache.get(t.context.url), { message: "world" }); + t.deepEqual(h.cache.get(t.context.urlHash), { message: "world" }); // Fetch cached with a warm cache again. t.deepEqual(await h.fetch(t.context.url, null, 300), { message: "world" }); - t.deepEqual(h.cache.get(t.context.url), { message: "world" }); + t.deepEqual(h.cache.get(t.context.urlHash), { message: "world" }); }); test.afterEach.always(() => { diff --git a/test/helpers/init.ts b/test/helpers/init.ts index 6886212..f1e0d5c 100644 --- a/test/helpers/init.ts +++ b/test/helpers/init.ts @@ -3,6 +3,7 @@ import crypto from "crypto"; import path from "path"; import moment from "moment"; import fs from "fs-extra"; +import nock from "nock"; import { Updater, Hugo, HugoOptions } from "../../src"; @@ -24,12 +25,24 @@ export function setAlfredEnv() { export function hugo(options?: HugoOptions) { setAlfredEnv(); + // Disable real HTTP requests with nock + nock.disableNetConnect(); + + if (!options) { + options = { + checkUpdates: false, + }; + } + return new Hugo(options); } export function updater(cacheTtl?: number | moment.Duration) { setAlfredEnv(); + // Disable real HTTP requests with nock + nock.disableNetConnect(); + const cache = new Cache({ dir: process.env.alfred_workflow_cache, }); diff --git a/test/helpers/mock.ts b/test/helpers/mock.ts index b4eb979..42ff560 100644 --- a/test/helpers/mock.ts +++ b/test/helpers/mock.ts @@ -15,7 +15,7 @@ export function forwardTime(amount?: DurationInputArg1, unit?: DurationInputArg2 mockdate.set(moment.utc().add(amount, unit)); } -export function npm(times: number = 1, pkg?: any, code: number = 200, latestVersion?: string) { +export function npm(times: number, pkg?: any, code: number = 200, latestVersion?: string) { pkg = pkg || readPkg.sync(); if (latestVersion !== null) { @@ -58,13 +58,28 @@ export function npm(times: number = 1, pkg?: any, code: number = 200, latestVers } // Mock requests - return nock("https://registry.npmjs.org") - .get("/" + pkg.name) - .times(times) - .reply(code, body); + const url = "https://registry.npmjs.org"; + const urlPath = "/" + pkg.name; + + if (times >= 0) { + for (let i = 0; i < times; i++) { + nock(url) + .get(urlPath) + .reply(code, body) + ; + } + + return; + } + + nock(url) + .persist() + .get(urlPath) + .reply(code, body) + ; } -export function packal(times: number = 1, code: number = 200, filename: string = "appcast.xml") { +export function packal(times: number, code: number = 200, filename: string = "appcast.xml") { filename = path.join("test", "helpers", "mocks", filename); // Response body @@ -74,10 +89,26 @@ export function packal(times: number = 1, code: number = 200, filename: string = body = fs.readFileSync(filename, { encoding: "utf8" }); } - return nock("https://github.com") - .get("/packal/repository/blob/master/my.work.flow/appcast.xml") - .times(times) - .reply(code, body); + // Mock requests + const url = "https://github.com"; + const urlPath = "/packal/repository/blob/master/my.work.flow/appcast.xml"; + + if (times >= 0) { + for (let i = 0; i < times; i++) { + nock(url) + .get(urlPath) + .reply(code, body) + ; + } + + return; + } + + nock(url) + .persist() + .get(urlPath) + .reply(code, body) + ; } export function file() { diff --git a/test/helpers/types.ts b/test/helpers/types.ts index 44c81c9..9c7b3a7 100644 --- a/test/helpers/types.ts +++ b/test/helpers/types.ts @@ -3,5 +3,6 @@ import { Hugo, Item } from "../../src"; export interface TestContext { hugo?: Hugo; url?: string; + urlHash?: string; items?: Item[]; } diff --git a/test/hugo.ts b/test/hugo.ts index 95f9066..8932e1e 100644 --- a/test/hugo.ts +++ b/test/hugo.ts @@ -97,29 +97,23 @@ test("test reset", (t) => { t.falsy(h.rerun); }); -test("input without action", (t) => { +test("input with no actions", (t) => { process.argv = [ "node", "index.js", - "foobar", + "foo", + "bar", + "hello", + "world", ]; const h = hugo(); - t.is(h.input, "foobar"); -}); - -test("input with action", (t) => { - process.argv = [ - "node", - "index.js", - "myaction", - "foobar", - ]; - - const h = hugo(); - - t.is(h.input, "foobar"); + t.is(h.input.length, 4); + t.is(h.input[0], "foo"); + t.is(h.input[1], "bar"); + t.is(h.input[2], "hello"); + t.is(h.input[3], "world"); }); test("input with no input", (t) => { @@ -130,7 +124,7 @@ test("input with no input", (t) => { const h = hugo(); - t.is(h.input, ""); + t.is(h.input.length, 0); }); test("notify", async (t) => { diff --git a/test/updates/npm.ts b/test/updates/npm.ts index 43d80ce..99ecda0 100644 --- a/test/updates/npm.ts +++ b/test/updates/npm.ts @@ -3,7 +3,9 @@ import semver from "semver"; import nock from "nock"; import readPkg from "read-pkg"; -import { updater } from "../helpers/init"; +import { UpdateSource } from "../../src"; + +import { updater, hugo } from "../helpers/init"; import { TestContext } from "../helpers/types"; import * as mock from "../helpers/mock"; @@ -13,11 +15,54 @@ test.beforeEach(() => { mock.date(); }); +test.serial("check with valid update source NPM", async (t) => { + // Mock requests + mock.npm(5); + + await t.notThrowsAsync(async () => { + const h = hugo({ + updateSource: "npm", + updateNotification: false, + }); + + return h.checkUpdates(); + }); + + await t.notThrowsAsync(async () => { + const h = hugo({ + updateSource: "NPM", + updateNotification: false, + }); + + return h.checkUpdates(); + }); + + await t.notThrowsAsync(async () => { + const h = hugo({ + updateSource: UpdateSource.NPM, + updateNotification: false, + }); + + return h.checkUpdates(); + }); + + await t.notThrowsAsync(async () => { + return updater().checkUpdates("npm"); + }); + + await t.notThrowsAsync(async () => { + return updater().checkUpdates("NPM"); + }); +}); + test.serial("check for updates uncached", async (t) => { const u = updater(); + // Mock request + mock.npm(1); + + // Package const pkg = readPkg.sync(); - const request = mock.npm(); const update = await u.checkUpdates("npm"); @@ -29,17 +74,19 @@ test.serial("check for updates uncached", async (t) => { t.is(update.version, semver.parse(pkg.version).inc("major").toString()); t.is(update.url, `https://www.npmjs.com/package/${pkg.name}`); t.true(update.checkedOnline); - t.true(request.isDone()); }); test.serial("check for updates uncached with custom package.json", async (t) => { const u = updater(); + // Package const pkg = { name: "alfred-my-workflow", version: "1.0.0", }; - const request = mock.npm(1, pkg); + + // Mock request + mock.npm(1, pkg); const update = await u.checkUpdates("npm", pkg); @@ -51,14 +98,16 @@ test.serial("check for updates uncached with custom package.json", async (t) => t.is(update.version, "2.0.0"); t.is(update.url, `https://www.npmjs.com/package/${pkg.name}`); t.true(update.checkedOnline); - t.true(request.isDone()); }); test.serial("check for updates cached", async (t) => { const u = updater(); + // Mock requests + mock.npm(2); + + // Package const pkg = readPkg.sync(); - const request = mock.npm(2); // Check for updates let update = await u.checkUpdates("npm"); @@ -71,7 +120,6 @@ test.serial("check for updates cached", async (t) => { t.is(update.version, semver.parse(pkg.version).inc("major").toString()); t.is(update.url, `https://www.npmjs.com/package/${pkg.name}`); t.true(update.checkedOnline); - t.is(request.pendingMocks().length, 1); // Forward time mock.forwardTime(30, "minutes"); @@ -85,7 +133,6 @@ test.serial("check for updates cached", async (t) => { } t.false(update.checkedOnline); - t.is(request.pendingMocks().length, 1); // Forward time mock.forwardTime(30, "minutes"); @@ -99,7 +146,6 @@ test.serial("check for updates cached", async (t) => { } t.true(update.checkedOnline); - t.true(request.isDone()); }); test.serial("check for updates cached with custom package.json", async (t) => { @@ -109,7 +155,9 @@ test.serial("check for updates cached with custom package.json", async (t) => { name: "alfred-my-workflow", version: "1.0.0", }; - const request = mock.npm(2, pkg); + + // Mock requests + mock.npm(2, pkg); // Check for updates let update = await u.checkUpdates("npm", pkg); @@ -122,7 +170,7 @@ test.serial("check for updates cached with custom package.json", async (t) => { t.is(update.version, "2.0.0"); t.is(update.url, `https://www.npmjs.com/package/${pkg.name}`); t.true(update.checkedOnline); - t.is(request.pendingMocks().length, 1); + t.is(nock.pendingMocks().length, 1); // Forward time mock.forwardTime(30, "minutes"); @@ -136,7 +184,7 @@ test.serial("check for updates cached with custom package.json", async (t) => { } t.false(update.checkedOnline); - t.is(request.pendingMocks().length, 1); + t.is(nock.pendingMocks().length, 1); // Forward time mock.forwardTime(30, "minutes"); @@ -150,7 +198,6 @@ test.serial("check for updates cached with custom package.json", async (t) => { } t.true(update.checkedOnline); - t.true(request.isDone()); }); test("check for updates with no package name set", async (t) => { @@ -179,12 +226,11 @@ test.serial("check for updates with unpublished package", async (t) => { const pkg = readPkg.sync(); // Mock request - const request = mock.npm(1, pkg, 404); + mock.npm(1, pkg, 404); const update = await u.checkUpdates("npm"); t.is(typeof update, "undefined"); - t.true(request.isDone()); }); test.serial("check for updates with unpublished package from custom package.json", async (t) => { @@ -196,12 +242,11 @@ test.serial("check for updates with unpublished package from custom package.json }; // Mock request - const request = mock.npm(1, pkg, 404); + mock.npm(1, pkg, 404); const update = await u.checkUpdates("npm", pkg); t.is(typeof update, "undefined"); - t.true(request.isDone()); }); test.serial("check for updates with package without latest dist-tag", async (t) => { @@ -210,9 +255,8 @@ test.serial("check for updates with package without latest dist-tag", async (t) const pkg = readPkg.sync(); // Mock request - const request = nock("https://registry.npmjs.org") + nock("https://registry.npmjs.org") .get("/" + pkg.name) - .once() .reply(200, JSON.stringify({ "name": pkg.name, "dist-tags": {}, @@ -231,8 +275,6 @@ test.serial("check for updates with package without latest dist-tag", async (t) await t.throwsAsync(async () => { return u.checkUpdates("npm"); }, "No latest version found in response."); - - t.true(request.isDone()); }); test.serial("check for updates with package without latest dist-tag from custom package.json", async (t) => { @@ -244,13 +286,11 @@ test.serial("check for updates with package without latest dist-tag from custom }; // Mock request - const request = mock.npm(1, pkg, 200, null); + mock.npm(1, pkg, 200, null); await t.throwsAsync(async () => { return u.checkUpdates("npm", pkg); }, "No latest version found in response."); - - t.true(request.isDone()); }); test.serial("check for updates when invalid version is returned", async (t) => { @@ -259,13 +299,17 @@ test.serial("check for updates when invalid version is returned", async (t) => { const pkg = readPkg.sync(); // Mock request - const request = mock.npm(1, pkg, 200, "foobar"); + mock.npm(1, pkg, 200, "foobar"); await t.throwsAsync(async () => { return u.checkUpdates("npm"); }, "Invalid version in response."); +}); - t.true(request.isDone()); +test.afterEach((t) => { + if (!nock.isDone()) { + t.fail("Not all requests were performed."); + } }); test.afterEach.always(() => { diff --git a/test/updates/packal.ts b/test/updates/packal.ts index cb6e024..397ee4b 100644 --- a/test/updates/packal.ts +++ b/test/updates/packal.ts @@ -1,4 +1,7 @@ import test from "ava"; +import nock from "nock"; + +import { UpdateSource } from "../../src"; import { updater, hugo } from "../helpers/init"; import * as mock from "../helpers/mock"; @@ -7,10 +10,51 @@ test.beforeEach(() => { mock.date(); }); -test("check for updates uncached", async (t) => { +test.serial("check with valid update source Packal", async (t) => { + // Mock requests + mock.packal(5); + + await t.notThrowsAsync(async () => { + const h = hugo({ + updateSource: "packal", + updateNotification: false, + }); + + return h.checkUpdates(); + }); + + await t.notThrowsAsync(async () => { + const h = hugo({ + updateSource: "Packal", + updateNotification: false, + }); + + return h.checkUpdates(); + }); + + await t.notThrowsAsync(async () => { + const h = hugo({ + updateSource: UpdateSource.Packal, + updateNotification: false, + }); + + return h.checkUpdates(); + }); + + await t.notThrowsAsync(async () => { + return updater().checkUpdates("packal"); + }); + + await t.notThrowsAsync(async () => { + return updater().checkUpdates("Packal"); + }); +}); + +test.serial("check for updates uncached", async (t) => { const u = updater(); - const request = mock.packal(); + // Mock request + mock.packal(1); const update = await u.checkUpdates("packal"); @@ -23,13 +67,12 @@ test("check for updates uncached", async (t) => { t.regex(update.url, /^https:\/\/encrypted\.google\.com\//); t.regex(update.url, /my\.work\.flow/); t.true(update.checkedOnline); - t.true(request.isDone()); }); -test("check for updates cached", async (t) => { +test.serial("check for updates cached", async (t) => { const u = updater(); - const request = mock.packal(2); + mock.packal(2); let update = await u.checkUpdates("packal"); @@ -42,7 +85,7 @@ test("check for updates cached", async (t) => { t.regex(update.url, /^https:\/\/encrypted\.google\.com\//); t.regex(update.url, /my\.work\.flow/); t.true(update.checkedOnline); - t.is(request.pendingMocks().length, 1); + t.is(nock.pendingMocks().length, 1); // Forward time mock.forwardTime(30, "minutes"); @@ -56,7 +99,7 @@ test("check for updates cached", async (t) => { } t.false(update.checkedOnline); - t.is(request.pendingMocks().length, 1); + t.is(nock.pendingMocks().length, 1); // Forward time mock.forwardTime(30, "minutes"); @@ -70,7 +113,6 @@ test("check for updates cached", async (t) => { } t.true(update.checkedOnline); - t.true(request.isDone()); }); test.serial("check for updates with no bundle id set", async (t) => { @@ -87,43 +129,40 @@ test.serial("check for updates with no bundle id set", async (t) => { test.serial("check for updates when no version is returned", async (t) => { const u = updater(); - const request = mock.packal(1, 200, "appcast-noversion.xml"); + mock.packal(1, 200, "appcast-noversion.xml"); await t.throwsAsync(async () => { return u.checkUpdates("packal"); }, "No version found."); - - t.true(request.isDone()); }); test.serial("check for updates when invalid version is returned", async (t) => { const u = updater(); - const request = mock.packal(1, 200, "appcast-invalidversion.xml"); + mock.packal(1, 200, "appcast-invalidversion.xml"); await t.throwsAsync(async () => { return u.checkUpdates("packal"); }, "Invalid version in response."); - - t.true(request.isDone()); }); test.serial("check for updates with unpublished workflow", async (t) => { const u = updater(); // Mock request - const request = mock.packal(1, 404); + mock.packal(1, 404); const update = await u.checkUpdates("packal"); t.is(typeof update, "undefined"); - t.true(request.isDone()); }); -test.afterEach.always(() => { - mock.cleanDate(); +test.afterEach((t) => { + if (!nock.isDone()) { + t.fail("Not all requests were performed."); + } }); -test.after.always(() => { +test.afterEach.always(() => { mock.cleanAll(); }); diff --git a/test/updates/snapshots/updater.ts.md b/test/updates/snapshots/updater.ts.md index 1b2b905..dee1ff1 100644 --- a/test/updates/snapshots/updater.ts.md +++ b/test/updates/snapshots/updater.ts.md @@ -19,3 +19,35 @@ Generated by [AVA](https://ava.li). task: 'wfUpdate', }, } + +## check update item + +> Snapshot 1 + + { + arg: 'https://encrypted.google.com/search?sourceid=chrome&ie=UTF-8&q=site%3Apackal.org%20my.work.flow&btnI', + icon: { + path: '/Users/maarten/Projects/Alfred/alfred-hugo/icon.png', + }, + subtitle: 'Version 2.0.0 is available. Current version: 1.0.0.', + title: 'Workflow update available!', + variables: { + task: 'wfUpdate', + }, + } + +## update item only + +> Snapshot 1 + + { + arg: 'https://encrypted.google.com/search?sourceid=chrome&ie=UTF-8&q=site%3Apackal.org%20my.work.flow&btnI', + icon: { + path: '/Users/maarten/Projects/Alfred/alfred-hugo/icon.png', + }, + subtitle: 'Version 2.0.0 is available. Current version: 1.0.0.', + title: 'Workflow update available!', + variables: { + task: 'wfUpdate', + }, + } diff --git a/test/updates/snapshots/updater.ts.snap b/test/updates/snapshots/updater.ts.snap index 388ed27150cb7c9616f6ade8d03ae2e52ca7e471..44fb55a0a5bad4cbd7a264110ee17a12df6d35ec 100644 GIT binary patch literal 516 zcmV+f0{i_zRzVb=?9)V$=P z%7T*A6utEP{Pdhuz2y8{{o>TbqT~$w;{4L05wL;tC z%#u`9W5?;O21Y(c#zvq+VYaelCgG^r%BBqtRnU>ufORGgWgr(mRKpl6_vS*(y)mYA87m;`j3f^%t6QEFa^LK#Gj zm4YEiksg|vtSAObg#%p$a+E@8K}uptD#AQPunSipxsbCgu_zNHRSXJwrt?6ltLP!k zgc{O7WvamF)Mi3c#*7gmjA+heDM&2IfO}g%v>50q{oKUFqLS1+{eYr;kltc_$DFjH z)D-KPnEIs{i|L5=bpKXK?p!)=QI#N4? zu+Wj0k!CLTgzy4}9Wfw^QR(=5O2pD(+-*3%6a!Y_tkF4XRkte_4aGGp*P9V_`ZT~o zdgZO!;1Z97?BiY_MwPA(4-qT^TpOX2SF_v^VM&mwLSdi?AV(L38#9_%`{v)GpZ6%b{x4>v!8zJV}-ZB6c&b5@}#5^ z=dEW`dQCfR%{pypW%FShR*IJS^C6IunT@FSr(=_jGDDF8rBbtyw53SyD$)#klDUMA iL)DKxK@uBr6ng)6)l~JT?v8q$@z7t{uT#Nr0ssJGLCD_# diff --git a/test/updates/updater.ts b/test/updates/updater.ts index 11bec0a..4bfd84f 100644 --- a/test/updates/updater.ts +++ b/test/updates/updater.ts @@ -1,7 +1,7 @@ import test from "ava"; import sinon from "sinon"; - -import { UpdateSource } from "../../src"; +import moment from "moment"; +import nock from "nock"; import { hugo, updater } from "../helpers/init"; import * as mock from "../helpers/mock"; @@ -12,92 +12,105 @@ test.beforeEach(() => { mock.date(); }); -test.serial("check with valid update source NPM", async (t) => { - t.notThrows(() => { +test("check with invalid update source as string", async (t) => { + t.throws(() => { hugo({ - updateSource: "npm", + updateSource: "foobar", }); - }); + }, "Invalid update source."); - t.notThrows(() => { - hugo({ - updateSource: "NPM", - }); - }); + await t.throwsAsync(async () => { + return updater().checkUpdates("foobar"); + }, "Invalid update source."); +}); - t.notThrows(() => { - hugo({ - updateSource: UpdateSource.NPM, - }); +test.serial("check update with no new updates", async (t) => { + const h = hugo({ + updateSource: "packal", }); - // Mock requests - mock.npm(2); + // Ensure that no new version exists + process.env.alfred_workflow_version = "3.0.0"; - await t.notThrowsAsync(async () => { - return updater().checkUpdates("npm"); - }); + // Mock request + mock.packal(1); - await t.notThrowsAsync(async () => { - return updater().checkUpdates("NPM"); - }); + // Check for updates + await h.checkUpdates(); + t.true(nock.isDone()); + + // Check output buffer + t.is(h.output.items.length, 0); }); -test.serial("check with valid update source Packal", async (t) => { - t.notThrows(() => { - hugo({ - updateSource: "packal", - }); +test.serial("update notification only when checked online", async (t) => { + const h = hugo({ + updateSource: "packal", + updateItem: false, }); - t.notThrows(() => { - hugo({ - updateSource: "Packal", - }); - }); + const notifyStub = sinon.stub(h, "notify"); - t.notThrows(() => { - hugo({ - updateSource: UpdateSource.Packal, - }); - }); + // Mock request + mock.packal(1); - mock.packal(2); + // Check for updates + await h.checkUpdates(); + t.true(nock.isDone()); - await t.notThrowsAsync(async () => { - return updater().checkUpdates("packal"); - }); + // Check for updates again (should be cached) + await h.checkUpdates(); - await t.notThrowsAsync(async () => { - return updater().checkUpdates("Packal"); - }); + // Notify should only be called once + t.true(notifyStub.calledOnce); + + // Make sure update item was not added + t.is(h.items.length, 0); }); -test("check with invalid update source as string", async (t) => { - t.throws(() => { - hugo({ - updateSource: "foobar", - }); - }, "Invalid update source."); +test.serial("update item only", async (t) => { + const h = hugo({ + updateSource: "packal", + updateNotification: false, + }); - await t.throwsAsync(async () => { - return updater().checkUpdates("foobar"); - }, "Invalid update source."); + const notifyStub = sinon.stub(h, "notify"); + + // Mock request + mock.packal(1); + + // Check for updates + await h.checkUpdates(); + t.true(nock.isDone()); + + // Check for updates again (should be cached) + await h.checkUpdates(); + + // Notify should only be called once + t.false(notifyStub.calledOnce); + + // Make sure update item was added + t.is(h.items.length, 1); + + // Check update item + const item = h.output.items.pop(); + + t.snapshot(item); }); -test("check update notification item", async (t) => { +test.serial("check update item", async (t) => { const h = hugo({ updateSource: "packal", }); - const request = mock.packal(); + // Mock request + mock.packal(1); // Check for updates await h.checkUpdates(); - t.true(request.isDone()); + t.true(nock.isDone()); // Check output buffer - t.true(Array.isArray(h.output.items)); t.is(h.output.items.length, 1); // Check update item @@ -110,13 +123,13 @@ test.serial("check for unpublished workflow twice within interval", async (t) => const u = updater(); // Mock request - const request = mock.packal(1, 404); + mock.packal(1, 404); // Check for update let update = await u.checkUpdates("packal"); t.is(typeof update, "undefined"); - t.true(request.isDone()); + t.true(nock.isDone()); // Check for update the second time shortly after. No request should be made. update = await u.checkUpdates("packal"); @@ -124,25 +137,73 @@ test.serial("check for unpublished workflow twice within interval", async (t) => t.is(typeof update, "undefined"); }); -test("check for updates with updates disabled", async (t) => { +test.serial("check for updates with updates disabled", async (t) => { const h = hugo({ checkUpdates: false, + updateSource: "npm", }); + // Mock request + mock.npm(1); + const update = await h.checkUpdates(); t.falsy(update); + t.false(nock.isDone()); + + nock.cleanAll(); }); -test("check for updates with update notification and item disabled", async (t) => { +test.serial("check for updates with update notification and item disabled", async (t) => { const h = hugo({ updateNotification: false, updateItem: false, + updateSource: "npm", }); + // Mock request + mock.npm(1); + const update = await h.checkUpdates(); t.falsy(update); + t.false(nock.isDone()); + + nock.cleanAll(); +}); + +test.serial("check for updates with updateInterval undefined", async (t) => { + const h = hugo({ + updateInterval: undefined, + updateSource: "npm", + }); + + // Mock request + mock.npm(1); + + const update = await h.checkUpdates(); + + t.falsy(update); + t.false(nock.isDone()); + + nock.cleanAll(); +}); + +test.serial("check for updates with updateInterval under one second", async (t) => { + const h = hugo({ + updateInterval: moment.duration(1, "milliseconds"), + updateSource: "npm", + }); + + // Mock request + mock.npm(1); + + const update = await h.checkUpdates(); + + t.falsy(update); + t.false(nock.isDone()); + + nock.cleanAll(); }); test.serial("check for updates with invalid workflow version", async (t) => { @@ -152,12 +213,13 @@ test.serial("check for updates with invalid workflow version", async (t) => { process.env.alfred_workflow_version = "foobar"; - const request = mock.packal(); + // Mock request + mock.packal(1); const update = await h.checkUpdates(); t.falsy(update); - t.true(request.isDone()); + t.true(nock.isDone()); }); test.serial("check for updates with updates with unpublished package", async (t) => { @@ -166,12 +228,12 @@ test.serial("check for updates with updates with unpublished package", async (t) }); // Mock request - const request = mock.packal(1, 404); + mock.packal(1, 404); const update = await h.checkUpdates(); t.falsy(update); - t.true(request.isDone()); + t.true(nock.isDone()); }); test.serial("check for updates with updates when exception occurs", async (t) => { @@ -182,12 +244,12 @@ test.serial("check for updates with updates when exception occurs", async (t) => }); // Mock request - const request = mock.packal(2, 500); + mock.packal(2, 500); let update = await h.checkUpdates(); t.falsy(update); - t.is(request.pendingMocks().length, 1); + t.is(nock.pendingMocks().length, 1); t.false(consoleStub.called); // Clear cache @@ -199,16 +261,18 @@ test.serial("check for updates with updates when exception occurs", async (t) => update = await h.checkUpdates(); t.falsy(update); - t.true(request.isDone()); + t.true(nock.isDone()); t.true(consoleStub.calledWith("Request failed with status code 500")); }); +test.afterEach((t) => { + if (!nock.isDone()) { + t.fail("Not all requests were performed."); + } +}); + test.afterEach.always(() => { console.error = backupConsoleError; - mock.cleanDate(); -}); - -test.after.always(() => { mock.cleanAll(); }); diff --git a/yarn.lock b/yarn.lock index 266ba72..d0c5b86 100644 --- a/yarn.lock +++ b/yarn.lock @@ -388,9 +388,9 @@ "@types/node" "*" "@types/node@*", "@types/node@^12.0.2": - version "12.0.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.4.tgz#46832183115c904410c275e34cf9403992999c32" - integrity sha512-j8YL2C0fXq7IONwl/Ud5Kt0PeXw22zGERt+HSSnwbKOJVsAGkEz3sFCYwaF9IOuoG1HOtE0vKCj6sXF7Q0+Vaw== + version "12.0.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.7.tgz#4f2563bad652b2acb1722d7e7aae2b0ff62d192c" + integrity sha512-1YKeT4JitGgE4SOzyB9eMwO0nGVNkNEsm9qlIt1Lqm/tG2QEiSMTD4kS3aO6L+w5SClLVxALmIBESK6Mk5wX0A== "@types/normalize-package-data@*", "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -825,16 +825,16 @@ cache-base@^1.0.1: unset-value "^1.0.0" cacheable-request@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.0.0.tgz#4a1727414e02ac4af82560c4da1b61daa3fa2b63" - integrity sha512-2N7AmszH/WPPpl5Z3XMw1HAP+8d+xugnKQAeKvxFZ/04dbT/CAznqwbl+7eSr3HkwdepNwtb2yx3CAMQWvG01Q== + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== dependencies: clone-response "^1.0.2" - get-stream "^4.0.0" + get-stream "^5.1.0" http-cache-semantics "^4.0.0" keyv "^3.0.0" - lowercase-keys "^1.0.1" - normalize-url "^3.1.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" responselike "^1.0.2" caching-transform@^3.0.2: @@ -1365,9 +1365,9 @@ dot-prop@^4.1.0: is-obj "^1.0.0" dot-prop@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.0.0.tgz#64b7968af349c3a9f966aa12658dbd5829f6b953" - integrity sha512-RTmaF2jx3nOBO2GvtFqjnDLycjFUMqt+2pwRx7JVYa81lDauoj9aNkyrJI2ikR58FbBIchiIlRiGG+muLJ4oHQ== + version "5.0.1" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.0.1.tgz#e26c283bd1f10aab01e782371a751fb52cc3cb1c" + integrity sha512-5BKAm3KC6kgHOm5WqekMXd0HHRhilE0aJzBuOqtrPo2RDS2FTaOeuF5CEsHvZ8ETfjC9N3BufL6sxEMV8w/IIA== dependencies: is-obj "^1.0.0" @@ -1718,6 +1718,13 @@ get-stream@^4.0.0, get-stream@^4.1.0: dependencies: pump "^3.0.0" +get-stream@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9" + integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw== + dependencies: + pump "^3.0.0" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" @@ -2558,15 +2565,10 @@ log-symbols@^2.2.0: dependencies: chalk "^2.0.1" -lolex@^2.3.2: - version "2.7.5" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.7.5.tgz#113001d56bfc7e02d56e36291cc5c413d1aa0733" - integrity sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q== - -lolex@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-4.0.1.tgz#4a99c2251579d693c6a083446dae0e5c3844d3fa" - integrity sha512-UHuOBZ5jjsKuzbB/gRNNW8Vg8f00Emgskdq2kvZxgBJCS0aqquAuXai/SkWORlKeZEiNQWZjFZOqIUcH9LqKCw== +lolex@^4.0.1, lolex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/lolex/-/lolex-4.1.0.tgz#ecdd7b86539391d8237947a3419aa8ac975f0fe1" + integrity sha512-BYxIEXiVq5lGIXeVHnsFzqa1TxN5acnKnPCdlZSpzm8viNEOhiigupA4vTQ9HEFQ6nLTQ9wQOgBknJgzUYQ9Aw== loud-rejection@^1.0.0: version "1.6.0" @@ -2589,6 +2591,11 @@ lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + lru-cache@^4.0.1: version "4.1.5" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" @@ -2818,9 +2825,9 @@ ms@2.0.0: integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= ms@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== nanomatch@^1.2.9: version "1.2.13" @@ -2855,14 +2862,14 @@ nice-try@^1.0.4: integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== nise@^1.4.10: - version "1.4.10" - resolved "https://registry.yarnpkg.com/nise/-/nise-1.4.10.tgz#ae46a09a26436fae91a38a60919356ae6db143b6" - integrity sha512-sa0RRbj53dovjc7wombHmVli9ZihXbXCQ2uH3TNm03DyvOSIQbxg+pbqDKrk2oxMK1rtLGVlKxcB9rrc6X5YjA== + version "1.5.0" + resolved "https://registry.yarnpkg.com/nise/-/nise-1.5.0.tgz#d03ea0e6c1b75c638015aa3585eddc132949a50d" + integrity sha512-Z3sfYEkLFzFmL8KY6xnSJLRxwQwYBjOXi/24lb62ZnZiGA0JUzGGTI6TBIgfCSMIDl9Jlu8SRmHNACLTemDHww== dependencies: "@sinonjs/formatio" "^3.1.0" "@sinonjs/text-encoding" "^0.7.1" just-extend "^4.0.2" - lolex "^2.3.2" + lolex "^4.1.0" path-to-regexp "^1.7.0" nock@^10.0.6: @@ -2906,10 +2913,10 @@ normalize-path@^3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -normalize-url@^3.1.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" - integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== +normalize-url@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.3.0.tgz#9c49e10fc1876aeb76dba88bf1b2b5d9fa57b2ee" + integrity sha512-0NLtR71o4k6GLP+mr6Ty34c5GA6CMoEsncKJxvQd8NzPxaHRJNnb5gZE8R1XF4CPIS7QPHLJ74IFszwtNVAHVQ== npm-run-all@^4.1.5: version "4.1.5" @@ -3575,9 +3582,9 @@ resolve-url@^0.2.1: integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= resolve@^1.10.0, resolve@^1.3.2: - version "1.11.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.0.tgz#4014870ba296176b86343d50b60f3b50609ce232" - integrity sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw== + version "1.11.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.1.tgz#ea10d8110376982fef578df8fc30b9ac30a07a3e" + integrity sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw== dependencies: path-parse "^1.0.6" From eebcbc82255dc02bf44768aab52732cb81d4b3fb Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sat, 8 Jun 2019 19:43:46 +0200 Subject: [PATCH 07/35] Add initial new documentation --- docs/cache.md | 35 +++++++++++++++++++++++++++++++++++ docs/config.md | 24 ++++++++++++++++++++++++ docs/fetch.md | 37 +++++++++++++++++++++++++++++++++++++ docs/updates.md | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 135 insertions(+) create mode 100644 docs/cache.md create mode 100644 docs/config.md create mode 100644 docs/fetch.md create mode 100644 docs/updates.md diff --git a/docs/cache.md b/docs/cache.md new file mode 100644 index 0000000..85d9cd7 --- /dev/null +++ b/docs/cache.md @@ -0,0 +1,35 @@ +# Cache + +As Hugo is a framework for building [script filters](https://www.alfredapp.com/help/workflows/inputs/script-filter/), you often get to deal with dynamic data. [Fetching](./fetch.md) and processing it can take quite some time which means users have to wait each time they run your workflow. + +To make your workflow more responsive, Hugo initialises a [cache](https://www.npmjs.com/package/@cloudstek/cache) for you to use in your workflow. It's a simple key/value store stored as JSON in your workflow cache directory. Each item has a TTL (Time To Live) of 1 hour by default, after that time it will be removed from the cache. You can override this TTL or even disable it when setting a cache value. Disabling the TTL means it will be available forever so it acts as a normal key/value store. + +If you want to store configuration details for your workflow, please do not use the cache but use the [config](./config) instead. It has the same API but is stored in a different directory and has no TTL set by default, making it act as a proper key/value store. + +If you deal with processing local files a lot, please also see the [file cache](./file-cache.md) :star: + +For more details about [Cache](https://www.npmjs.com/package/@cloudstek/cache), please see: https://www.npmjs.com/package/@cloudstek/cache. + +### Example + +```js +import { Hugo } from "alfred-hugo"; + +const hugo = new Hugo(); + +// Store "foo" with value "bar" for 1 hour +hugo.cache.set("foo", "bar"); + +// Store "pie" with value "apple" for 5 seconds +hugo.cache.set("pie", "apple", 5); + +hugo.cache.has("pie"); // true +hugo.cache.get("pie"); // apple + +// Wait 5 seconds. ZzzZzZzZZz +// sleep(5000); + +hugo.cache.has("pie"); // false +hugo.cache.get("pie"); // undefined +``` + diff --git a/docs/config.md b/docs/config.md new file mode 100644 index 0000000..b52877d --- /dev/null +++ b/docs/config.md @@ -0,0 +1,24 @@ +# Config + +Hugo provides an easy way to store your workflow configuration by providing you with a simple key/value store that is automatically stored in a JSON file. No need to deal with handling files and serialising data, simply get and set your values. + +Under the hood this uses the same package which handles the [cache](./cache.md) in Hugo, but with expiration of items disabled. For more details about the [Cache](https://www.npmjs.com/package/@cloudstek/cache) package, please see: https://www.npmjs.com/package/@cloudstek/cache. + +You *can* let a configuration item expire but that is entirely optional and I'm not sure why you'd want that. Use the [cache](./cache) instead :wink: + +### Example + +```js +import { Hugo } from "alfred-hugo"; + +const hugo = new Hugo(); + +// No need to load anything, just use it! + +// Store "foo" with value "bar" +hugo.config.set("foo", "bar"); + +// Get "foo" +console.log(hugo.config.get("foo")); // bar +``` + diff --git a/docs/fetch.md b/docs/fetch.md new file mode 100644 index 0000000..490bcfb --- /dev/null +++ b/docs/fetch.md @@ -0,0 +1,37 @@ +# Fetch + +Hugo has a built-in method to make fetching data from other sites (e.g. REST APIs) a breeze and if you like, it can also cache the result for you, leveraging the built-in [cache](./cache.md). + +Behind the scenes [Axios](https://github.com/axios/axios) is used to make the request and by default it automatically parses JSON for you. This means you can directly use your data. + +*Note that this is only a simple wrapper function to make a GET request. Though you can specify the options for Axios, you might want to look into using Axios (or other libraries) directly if you need advanced options.* + +### Example + +```js +import { Hugo } from "alfred-hugo"; + +const hugo = new Hugo(); + +// Fetch single todo item without caching +hugo + .fetch("https://jsonplaceholder.typicode.com/todos/1") + .then((data) => { + console.log(`#${data.id} ${data.title}`); + }); + +// Fetch todo list and cache it for 1 hour +hugo + .fetch("https://jsonplaceholder.typicode.com/todos", {/* Axios options */}, 3600) + .then((data) => { + console.log(`${data.length} todo items fetched.`); + }); + +// Fetch the todo list again, this time it's cached! +hugo + .fetch("https://jsonplaceholder.typicode.com/todos", {/* Axios options */}, 3600) + .then((data) => { + console.log(`${data.length} todo items loaded from cache.`); + }); +``` + diff --git a/docs/updates.md b/docs/updates.md new file mode 100644 index 0000000..472809f --- /dev/null +++ b/docs/updates.md @@ -0,0 +1,39 @@ +# Updates + +If your workflow has been published on NPM or Packal, Hugo can automatically notifiy the user if there is an update available. + +There are two ways to notify the user of an available update, with a notification and with an item on the bottom of the list. You're free to choose either one or both. If you disable both methods, you effectively disable checking for updates. + +### Examples + +#### Defaults + +```js +import { Hugo } from "alfred-hugo"; + +const hugo = new Hugo({ + checkUpdates: true, // Check for updates! + updateInterval: moment.duration(1, "day"), // Check for updates once a day + updateItem: true, // Show an item on the bottom of the list + updateNotification: true, // Show a notification + updateSource: "npm" // Check NPM for updates +}); +``` + +#### Disable updates + +```js +import { Hugo } from "alfred-hugo"; + +const hugo = new Hugo({ + checkUpdates: false +}); + +// Or (but not recommended) + +const hugo = new Hugo({ + updateItem: false, + updateNotification: false +}); +``` + From 611c3825f2f0128ffa4e70cb9b037f026a34ba28 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Tue, 18 Jun 2019 00:48:15 +0200 Subject: [PATCH 08/35] Updates to the file cache --- src/file-cache.ts | 16 ++++++++-------- test/file-cache.ts | 16 ++++------------ 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/src/file-cache.ts b/src/file-cache.ts index b393372..f75cd0e 100644 --- a/src/file-cache.ts +++ b/src/file-cache.ts @@ -35,22 +35,22 @@ export class FileCache extends EventEmitter { /** * Get (cached) contents. + * + * Emits the "change" event with the cache instance, file and hash of that file when the file has been changed + * or expired from the cache. */ public get() { if (utils.fileExists(this.filePath) === false) { return null; } - // Read file - const file = fs.readFileSync(this.filePath, "utf8"); - - // Calculate file hash - const hash = Crypto.createHash("sha1").update(file, "utf8").digest("hex"); + // Get file fstat + const stat = fs.statSync(this.filePath); - if (this.cache.has("hash") === false || this.cache.get("hash") !== hash) { - this.emit("change", this.cache, file, hash); + if (this.cache.has("mtime") === false || this.cache.get("mtime") !== stat.mtimeMs) { + this.emit("change", this.cache, fs.readFileSync(this.filePath, "utf8")); - this.cache.set("hash", hash); + this.cache.set("mtime", stat.mtimeMs); this.cache.commit(); return this.cache.all(); diff --git a/test/file-cache.ts b/test/file-cache.ts index 9b895b1..56dcf82 100644 --- a/test/file-cache.ts +++ b/test/file-cache.ts @@ -16,12 +16,9 @@ test.serial("process file and cache it", (t) => { const cachedFile = h.cacheFile(tmpFile); // Listen to change event to process data - cachedFile.once("change", (cache, file, hash) => { + cachedFile.once("change", (cache, file) => { t.is(cache.constructor.name, "Cache"); - t.is(typeof file, "string"); - t.true(file.length > 0); - t.is(typeof hash, "string"); - t.true(hash.length > 0); + t.is("Hello world!", file); cache.set("hello", "world!"); }); @@ -32,7 +29,6 @@ test.serial("process file and cache it", (t) => { // Verify data t.is(typeof data, "object"); t.is(data.hello, "world!"); - t.true(data.hash.length > 0); // Listen to change event (which should not be emitted now) cachedFile.once("change", () => { @@ -45,12 +41,9 @@ test.serial("process file and cache it", (t) => { cachedFile.removeAllListeners(); // Listen to change event to process data - cachedFile.once("change", (cache, file, hash) => { + cachedFile.once("change", (cache, file) => { t.is(cache.constructor.name, "Cache"); - t.is(typeof file, "string"); - t.true(file.length > 0); - t.is(typeof hash, "string"); - t.true(hash.length > 0); + t.is("Foobar", file); cache.set("foo", "bar"); }); @@ -64,7 +57,6 @@ test.serial("process file and cache it", (t) => { // Verify data t.is(typeof data, "object"); t.is(data.foo, "bar"); - t.true(data.hash.length > 0); }); test.serial("process non-existing file", (t) => { From 3560babd2d40f6f0a50ae51f8181f1b09c17847b Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Tue, 18 Jun 2019 00:48:48 +0200 Subject: [PATCH 09/35] Make custom matching respect match option like Alfred --- src/hugo.ts | 15 +++++++++++++-- test/matching.ts | 18 ++++++++++++++++++ test/snapshots/matching.ts.md | 2 ++ test/snapshots/matching.ts.snap | Bin 451 -> 472 bytes 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/hugo.ts b/src/hugo.ts index bb4f13a..2d9ed5d 100644 --- a/src/hugo.ts +++ b/src/hugo.ts @@ -42,7 +42,7 @@ export class Hugo { // Set defaults for FuseJS this.fuseDefaults = { - keys: ["title"], + keys: ["match"], threshold: 0.4, }; @@ -315,6 +315,17 @@ export class Hugo { return candidates; } + // Set match attribute to title when missing to mimic Alfred matching behaviour + if (options.keys.indexOf("match") >= 0) { + candidates = candidates.map((candidate) => { + if (!candidate.match) { + candidate.match = candidate.title; + } + + return candidate; + }); + } + // Create fuse.js fuzzy search object const fuse = new Fuse(candidates, options); @@ -397,7 +408,7 @@ export class Hugo { title: "Workflow update available!", subtitle: `Version ${latest} is available. Current version: ${current}.`, icon: { - path: this.workflowMeta.icon || "", + path: this.workflowMeta.icon, }, arg: result.url, variables: { diff --git a/test/matching.ts b/test/matching.ts index 71954ba..76beba6 100644 --- a/test/matching.ts +++ b/test/matching.ts @@ -17,6 +17,7 @@ test.beforeEach((t) => { }, { title: "Eep", + match: "Abra", subtitle: "eep foo blep", }, { @@ -33,6 +34,23 @@ test.beforeEach((t) => { test("exact match", (t) => { const h = hugo(); + const matches = h.match(t.context.items, "Abra", { + threshold: 0, + shouldSort: false, + }); + + t.true(Array.isArray(matches)); + + // Should match both item with match property as well as title property + // See https://www.alfredapp.com/help/workflows/inputs/script-filter/json/#match + t.is(matches.length, 2); + t.deepEqual(matches[0], t.context.items[2]); + t.deepEqual(matches[1], t.context.items[4]); +}); + +test("exact match by single key", (t) => { + const h = hugo(); + const matches = h.match(t.context.items, "foo bar bleep", { keys: ["subtitle"], threshold: 0, diff --git a/test/snapshots/matching.ts.md b/test/snapshots/matching.ts.md index 11ff301..476a0db 100644 --- a/test/snapshots/matching.ts.md +++ b/test/snapshots/matching.ts.md @@ -22,6 +22,7 @@ Generated by [AVA](https://ava.li). title: 'Bar', }, { + match: 'Abra', subtitle: 'eep foo blep', title: 'Eep', }, @@ -41,6 +42,7 @@ Generated by [AVA](https://ava.li). title: 'Bar', }, { + match: 'Abra', subtitle: 'eep foo blep', title: 'Eep', }, diff --git a/test/snapshots/matching.ts.snap b/test/snapshots/matching.ts.snap index 70b6e52bb04dd0d585b5de4330cf1043add919a4..804aa002ce11f19801df75a68363a71dd8226449 100644 GIT binary patch literal 472 zcmV;}0Vn=JRzVmQ2<00000000Bk zlfO#>VHn5X_kK!ccaaoL3N5uXMnnioX@lh85Df))cA;^0q8HQ{*w_*-t24%bFA|X7H8AStBT*4Yf){zXdgG^Fsf{L+HNjs*rRVj)> z=m?<#p`(=Me;c5xIxA&m%_%unzB?uFOyFm5q%e}CZf7a2?;Ba0a_v%8Rfgt(93WLM z%J-o6Kx#8?AuIEv?dPHFzB8yqML@%zcC+ooAO?)pxN16>rII1CCzW_7=}gI zXwz@%no<1YptOQDj--%HL`MpK9*WGfqqc`v9S>hR9yVPMQO>~>$6m;jLAiyT_$zq{ z0zOmPGs-99mEW7iSSIv})_1b`Wt=NZJUMNJ?5k2R9uB2M4Dvc5@Ub z2e*QYga4wIPP!BvJU8~krqFb&fx|uAJURCbIay|m32bNm`#O^P%EewEBUf7Wff&CI z1;(Z;^@G}Ctv;JBFHEt^I=Q<^i7}BWE=56-maxX4O=y=t35}CHMpE2y^mC$?Q&p8w zh*5yi2vP1g0PdErNsKfDtx+>sP8-K&rbt5DYMSPvSs=&IjTaSr z&?g|zP}PeDde9JFTZ2{w4=Qz|VRv{Hj4;7x$L(O@)F|ePmf6}+j%+(>=#Gbzx*#!W z+k?ePdCRu*eZ!Pw>%>6)Y`^3Z$v4{9`|A4tjQS>15-zL9}Ah#z7wAIX3P007aI&>{c; From ea7fc921ad689fa685ef4830a8646258cc474416 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Tue, 18 Jun 2019 00:48:58 +0200 Subject: [PATCH 10/35] Clean up --- src/types.ts | 2 +- test/updates/snapshots/updater.ts.md | 16 ---------------- test/updates/snapshots/updater.ts.snap | Bin 516 -> 482 bytes 3 files changed, 1 insertion(+), 17 deletions(-) diff --git a/src/types.ts b/src/types.ts index 5d59b60..d130894 100644 --- a/src/types.ts +++ b/src/types.ts @@ -31,7 +31,7 @@ export interface WorkflowMeta { bundleId?: string; data?: string; cache?: string; - icon?: string; + icon: string; } export interface AlfredMeta { diff --git a/test/updates/snapshots/updater.ts.md b/test/updates/snapshots/updater.ts.md index dee1ff1..9b9a7f3 100644 --- a/test/updates/snapshots/updater.ts.md +++ b/test/updates/snapshots/updater.ts.md @@ -4,22 +4,6 @@ The actual snapshot is saved in `updater.ts.snap`. Generated by [AVA](https://ava.li). -## check update notification item - -> Snapshot 1 - - { - arg: 'https://encrypted.google.com/search?sourceid=chrome&ie=UTF-8&q=site%3Apackal.org%20my.work.flow&btnI', - icon: { - path: '/Users/maarten/Projects/Alfred/alfred-hugo/icon.png', - }, - subtitle: 'Version 2.0.0 is available. Current version: 1.0.0.', - title: 'Workflow update available!', - variables: { - task: 'wfUpdate', - }, - } - ## check update item > Snapshot 1 diff --git a/test/updates/snapshots/updater.ts.snap b/test/updates/snapshots/updater.ts.snap index 44fb55a0a5bad4cbd7a264110ee17a12df6d35ec..79160a29d225335a97156eb0dc49ea89d388a3ee 100644 GIT binary patch literal 482 zcmV<80UiE9RzVJR7$ z0}@Mr09BcpSXkJZn3x#w9ZGK7rlnE|!6bq)1fLAXnt_~IOhb-JZ#Z{-ts_+@goTbgh%|GtCxjO;?1&ywj7rD< zrbH|q#@&YFOVMLh&Kj-l^@Ww{&xYcfRhF6&b-FabLVA_OTJHc4gzVx@AO_X84mS`? z0UR2k!&md%5n)DEQN?Y|b-;!jOFK*|E<$?|*Kp0|%BFqF1KKv??6p`*7HYfygsIzK z6A;dDj=dr*?;2H!C_9c^s@XH&Y^w11g~EwGl{`68iSyQ_Il9U^ZM}Bdz$)g`=B*4Y z_vS+&BQqaS?T^wXEoG7-JxZl!A=#25xvNMs=t$-gnhpzo>gl7N{%1Ws0;el?YT5(<0G?ptCjbBd literal 516 zcmV+f0{i_zRzVb=?9)V$=P z%7T*A6utEP{Pdhuz2y8{{o>TbqT~$w;{4L05wL;tC z%#u`9W5?;O21Y(c#zvq+VYaelCgG^r%BBqtRnU>ufORGgWgr(mRKpl6_vS*(y)mYA87m;`j3f^%t6QEFa^LK#Gj zm4YEiksg|vtSAObg#%p$a+E@8K}uptD#AQPunSipxsbCgu_zNHRSXJwrt?6ltLP!k zgc{O7WvamF)Mi3c#*7gmjA+heDM&2IfO}g%v>50q{oKUFqLS1+{eYr;kltc_$DFjH z)D- Date: Tue, 18 Jun 2019 00:49:15 +0200 Subject: [PATCH 11/35] Remove examples --- examples/actions.js | 47 - examples/basic-filter.js | 31 - examples/comments.json | 3502 -------------------------------------- examples/fetch-json.js | 33 - examples/file-cache.js | 95 -- 5 files changed, 3708 deletions(-) delete mode 100644 examples/actions.js delete mode 100644 examples/basic-filter.js delete mode 100644 examples/comments.json delete mode 100644 examples/fetch-json.js delete mode 100644 examples/file-cache.js diff --git a/examples/actions.js b/examples/actions.js deleted file mode 100644 index 0d9c2bc..0000000 --- a/examples/actions.js +++ /dev/null @@ -1,47 +0,0 @@ -'use strict'; - -/** - * Multiple acitons in one file - * - * A very easy way to split your code whilst not having to split it up in seperate files, keeping things nice and tidy. - */ - -const Hugo = require('../'); - -// Aliens action (/usr/local/bin/node index.js aliens "$1") -Hugo.action('aliens', query => { - Hugo.addItems([ - { - title: 'My book about wizards', - subtitle: 'It\'s awesome, read it.', - arg: 'wizards' - }, - { - title: 'My book about unicorns', - subtitle: 'Not as great as my book about wizards, but a decent read.', - arg: 'unicorns' - } - ]); - - Hugo.filterItems(query); -}); - -// Zombies action (/usr/local/bin/node index.js zombies "$1") -Hugo.action('zombies', query => { - Hugo.addItems([ - { - title: 'My book about zombies', - subtitle: 'It\'s awesome, read it.', - arg: 'rotting flesh' - }, - { - title: 'My book about the undead', - subtitle: 'Not as great as my book about zombies, but a decent read.', - arg: 'undead beings' - } - ]); - - Hugo.filterItems(query); -}); - -Hugo.feedback(); diff --git a/examples/basic-filter.js b/examples/basic-filter.js deleted file mode 100644 index 53ca858..0000000 --- a/examples/basic-filter.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - -/** - * Basic adding and filtering of items - * - * A very basic example of adding items and filtering them by user input. As of Alfred 3 you have the option to let - * Alfred do the filtering. This runs the script once and then caches and filters the results. It is less flexible as it - * only filters the output data and only by title but it is FAST! Use it if you don't require fancy filtering options. - */ - -const Hugo = require('../'); - -// Add items to Hugo -Hugo.addItems([ - { - title: 'My book about wizards', - subtitle: 'It\'s awesome, read it.', - arg: 'wizards' - }, - { - title: 'My book about unicorns', - subtitle: 'Not as great as my book about wizards, but a decent read.', - arg: 'unicorns' - } -]); - -// Filter added items by user input -Hugo.filterItems(Hugo.input); - -// Display items -Hugo.feedback(); diff --git a/examples/comments.json b/examples/comments.json deleted file mode 100644 index 0d7ba4c..0000000 --- a/examples/comments.json +++ /dev/null @@ -1,3502 +0,0 @@ -[ - { - "postId": 1, - "id": 1, - "name": "id labore ex et quam laborum", - "email": "Eliseo@gardner.biz", - "body": "laudantium enim quasi est quidem magnam voluptate ipsam eos\ntempora quo necessitatibus\ndolor quam autem quasi\nreiciendis et nam sapiente accusantium" - }, - { - "postId": 1, - "id": 2, - "name": "quo vero reiciendis velit similique earum", - "email": "Jayne_Kuhic@sydney.com", - "body": "est natus enim nihil est dolore omnis voluptatem numquam\net omnis occaecati quod ullam at\nvoluptatem error expedita pariatur\nnihil sint nostrum voluptatem reiciendis et" - }, - { - "postId": 1, - "id": 3, - "name": "odio adipisci rerum aut animi", - "email": "Nikita@garfield.biz", - "body": "quia molestiae reprehenderit quasi aspernatur\naut expedita occaecati aliquam eveniet laudantium\nomnis quibusdam delectus saepe quia accusamus maiores nam est\ncum et ducimus et vero voluptates excepturi deleniti ratione" - }, - { - "postId": 1, - "id": 4, - "name": "alias odio sit", - "email": "Lew@alysha.tv", - "body": "non et atque\noccaecati deserunt quas accusantium unde odit nobis qui voluptatem\nquia voluptas consequuntur itaque dolor\net qui rerum deleniti ut occaecati" - }, - { - "postId": 1, - "id": 5, - "name": "vero eaque aliquid doloribus et culpa", - "email": "Hayden@althea.biz", - "body": "harum non quasi et ratione\ntempore iure ex voluptates in ratione\nharum architecto fugit inventore cupiditate\nvoluptates magni quo et" - }, - { - "postId": 2, - "id": 6, - "name": "et fugit eligendi deleniti quidem qui sint nihil autem", - "email": "Presley.Mueller@myrl.com", - "body": "doloribus at sed quis culpa deserunt consectetur qui praesentium\naccusamus fugiat dicta\nvoluptatem rerum ut voluptate autem\nvoluptatem repellendus aspernatur dolorem in" - }, - { - "postId": 2, - "id": 7, - "name": "repellat consequatur praesentium vel minus molestias voluptatum", - "email": "Dallas@ole.me", - "body": "maiores sed dolores similique labore et inventore et\nquasi temporibus esse sunt id et\neos voluptatem aliquam\naliquid ratione corporis molestiae mollitia quia et magnam dolor" - }, - { - "postId": 2, - "id": 8, - "name": "et omnis dolorem", - "email": "Mallory_Kunze@marie.org", - "body": "ut voluptatem corrupti velit\nad voluptatem maiores\net nisi velit vero accusamus maiores\nvoluptates quia aliquid ullam eaque" - }, - { - "postId": 2, - "id": 9, - "name": "provident id voluptas", - "email": "Meghan_Littel@rene.us", - "body": "sapiente assumenda molestiae atque\nadipisci laborum distinctio aperiam et ab ut omnis\net occaecati aspernatur odit sit rem expedita\nquas enim ipsam minus" - }, - { - "postId": 2, - "id": 10, - "name": "eaque et deleniti atque tenetur ut quo ut", - "email": "Carmen_Keeling@caroline.name", - "body": "voluptate iusto quis nobis reprehenderit ipsum amet nulla\nquia quas dolores velit et non\naut quia necessitatibus\nnostrum quaerat nulla et accusamus nisi facilis" - }, - { - "postId": 3, - "id": 11, - "name": "fugit labore quia mollitia quas deserunt nostrum sunt", - "email": "Veronica_Goodwin@timmothy.net", - "body": "ut dolorum nostrum id quia aut est\nfuga est inventore vel eligendi explicabo quis consectetur\naut occaecati repellat id natus quo est\nut blanditiis quia ut vel ut maiores ea" - }, - { - "postId": 3, - "id": 12, - "name": "modi ut eos dolores illum nam dolor", - "email": "Oswald.Vandervort@leanne.org", - "body": "expedita maiores dignissimos facilis\nipsum est rem est fugit velit sequi\neum odio dolores dolor totam\noccaecati ratione eius rem velit" - }, - { - "postId": 3, - "id": 13, - "name": "aut inventore non pariatur sit vitae voluptatem sapiente", - "email": "Kariane@jadyn.tv", - "body": "fuga eos qui dolor rerum\ninventore corporis exercitationem\ncorporis cupiditate et deserunt recusandae est sed quis culpa\neum maiores corporis et" - }, - { - "postId": 3, - "id": 14, - "name": "et officiis id praesentium hic aut ipsa dolorem repudiandae", - "email": "Nathan@solon.io", - "body": "vel quae voluptas qui exercitationem\nvoluptatibus unde sed\nminima et qui ipsam aspernatur\nexpedita magnam laudantium et et quaerat ut qui dolorum" - }, - { - "postId": 3, - "id": 15, - "name": "debitis magnam hic odit aut ullam nostrum tenetur", - "email": "Maynard.Hodkiewicz@roberta.com", - "body": "nihil ut voluptates blanditiis autem odio dicta rerum\nquisquam saepe et est\nsunt quasi nemo laudantium deserunt\nmolestias tempora quo quia" - }, - { - "postId": 4, - "id": 16, - "name": "perferendis temporibus delectus optio ea eum ratione dolorum", - "email": "Christine@ayana.info", - "body": "iste ut laborum aliquid velit facere itaque\nquo ut soluta dicta voluptate\nerror tempore aut et\nsequi reiciendis dignissimos expedita consequuntur libero sed fugiat facilis" - }, - { - "postId": 4, - "id": 17, - "name": "eos est animi quis", - "email": "Preston_Hudson@blaise.tv", - "body": "consequatur necessitatibus totam sed sit dolorum\nrecusandae quae odio excepturi voluptatum harum voluptas\nquisquam sit ad eveniet delectus\ndoloribus odio qui non labore" - }, - { - "postId": 4, - "id": 18, - "name": "aut et tenetur ducimus illum aut nulla ab", - "email": "Vincenza_Klocko@albertha.name", - "body": "veritatis voluptates necessitatibus maiores corrupti\nneque et exercitationem amet sit et\nullam velit sit magnam laborum\nmagni ut molestias" - }, - { - "postId": 4, - "id": 19, - "name": "sed impedit rerum quia et et inventore unde officiis", - "email": "Madelynn.Gorczany@darion.biz", - "body": "doloribus est illo sed minima aperiam\nut dignissimos accusantium tempore atque et aut molestiae\nmagni ut accusamus voluptatem quos ut voluptates\nquisquam porro sed architecto ut" - }, - { - "postId": 4, - "id": 20, - "name": "molestias expedita iste aliquid voluptates", - "email": "Mariana_Orn@preston.org", - "body": "qui harum consequatur fugiat\net eligendi perferendis at molestiae commodi ducimus\ndoloremque asperiores numquam qui\nut sit dignissimos reprehenderit tempore" - }, - { - "postId": 5, - "id": 21, - "name": "aliquid rerum mollitia qui a consectetur eum sed", - "email": "Noemie@marques.me", - "body": "deleniti aut sed molestias explicabo\ncommodi odio ratione nesciunt\nvoluptate doloremque est\nnam autem error delectus" - }, - { - "postId": 5, - "id": 22, - "name": "porro repellendus aut tempore quis hic", - "email": "Khalil@emile.co.uk", - "body": "qui ipsa animi nostrum praesentium voluptatibus odit\nqui non impedit cum qui nostrum aliquid fuga explicabo\nvoluptatem fugit earum voluptas exercitationem temporibus dignissimos distinctio\nesse inventore reprehenderit quidem ut incidunt nihil necessitatibus rerum" - }, - { - "postId": 5, - "id": 23, - "name": "quis tempora quidem nihil iste", - "email": "Sophia@arianna.co.uk", - "body": "voluptates provident repellendus iusto perspiciatis ex fugiat ut\nut dolor nam aliquid et expedita voluptate\nsunt vitae illo rerum in quos\nvel eligendi enim quae fugiat est" - }, - { - "postId": 5, - "id": 24, - "name": "in tempore eos beatae est", - "email": "Jeffery@juwan.us", - "body": "repudiandae repellat quia\nsequi est dolore explicabo nihil et\net sit et\net praesentium iste atque asperiores tenetur" - }, - { - "postId": 5, - "id": 25, - "name": "autem ab ea sit alias hic provident sit", - "email": "Isaias_Kuhic@jarrett.net", - "body": "sunt aut quae laboriosam sit ut impedit\nadipisci harum laborum totam deleniti voluptas odit rem ea\nnon iure distinctio ut velit doloribus\net non ex" - }, - { - "postId": 6, - "id": 26, - "name": "in deleniti sunt provident soluta ratione veniam quam praesentium", - "email": "Russel.Parker@kameron.io", - "body": "incidunt sapiente eaque dolor eos\nad est molestias\nquas sit et nihil exercitationem at cumque ullam\nnihil magnam et" - }, - { - "postId": 6, - "id": 27, - "name": "doloribus quibusdam molestiae amet illum", - "email": "Francesco.Gleason@nella.us", - "body": "nisi vel quas ut laborum ratione\nrerum magni eum\nunde et voluptatem saepe\nvoluptas corporis modi amet ipsam eos saepe porro" - }, - { - "postId": 6, - "id": 28, - "name": "quo voluptates voluptas nisi veritatis dignissimos dolores ut officiis", - "email": "Ronny@rosina.org", - "body": "voluptatem repellendus quo alias at laudantium\nmollitia quidem esse\ntemporibus consequuntur vitae rerum illum\nid corporis sit id" - }, - { - "postId": 6, - "id": 29, - "name": "eum distinctio amet dolor", - "email": "Jennings_Pouros@erica.biz", - "body": "tempora voluptatem est\nmagnam distinctio autem est dolorem\net ipsa molestiae odit rerum itaque corporis nihil nam\neaque rerum error" - }, - { - "postId": 6, - "id": 30, - "name": "quasi nulla ducimus facilis non voluptas aut", - "email": "Lurline@marvin.biz", - "body": "consequuntur quia voluptate assumenda et\nautem voluptatem reiciendis ipsum animi est provident\nearum aperiam sapiente ad vitae iste\naccusantium aperiam eius qui dolore voluptatem et" - }, - { - "postId": 7, - "id": 31, - "name": "ex velit ut cum eius odio ad placeat", - "email": "Buford@shaylee.biz", - "body": "quia incidunt ut\naliquid est ut rerum deleniti iure est\nipsum quia ea sint et\nvoluptatem quaerat eaque repudiandae eveniet aut" - }, - { - "postId": 7, - "id": 32, - "name": "dolorem architecto ut pariatur quae qui suscipit", - "email": "Maria@laurel.name", - "body": "nihil ea itaque libero illo\nofficiis quo quo dicta inventore consequatur voluptas voluptatem\ncorporis sed necessitatibus velit tempore\nrerum velit et temporibus" - }, - { - "postId": 7, - "id": 33, - "name": "voluptatum totam vel voluptate omnis", - "email": "Jaeden.Towne@arlene.tv", - "body": "fugit harum quae vero\nlibero unde tempore\nsoluta eaque culpa sequi quibusdam nulla id\net et necessitatibus" - }, - { - "postId": 7, - "id": 34, - "name": "omnis nemo sunt ab autem", - "email": "Ethelyn.Schneider@emelia.co.uk", - "body": "omnis temporibus quasi ab omnis\nfacilis et omnis illum quae quasi aut\nminus iure ex rem ut reprehenderit\nin non fugit" - }, - { - "postId": 7, - "id": 35, - "name": "repellendus sapiente omnis praesentium aliquam ipsum id molestiae omnis", - "email": "Georgianna@florence.io", - "body": "dolor mollitia quidem facere et\nvel est ut\nut repudiandae est quidem dolorem sed atque\nrem quia aut adipisci sunt" - }, - { - "postId": 8, - "id": 36, - "name": "sit et quis", - "email": "Raheem_Heaney@gretchen.biz", - "body": "aut vero est\ndolor non aut excepturi dignissimos illo nisi aut quas\naut magni quia nostrum provident magnam quas modi maxime\nvoluptatem et molestiae" - }, - { - "postId": 8, - "id": 37, - "name": "beatae veniam nemo rerum voluptate quam aspernatur", - "email": "Jacky@victoria.net", - "body": "qui rem amet aut\ncumque maiores earum ut quia sit nam esse qui\niusto aspernatur quis voluptas\ndolorem distinctio ex temporibus rem" - }, - { - "postId": 8, - "id": 38, - "name": "maiores dolores expedita", - "email": "Piper@linwood.us", - "body": "unde voluptatem qui dicta\nvel ad aut eos error consequatur voluptatem\nadipisci doloribus qui est sit aut\nvelit aut et ea ratione eveniet iure fuga" - }, - { - "postId": 8, - "id": 39, - "name": "necessitatibus ratione aut ut delectus quae ut", - "email": "Gaylord@russell.net", - "body": "atque consequatur dolorem sunt\nadipisci autem et\nvoluptatibus et quae necessitatibus rerum eaque aperiam nostrum nemo\neligendi sed et beatae et inventore" - }, - { - "postId": 8, - "id": 40, - "name": "non minima omnis deleniti pariatur facere quibusdam at", - "email": "Clare.Aufderhar@nicole.ca", - "body": "quod minus alias quos\nperferendis labore molestias quae ut ut corporis deserunt vitae\net quaerat ut et ullam unde asperiores\ncum voluptatem cumque" - }, - { - "postId": 9, - "id": 41, - "name": "voluptas deleniti ut", - "email": "Lucio@gladys.tv", - "body": "facere repudiandae vitae ea aut sed quo ut et\nfacere nihil ut voluptates in\nsaepe cupiditate accusantium numquam dolores\ninventore sint mollitia provident" - }, - { - "postId": 9, - "id": 42, - "name": "nam qui et", - "email": "Shemar@ewell.name", - "body": "aut culpa quaerat veritatis eos debitis\naut repellat eius explicabo et\nofficiis quo sint at magni ratione et iure\nincidunt quo sequi quia dolorum beatae qui" - }, - { - "postId": 9, - "id": 43, - "name": "molestias sint est voluptatem modi", - "email": "Jackeline@eva.tv", - "body": "voluptatem ut possimus laborum quae ut commodi delectus\nin et consequatur\nin voluptas beatae molestiae\nest rerum laborum et et velit sint ipsum dolorem" - }, - { - "postId": 9, - "id": 44, - "name": "hic molestiae et fuga ea maxime quod", - "email": "Marianna_Wilkinson@rupert.io", - "body": "qui sunt commodi\nsint vel optio vitae quis qui non distinctio\nid quasi modi dicta\neos nihil sit inventore est numquam officiis" - }, - { - "postId": 9, - "id": 45, - "name": "autem illo facilis", - "email": "Marcia@name.biz", - "body": "ipsum odio harum voluptatem sunt cumque et dolores\nnihil laboriosam neque commodi qui est\nquos numquam voluptatum\ncorporis quo in vitae similique cumque tempore" - }, - { - "postId": 10, - "id": 46, - "name": "dignissimos et deleniti voluptate et quod", - "email": "Jeremy.Harann@waino.me", - "body": "exercitationem et id quae cum omnis\nvoluptatibus accusantium et quidem\nut ipsam sint\ndoloremque illo ex atque necessitatibus sed" - }, - { - "postId": 10, - "id": 47, - "name": "rerum commodi est non dolor nesciunt ut", - "email": "Pearlie.Kling@sandy.com", - "body": "occaecati laudantium ratione non cumque\nearum quod non enim soluta nisi velit similique voluptatibus\nesse laudantium consequatur voluptatem rem eaque voluptatem aut ut\net sit quam" - }, - { - "postId": 10, - "id": 48, - "name": "consequatur animi dolorem saepe repellendus ut quo aut tenetur", - "email": "Manuela_Stehr@chelsie.tv", - "body": "illum et alias quidem magni voluptatum\nab soluta ea qui saepe corrupti hic et\ncum repellat esse\nest sint vel veritatis officia consequuntur cum" - }, - { - "postId": 10, - "id": 49, - "name": "rerum placeat quae minus iusto eligendi", - "email": "Camryn.Weimann@doris.io", - "body": "id est iure occaecati quam similique enim\nab repudiandae non\nillum expedita quam excepturi soluta qui placeat\nperspiciatis optio maiores non doloremque aut iusto sapiente" - }, - { - "postId": 10, - "id": 50, - "name": "dolorum soluta quidem ex quae occaecati dicta aut doloribus", - "email": "Kiana_Predovic@yasmin.io", - "body": "eum accusamus aut delectus\narchitecto blanditiis quia sunt\nrerum harum sit quos quia aspernatur vel corrupti inventore\nanimi dicta vel corporis" - }, - { - "postId": 11, - "id": 51, - "name": "molestias et odio ut commodi omnis ex", - "email": "Laurie@lincoln.us", - "body": "perferendis omnis esse\nvoluptate sit mollitia sed perferendis\nnemo nostrum qui\nvel quis nisi doloribus animi odio id quas" - }, - { - "postId": 11, - "id": 52, - "name": "esse autem dolorum", - "email": "Abigail.OConnell@june.org", - "body": "et enim voluptatem totam laudantium\nimpedit nam labore repellendus enim earum aut\nconsectetur mollitia fugit qui repellat expedita sunt\naut fugiat vel illo quos aspernatur ducimus" - }, - { - "postId": 11, - "id": 53, - "name": "maiores alias necessitatibus aut non", - "email": "Laverne_Price@scotty.info", - "body": "a at tempore\nmolestiae odit qui dolores molestias dolorem et\nlaboriosam repudiandae placeat quisquam\nautem aperiam consectetur maiores laboriosam nostrum" - }, - { - "postId": 11, - "id": 54, - "name": "culpa eius tempora sit consequatur neque iure deserunt", - "email": "Kenton_Vandervort@friedrich.com", - "body": "et ipsa rem ullam cum pariatur similique quia\ncum ipsam est sed aut inventore\nprovident sequi commodi enim inventore assumenda aut aut\ntempora possimus soluta quia consequatur modi illo" - }, - { - "postId": 11, - "id": 55, - "name": "quas pariatur quia a doloribus", - "email": "Hayden_Olson@marianna.me", - "body": "perferendis eaque labore laudantium ut molestiae soluta et\nvero odio non corrupti error pariatur consectetur et\nenim nam quia voluptatum non\nmollitia culpa facere voluptas suscipit veniam" - }, - { - "postId": 12, - "id": 56, - "name": "et dolorem corrupti sed molestias", - "email": "Vince_Crist@heidi.biz", - "body": "cum esse odio nihil reiciendis illum quaerat\nest facere quia\noccaecati sit totam fugiat in beatae\nut occaecati unde vitae nihil quidem consequatur" - }, - { - "postId": 12, - "id": 57, - "name": "qui quidem sed", - "email": "Darron.Nikolaus@eulah.me", - "body": "dolorem facere itaque fuga odit autem\nperferendis quisquam quis corrupti eius dicta\nrepudiandae error esse itaque aut\ncorrupti sint consequatur aliquid" - }, - { - "postId": 12, - "id": 58, - "name": "sint minus reiciendis qui perspiciatis id", - "email": "Ezra_Abshire@lyda.us", - "body": "veritatis qui nihil\nquia reprehenderit non ullam ea iusto\nconsectetur nam voluptas ut temporibus tempore provident error\neos et nisi et voluptate" - }, - { - "postId": 12, - "id": 59, - "name": "quis ducimus distinctio similique et illum minima ab libero", - "email": "Jameson@tony.info", - "body": "cumque molestiae officia aut fugiat nemo autem\nvero alias atque sed qui ratione quia\nrepellat vel earum\nea laudantium mollitia" - }, - { - "postId": 12, - "id": 60, - "name": "expedita libero quos cum commodi ad", - "email": "Americo@estrella.net", - "body": "error eum quia voluptates alias repudiandae\naccusantium veritatis maiores assumenda\nquod impedit animi tempore veritatis\nanimi et et officiis labore impedit blanditiis repudiandae" - }, - { - "postId": 13, - "id": 61, - "name": "quidem itaque dolores quod laborum aliquid molestiae", - "email": "Aurelio.Pfeffer@griffin.ca", - "body": "deserunt cumque laudantium\net et odit quia sint quia quidem\nquibusdam debitis fuga in tempora deleniti\nimpedit consequatur veniam reiciendis autem porro minima" - }, - { - "postId": 13, - "id": 62, - "name": "libero beatae consequuntur optio est hic", - "email": "Vesta_Crooks@dora.us", - "body": "tempore dolorum corrupti facilis\npraesentium sunt iste recusandae\nunde quisquam similique\nalias consequuntur voluptates velit" - }, - { - "postId": 13, - "id": 63, - "name": "occaecati dolor accusantium et quasi architecto aut eveniet fugiat", - "email": "Margarett_Klein@mike.biz", - "body": "aut eligendi et molestiae voluptatum tempora\nofficia nihil sit voluptatem aut deleniti\nquaerat consequatur eaque\nsapiente tempore commodi tenetur rerum qui quo" - }, - { - "postId": 13, - "id": 64, - "name": "consequatur aut ullam voluptas dolorum voluptatum sequi et", - "email": "Freida@brandt.tv", - "body": "sed illum quis\nut aut culpa labore aspernatur illo\ndolorem quia vitae ut aut quo repellendus est omnis\nesse at est debitis" - }, - { - "postId": 13, - "id": 65, - "name": "earum ea ratione numquam", - "email": "Mollie@agustina.name", - "body": "qui debitis vitae ratione\ntempora impedit aperiam porro molestiae placeat vero laboriosam recusandae\npraesentium consequatur facere et itaque quidem eveniet\nmagnam natus distinctio sapiente" - }, - { - "postId": 14, - "id": 66, - "name": "eius nam consequuntur", - "email": "Janice@alda.io", - "body": "necessitatibus libero occaecati\nvero inventore iste assumenda veritatis\nasperiores non sit et quia omnis facere nemo explicabo\nodit quo nobis porro" - }, - { - "postId": 14, - "id": 67, - "name": "omnis consequatur natus distinctio", - "email": "Dashawn@garry.com", - "body": "nulla quo itaque beatae ad\nofficiis animi aut exercitationem voluptatum dolorem doloremque ducimus in\nrecusandae officia consequuntur quas\naspernatur dolores est esse dolores sit illo laboriosam quaerat" - }, - { - "postId": 14, - "id": 68, - "name": "architecto ut deserunt consequatur cumque sapiente", - "email": "Devan.Nader@ettie.me", - "body": "sed magni accusantium numquam quidem omnis et voluptatem beatae\nquos fugit libero\nvel ipsa et nihil recusandae ea\niste nemo qui optio sit enim ut nostrum odit" - }, - { - "postId": 14, - "id": 69, - "name": "at aut ea iure accusantium voluptatum nihil ipsum", - "email": "Joana.Schoen@leora.co.uk", - "body": "omnis dolor autem qui est natus\nautem animi nemo voluptatum aut natus accusantium iure\ninventore sunt ea tenetur commodi suscipit facere architecto consequatur\ndolorem nihil veritatis consequuntur corporis" - }, - { - "postId": 14, - "id": 70, - "name": "eum magni accusantium labore aut cum et tenetur", - "email": "Minerva.Anderson@devonte.ca", - "body": "omnis aliquam praesentium ad voluptatem harum aperiam dolor autem\nhic asperiores quisquam ipsa necessitatibus suscipit\npraesentium rem deserunt et\nfacere repellendus aut sed fugit qui est" - }, - { - "postId": 15, - "id": 71, - "name": "vel pariatur perferendis vero ab aut voluptates labore", - "email": "Lavinia@lafayette.me", - "body": "mollitia magnam et\nipsum consequatur est expedita\naut rem ut ex doloremque est vitae est\ncumque velit recusandae numquam libero dolor fuga fugit a" - }, - { - "postId": 15, - "id": 72, - "name": "quia sunt dolor dolor suscipit expedita quis", - "email": "Sabrina.Marks@savanah.name", - "body": "quisquam voluptas ut\npariatur eos amet non\nreprehenderit voluptates numquam\nin est voluptatem dicta ipsa qui esse enim" - }, - { - "postId": 15, - "id": 73, - "name": "ut quia ipsa repellat sunt et sequi aut est", - "email": "Desmond_Graham@kailee.biz", - "body": "nam qui possimus deserunt\ninventore dignissimos nihil rerum ut consequatur vel architecto\ntenetur recusandae voluptate\nnumquam dignissimos aliquid ut reprehenderit voluptatibus" - }, - { - "postId": 15, - "id": 74, - "name": "ut non illum pariatur dolor", - "email": "Gussie_Kunde@sharon.biz", - "body": "non accusamus eum aut et est\naccusantium animi nesciunt distinctio ea quas quisquam\nsit ut voluptatem modi natus sint\nfacilis est qui molestias recusandae nemo" - }, - { - "postId": 15, - "id": 75, - "name": "minus laboriosam consequuntur", - "email": "Richard@chelsie.co.uk", - "body": "natus numquam enim asperiores doloremque ullam et\nest molestias doloribus cupiditate labore vitae aut voluptatem\nitaque quos quo consectetur nihil illum veniam\nnostrum voluptatum repudiandae ut" - }, - { - "postId": 16, - "id": 76, - "name": "porro ut soluta repellendus similique", - "email": "Gage_Turner@halle.name", - "body": "sunt qui consequatur similique recusandae repellendus voluptates eos et\nvero nostrum fugit magnam aliquam\nreprehenderit nobis voluptatem eos consectetur possimus\net perferendis qui ea fugiat sit doloremque" - }, - { - "postId": 16, - "id": 77, - "name": "dolores et quo omnis voluptates", - "email": "Alfred@sadye.biz", - "body": "eos ullam dolorem impedit labore mollitia\nrerum non dolores\nmolestiae dignissimos qui maxime sed voluptate consequatur\ndoloremque praesentium magnam odio iste quae totam aut" - }, - { - "postId": 16, - "id": 78, - "name": "voluptas voluptas voluptatibus blanditiis", - "email": "Catharine@jordyn.com", - "body": "qui adipisci eveniet excepturi iusto magni et\nenim ducimus asperiores blanditiis nemo\ncommodi nihil ex\nenim rerum vel nobis nostrum et non" - }, - { - "postId": 16, - "id": 79, - "name": "beatae ut ad quisquam sed repellendus et", - "email": "Esther_Ratke@shayna.biz", - "body": "et inventore sapiente sed\nsunt similique fugiat officia velit doloremque illo eligendi quas\nsed rerum in quidem perferendis facere molestias\ndolore dolor voluptas nam vel quia" - }, - { - "postId": 16, - "id": 80, - "name": "et cumque ad culpa ut eligendi non", - "email": "Evangeline@chad.net", - "body": "dignissimos itaque ab et tempore odio omnis voluptatem\nitaque perferendis rem repellendus tenetur nesciunt velit\nqui cupiditate recusandae\nquis debitis dolores aliquam nam" - }, - { - "postId": 17, - "id": 81, - "name": "aut non consequuntur dignissimos voluptatibus dolorem earum recusandae dolorem", - "email": "Newton.Kertzmann@anjali.io", - "body": "illum et voluptatem quis repellendus quidem repellat\nreprehenderit voluptas consequatur mollitia\npraesentium nisi quo quod et\noccaecati repellendus illo eius harum explicabo doloribus officia" - }, - { - "postId": 17, - "id": 82, - "name": "ea est non dolorum iste nihil est", - "email": "Caleb_Herzog@rosamond.net", - "body": "officiis dolorem voluptas aliquid eveniet tempora qui\nea temporibus labore accusamus sint\nut sunt necessitatibus voluptatum animi cumque\nat reiciendis voluptatem iure aliquid et qui dolores et" - }, - { - "postId": 17, - "id": 83, - "name": "nihil qui accusamus ratione et molestias et minus", - "email": "Sage_Mueller@candace.net", - "body": "et consequatur voluptates magnam fugit sunt repellendus nihil earum\nofficiis aut cupiditate\net distinctio laboriosam\nmolestiae sunt dolor explicabo recusandae" - }, - { - "postId": 17, - "id": 84, - "name": "quia voluptatibus magnam voluptatem optio vel perspiciatis", - "email": "Bernie.Bergnaum@lue.com", - "body": "ratione ut magni voluptas\nexplicabo natus quia consequatur nostrum aut\nomnis enim in qui illum\naut atque laboriosam aliquid blanditiis quisquam et laborum" - }, - { - "postId": 17, - "id": 85, - "name": "non voluptas cum est quis aut consectetur nam", - "email": "Alexzander_Davis@eduardo.name", - "body": "quisquam incidunt dolores sint qui doloribus provident\nvel cupiditate deleniti alias voluptatem placeat ad\nut dolorem illum unde iure quis libero neque\nea et distinctio id" - }, - { - "postId": 18, - "id": 86, - "name": "suscipit est sunt vel illum sint", - "email": "Jacquelyn@krista.info", - "body": "eum culpa debitis sint\neaque quia magni laudantium qui neque voluptas\nvoluptatem qui molestiae vel earum est ratione excepturi\nsit aut explicabo et repudiandae ut perspiciatis" - }, - { - "postId": 18, - "id": 87, - "name": "dolor asperiores autem et omnis quasi nobis", - "email": "Grover_Volkman@coty.tv", - "body": "assumenda corporis architecto repudiandae omnis qui et odit\nperferendis velit enim\net quia reiciendis sint\nquia voluptas quam deserunt facilis harum eligendi" - }, - { - "postId": 18, - "id": 88, - "name": "officiis aperiam odit sint est non", - "email": "Jovanny@abigale.ca", - "body": "laudantium corrupti atque exercitationem quae enim et veniam dicta\nautem perspiciatis sit dolores\nminima consectetur tenetur iste facere\namet est neque" - }, - { - "postId": 18, - "id": 89, - "name": "in voluptatum nostrum voluptas iure nisi rerum est placeat", - "email": "Isac_Schmeler@barton.com", - "body": "quibusdam rerum quia nostrum culpa\nculpa est natus impedit quo rem voluptate quos\nrerum culpa aut ut consectetur\nsunt esse laudantium voluptatibus cupiditate rerum" - }, - { - "postId": 18, - "id": 90, - "name": "eum voluptas dolores molestias odio amet repellendus", - "email": "Sandy.Erdman@sabina.info", - "body": "vitae cupiditate excepturi eum veniam laudantium aspernatur blanditiis\naspernatur quia ut assumenda et magni enim magnam\nin voluptate tempora\nnon qui voluptatem reprehenderit porro qui voluptatibus" - }, - { - "postId": 19, - "id": 91, - "name": "repellendus est laboriosam voluptas veritatis", - "email": "Alexandro@garry.io", - "body": "qui nisi at maxime deleniti quo\nex quas tenetur nam\ndeleniti aut asperiores deserunt cum ex eaque alias sit\net veniam ab consequatur molestiae" - }, - { - "postId": 19, - "id": 92, - "name": "repellendus aspernatur occaecati tempore blanditiis deleniti omnis qui distinctio", - "email": "Vickie_Schuster@harley.net", - "body": "nihil necessitatibus omnis asperiores nobis praesentium quia\nab debitis quo deleniti aut sequi commodi\nut perspiciatis quod est magnam aliquam modi\neum quos aliquid ea est" - }, - { - "postId": 19, - "id": 93, - "name": "mollitia dolor deleniti sed iure laudantium", - "email": "Roma_Doyle@alia.com", - "body": "ut quis et id repellat labore\nnobis itaque quae saepe est ullam aut\ndolor id ut quis\nsunt iure voluptates expedita voluptas doloribus modi saepe autem" - }, - { - "postId": 19, - "id": 94, - "name": "vero repudiandae voluptatem nobis", - "email": "Tatum_Marks@jaylon.name", - "body": "reiciendis delectus nulla quae voluptas nihil provident quia\nab corporis nesciunt blanditiis quibusdam et unde et\nmagni eligendi aperiam corrupti perspiciatis quasi\nneque iure voluptatibus mollitia" - }, - { - "postId": 19, - "id": 95, - "name": "voluptatem unde quos provident ad qui sit et excepturi", - "email": "Juston.Ruecker@scot.tv", - "body": "at ut tenetur rem\nut fuga quis ea magnam alias\naut tempore fugiat laboriosam porro quia iure qui\narchitecto est enim" - }, - { - "postId": 20, - "id": 96, - "name": "non sit ad culpa quis", - "email": "River.Grady@lavada.biz", - "body": "eum itaque quam\nlaboriosam sequi ullam quos nobis\nomnis dignissimos nam dolores\nfacere id suscipit aliquid culpa rerum quis" - }, - { - "postId": 20, - "id": 97, - "name": "reiciendis culpa omnis suscipit est", - "email": "Claudia@emilia.ca", - "body": "est ducimus voluptate saepe iusto repudiandae recusandae et\nsint fugit voluptas eum itaque\nodit ab eos voluptas molestiae necessitatibus earum possimus voluptatem\nquibusdam aut illo beatae qui delectus aut officia veritatis" - }, - { - "postId": 20, - "id": 98, - "name": "praesentium dolorem ea voluptate et", - "email": "Torrey@june.tv", - "body": "ex et expedita cum voluptatem\nvoluptatem ab expedita quis nihil\nesse quo nihil perferendis dolores velit ut culpa aut\ndolor maxime necessitatibus voluptatem" - }, - { - "postId": 20, - "id": 99, - "name": "laudantium delectus nam", - "email": "Hildegard.Aufderhar@howard.com", - "body": "aut quam consequatur sit et\nrepellat maiores laborum similique voluptatem necessitatibus nihil\net debitis nemo occaecati cupiditate\nmodi dolorum quia aut" - }, - { - "postId": 20, - "id": 100, - "name": "et sint quia dolor et est ea nulla cum", - "email": "Leone_Fay@orrin.com", - "body": "architecto dolorem ab explicabo et provident et\net eos illo omnis mollitia ex aliquam\natque ut ipsum nulla nihil\nquis voluptas aut debitis facilis" - }, - { - "postId": 21, - "id": 101, - "name": "perspiciatis magnam ut eum autem similique explicabo expedita", - "email": "Lura@rod.tv", - "body": "ut aut maxime officia sed aliquam et magni autem\nveniam repudiandae nostrum odio enim eum optio aut\nomnis illo quasi quibusdam inventore explicabo\nreprehenderit dolor saepe possimus molestiae" - }, - { - "postId": 21, - "id": 102, - "name": "officia ullam ut neque earum ipsa et fuga", - "email": "Lottie.Zieme@ruben.us", - "body": "aut dolorem quos ut non\naliquam unde iure minima quod ullam qui\nfugiat molestiae tempora voluptate vel labore\nsaepe animi et vitae numquam ipsa" - }, - { - "postId": 21, - "id": 103, - "name": "ipsum a ut", - "email": "Winona_Price@jevon.me", - "body": "totam eum fugiat repellendus\nquae beatae explicabo excepturi iusto et\nrepellat alias iure voluptates consequatur sequi minus\nsed maxime unde" - }, - { - "postId": 21, - "id": 104, - "name": "a assumenda totam", - "email": "Gabriel@oceane.biz", - "body": "qui aperiam labore animi magnam odit est\nut autem eaque ea magni quas voluptatem\ndoloribus vel voluptatem nostrum ut debitis enim quaerat\nut esse eveniet aut" - }, - { - "postId": 21, - "id": 105, - "name": "voluptatem repellat est", - "email": "Adolph.Ondricka@mozell.co.uk", - "body": "ut rerum illum error at inventore ab nobis molestiae\nipsa architecto temporibus non aliquam aspernatur omnis quidem aliquid\nconsequatur non et expedita cumque voluptates ipsam quia\nblanditiis libero itaque sed iusto at" - }, - { - "postId": 22, - "id": 106, - "name": "maiores placeat facere quam pariatur", - "email": "Allen@richard.biz", - "body": "dolores debitis voluptatem ab hic\nmagnam alias qui est sunt\net porro velit et repellendus occaecati est\nsequi quia odio deleniti illum" - }, - { - "postId": 22, - "id": 107, - "name": "in ipsam vel id impedit possimus eos voluptate", - "email": "Nicholaus@mikayla.ca", - "body": "eveniet fugit qui\nporro eaque dolores eos adipisci dolores ut\nfugit perferendis pariatur\nnumquam et repellat occaecati atque ipsum neque" - }, - { - "postId": 22, - "id": 108, - "name": "ut veritatis corporis placeat suscipit consequatur quaerat", - "email": "Kayla@susanna.org", - "body": "at a vel sequi nostrum\nharum nam nihil\ncumque aut in dolore rerum ipsa hic ratione\nrerum cum ratione provident labore ad quisquam repellendus a" - }, - { - "postId": 22, - "id": 109, - "name": "eveniet ut similique accusantium qui dignissimos", - "email": "Gideon@amina.name", - "body": "aliquid qui dolorem deserunt aperiam natus corporis eligendi neque\nat et sunt aut qui\nillum repellat qui excepturi laborum facilis aut omnis consequatur\net aut optio ipsa nisi enim" - }, - { - "postId": 22, - "id": 110, - "name": "sint est odit officiis similique aut corrupti quas autem", - "email": "Cassidy@maribel.io", - "body": "cum sequi in eligendi id eaque\ndolores accusamus dolorem eum est voluptatem quisquam tempore\nin voluptas enim voluptatem asperiores voluptatibus\neius quo quos quasi voluptas earum ut necessitatibus" - }, - { - "postId": 23, - "id": 111, - "name": "possimus facilis deleniti nemo atque voluptate", - "email": "Stefan.Crist@duane.ca", - "body": "ullam autem et\naccusantium quod sequi similique soluta explicabo ipsa\neius ratione quisquam sed et excepturi occaecati pariatur\nmolestiae ut reiciendis eum voluptatem sed" - }, - { - "postId": 23, - "id": 112, - "name": "dolore aut aspernatur est voluptate quia ipsam", - "email": "Aniyah.Ortiz@monte.me", - "body": "ut tempora deleniti quo molestiae eveniet provident earum occaecati\nest nesciunt ut pariatur ipsa voluptas voluptatem aperiam\nqui deleniti quibusdam voluptas molestiae facilis id iusto similique\ntempora aut qui" - }, - { - "postId": 23, - "id": 113, - "name": "sint quo debitis deleniti repellat", - "email": "Laverna@rico.biz", - "body": "voluptatem sint quia modi accusantium alias\nrecusandae rerum voluptatem aut sit et ut magnam\nvoluptas rerum odio quo labore voluptatem facere consequuntur\nut sit voluptatum hic distinctio" - }, - { - "postId": 23, - "id": 114, - "name": "optio et sunt non", - "email": "Derek@hildegard.net", - "body": "nihil labore qui\nquis dolor eveniet iste numquam\nporro velit incidunt\nlaboriosam asperiores aliquam facilis in et voluptas eveniet quasi" - }, - { - "postId": 23, - "id": 115, - "name": "occaecati dolorem eum in veniam quia quo reiciendis", - "email": "Tyrell@abdullah.ca", - "body": "laudantium tempore aut\nmaiores laborum fugit qui suscipit hic sint officiis corrupti\nofficiis eum optio cumque fuga sed voluptatibus similique\nsit consequuntur rerum commodi" - }, - { - "postId": 24, - "id": 116, - "name": "veritatis sit tempora quasi fuga aut dolorum", - "email": "Reyes@hailey.name", - "body": "quia voluptas qui assumenda nesciunt harum iusto\nest corrupti aperiam\nut aut unde maxime consequatur eligendi\nveniam modi id sint rem labore saepe minus" - }, - { - "postId": 24, - "id": 117, - "name": "incidunt quae optio quam corporis iste deleniti accusantium vero", - "email": "Danika.Dicki@mekhi.biz", - "body": "doloribus esse necessitatibus qui eos et ut est saepe\nsed rerum tempore est ut\nquisquam et eligendi accusantium\ncommodi non doloribus" - }, - { - "postId": 24, - "id": 118, - "name": "quisquam laborum reiciendis aut", - "email": "Alessandra.Nitzsche@stephania.us", - "body": "repudiandae aliquam maxime cupiditate consequatur id\nquas error repellendus\ntotam officia dolorem beatae natus cum exercitationem\nasperiores dolor ea" - }, - { - "postId": 24, - "id": 119, - "name": "minus pariatur odit", - "email": "Matteo@marquis.net", - "body": "et omnis consequatur ut\nin suscipit et voluptatem\nanimi at ut\ndolores quos aut numquam esse praesentium aut placeat nam" - }, - { - "postId": 24, - "id": 120, - "name": "harum error sit", - "email": "Joshua.Spinka@toby.io", - "body": "iusto sint recusandae placeat atque perferendis sit corporis molestiae\nrem dolor eius id delectus et qui\nsed dolorem reiciendis error ullam corporis delectus\nexplicabo mollitia odit laborum sed itaque deserunt rem dolorem" - }, - { - "postId": 25, - "id": 121, - "name": "deleniti quo corporis ullam magni praesentium molestiae", - "email": "Annabelle@cole.com", - "body": "soluta mollitia impedit cumque nostrum tempore aut placeat repellat\nenim adipisci dolores aut ut ratione laboriosam necessitatibus vel\net blanditiis est iste sapiente qui atque repellendus alias\nearum consequuntur quia quasi quia" - }, - { - "postId": 25, - "id": 122, - "name": "nihil tempora et reiciendis modi veniam", - "email": "Kacey@jamal.info", - "body": "doloribus veritatis a et quis corrupti incidunt est\nharum maiores impedit et beatae qui velit et aut\nporro sed dignissimos deserunt deleniti\net eveniet voluptas ipsa pariatur rem ducimus" - }, - { - "postId": 25, - "id": 123, - "name": "ad eos explicabo odio velit", - "email": "Mina@mallie.name", - "body": "nostrum perspiciatis doloribus\nexplicabo soluta id libero illo iste et\nab expedita error aliquam eum sint ipsum\nmodi possimus et" - }, - { - "postId": 25, - "id": 124, - "name": "nostrum suscipit aut consequatur magnam sunt fuga nihil", - "email": "Hudson.Blick@ruben.biz", - "body": "ut ut eius qui explicabo quis\niste autem nulla beatae tenetur enim\nassumenda explicabo consequatur harum exercitationem\nvelit itaque consectetur et possimus" - }, - { - "postId": 25, - "id": 125, - "name": "porro et voluptate et reprehenderit", - "email": "Domenic.Durgan@joaquin.name", - "body": "aut voluptas dolore autem\nreprehenderit expedita et nihil pariatur ea animi quo ullam\na ea officiis corporis\neius voluptatum cum mollitia dolore quaerat accusamus" - }, - { - "postId": 26, - "id": 126, - "name": "fuga tenetur id et qui labore delectus", - "email": "Alexie@alayna.org", - "body": "est qui ut tempore temporibus pariatur provident qui consequuntur\nlaboriosam porro dignissimos quos debitis id laborum et totam\naut eius sequi dolor maiores amet\nrerum voluptatibus quod ratione quos labore fuga sit" - }, - { - "postId": 26, - "id": 127, - "name": "consequatur harum magnam", - "email": "Haven_Barrows@brant.org", - "body": "omnis consequatur dignissimos iure rerum odio\nculpa laudantium quia voluptas enim est nisi\ndoloremque consequatur autem officiis necessitatibus beatae et\net itaque animi dolor praesentium" - }, - { - "postId": 26, - "id": 128, - "name": "labore architecto quaerat tempora voluptas consequuntur animi", - "email": "Marianne@maximo.us", - "body": "exercitationem eius aut ullam vero\nimpedit similique maiores ea et in culpa possimus omnis\neos labore autem quam repellendus dolores deserunt voluptatem\nnon ullam eos accusamus" - }, - { - "postId": 26, - "id": 129, - "name": "deleniti facere tempore et perspiciatis voluptas quis voluptatem", - "email": "Fanny@danial.com", - "body": "fugit minima voluptatem est aut sed explicabo\nharum dolores at qui eaque\nmagni velit ut et\nnam et ut sunt excepturi repellat non commodi" - }, - { - "postId": 26, - "id": 130, - "name": "quod est non quia doloribus quam deleniti libero", - "email": "Trevion_Kuphal@bernice.name", - "body": "dicta sit culpa molestiae quasi at voluptate eos\ndolorem perferendis accusamus rerum expedita ipsum quis qui\nquos est deserunt\nrerum fuga qui aliquam in consequatur aspernatur" - }, - { - "postId": 27, - "id": 131, - "name": "voluptas quasi sunt laboriosam", - "email": "Emmet@guy.biz", - "body": "rem magnam at voluptatem\naspernatur et et nostrum rerum\ndignissimos eum quibusdam\noptio quod dolores et" - }, - { - "postId": 27, - "id": 132, - "name": "unde tenetur vero eum iusto", - "email": "Megane.Fritsch@claude.name", - "body": "ullam harum consequatur est rerum est\nmagni tenetur aperiam et\nrepudiandae et reprehenderit dolorum enim voluptas impedit\neligendi quis necessitatibus in exercitationem voluptatem qui" - }, - { - "postId": 27, - "id": 133, - "name": "est adipisci laudantium amet rem asperiores", - "email": "Amya@durward.ca", - "body": "sunt quis iure molestias qui ipsa commodi dolore a\nodio qui debitis earum\nunde ut omnis\ndoloremque corrupti at repellendus earum eum" - }, - { - "postId": 27, - "id": 134, - "name": "reiciendis quo est vitae dignissimos libero ut officiis fugiat", - "email": "Jasen_Rempel@willis.org", - "body": "corrupti perspiciatis eligendi\net omnis tempora nobis dolores hic\ndolorum vitae odit\nreiciendis sunt odit qui" - }, - { - "postId": 27, - "id": 135, - "name": "inventore fugiat dignissimos", - "email": "Harmony@reggie.com", - "body": "sapiente nostrum dolorem odit a\nsed animi non architecto doloremque unde\nnam aut aut ut facilis\net ut autem fugit minima culpa inventore non" - }, - { - "postId": 28, - "id": 136, - "name": "et expedita est odit", - "email": "Rosanna_Kunze@guy.net", - "body": "cum natus qui dolorem dolorum nihil ut nam tempore\nmodi nesciunt ipsum hic\nrem sunt possimus earum magnam similique aspernatur sed\ntotam sed voluptatem iusto id iste qui" - }, - { - "postId": 28, - "id": 137, - "name": "saepe dolore qui tempore nihil perspiciatis omnis omnis magni", - "email": "Ressie.Boehm@flossie.com", - "body": "reiciendis maiores id\nvoluptas sapiente deserunt itaque\nut omnis sunt\nnecessitatibus quibusdam dolorem voluptatem harum error" - }, - { - "postId": 28, - "id": 138, - "name": "ea optio nesciunt officia velit enim facilis commodi", - "email": "Domenic.Wuckert@jazmyne.us", - "body": "dolorem suscipit adipisci ad cum totam quia fugiat\nvel quia dolores molestiae eos\nomnis officia quidem quaerat alias vel distinctio\nvero provident et corporis a quia ut" - }, - { - "postId": 28, - "id": 139, - "name": "ut pariatur voluptate possimus quasi", - "email": "Rhett.OKon@brian.info", - "body": "facilis cumque nostrum dignissimos\ndoloremque saepe quia adipisci sunt\ndicta dolorum quo esse\nculpa iste ut asperiores cum aperiam" - }, - { - "postId": 28, - "id": 140, - "name": "consectetur tempore eum consequuntur", - "email": "Mathias@richmond.info", - "body": "velit ipsa fugiat sit qui vel nesciunt sapiente\nrepudiandae perferendis nemo eos quos perspiciatis aperiam\ndoloremque incidunt nostrum temporibus corrupti repudiandae vitae non corporis\ncupiditate suscipit quod sed numquam excepturi enim labore" - }, - { - "postId": 29, - "id": 141, - "name": "dignissimos perspiciatis voluptate quos rem qui temporibus excepturi", - "email": "Ottis@lourdes.org", - "body": "et ullam id eligendi rem sit\noccaecati et delectus in nemo\naut veritatis deserunt aspernatur dolor enim voluptas quos consequatur\nmolestiae temporibus error" - }, - { - "postId": 29, - "id": 142, - "name": "cum dolore sit quisquam provident nostrum vitae", - "email": "Estel@newton.ca", - "body": "cumque voluptas quo eligendi sit\nnemo ut ut dolor et cupiditate aut\net voluptatem quia aut maiores quas accusantium expedita quia\nbeatae aut ad quis soluta id dolorum" - }, - { - "postId": 29, - "id": 143, - "name": "velit molestiae assumenda perferendis voluptas explicabo", - "email": "Bertha@erik.co.uk", - "body": "est quasi maiores nisi reiciendis enim\ndolores minus facilis laudantium dignissimos\nreiciendis et facere occaecati dolores et\npossimus et vel et aut ipsa ad" - }, - { - "postId": 29, - "id": 144, - "name": "earum ipsum ea quas qui molestiae omnis unde", - "email": "Joesph@matteo.info", - "body": "voluptatem unde consequatur natus nostrum vel ut\nconsequatur sequi doloremque omnis dolorem maxime\neaque sunt excepturi\nfuga qui illum et accusamus" - }, - { - "postId": 29, - "id": 145, - "name": "magni iusto sit", - "email": "Alva@cassandre.net", - "body": "assumenda nihil et\nsed nulla tempora porro iste possimus aut sit officia\ncumque totam quis tenetur qui sequi\ndelectus aut sunt" - }, - { - "postId": 30, - "id": 146, - "name": "est qui debitis", - "email": "Vivienne@willis.org", - "body": "possimus necessitatibus quis\net dicta omnis voluptatem ea est\nsuscipit eum soluta in quia corrupti hic iusto\nconsequatur est aut qui earum nisi officiis sed culpa" - }, - { - "postId": 30, - "id": 147, - "name": "reiciendis et consectetur officiis beatae corrupti aperiam", - "email": "Angelita@aliza.me", - "body": "nihil aspernatur consequatur voluptatem facere sed fugiat ullam\nbeatae accusamus et fuga maxime vero\nomnis necessitatibus quisquam ipsum consectetur incidunt repellat voluptas\nerror quo et ab magnam quisquam" - }, - { - "postId": 30, - "id": 148, - "name": "iusto reprehenderit voluptatem modi", - "email": "Timmothy_Okuneva@alyce.tv", - "body": "nemo corporis quidem eius aut dolores\nitaque rerum quo occaecati mollitia incidunt\nautem est saepe nulla nobis a id\ndolore facilis placeat molestias in fugiat aliquam excepturi" - }, - { - "postId": 30, - "id": 149, - "name": "optio dolorem et reiciendis et recusandae quidem", - "email": "Moriah_Welch@richmond.org", - "body": "veniam est distinctio\nnihil quia eos sed\ndistinctio hic ut sint ducimus debitis dolorem voluptatum assumenda\neveniet ea perspiciatis" - }, - { - "postId": 30, - "id": 150, - "name": "id saepe numquam est facilis sint enim voluptas voluptatem", - "email": "Ramiro_Kuhn@harmon.biz", - "body": "est non atque eligendi aspernatur quidem earum mollitia\nminima neque nam exercitationem provident eum\nmaxime quo et ut illum sequi aut fuga repudiandae\nsapiente sed ea distinctio molestias illum consequatur libero quidem" - }, - { - "postId": 31, - "id": 151, - "name": "ut quas facilis laborum voluptatum consequatur odio voluptate et", - "email": "Cary@taurean.biz", - "body": "quos eos sint voluptatibus similique iusto perferendis omnis voluptas\nearum nulla cumque\ndolorem consequatur officiis quis consequatur aspernatur nihil ullam et\nenim enim unde nihil labore non ducimus" - }, - { - "postId": 31, - "id": 152, - "name": "quod doloremque omnis", - "email": "Tillman_Koelpin@luisa.com", - "body": "itaque veritatis explicabo\nquis voluptatem mollitia soluta id non\ndoloribus nobis fuga provident\nnesciunt saepe molestiae praesentium laboriosam" - }, - { - "postId": 31, - "id": 153, - "name": "dolorum et dolorem optio in provident", - "email": "Aleen@tania.biz", - "body": "et cumque error pariatur\nquo doloribus corrupti voluptates ad voluptatem consequatur voluptas dolores\npariatur at quas iste repellat et sed quasi\nea maiores rerum aut earum" - }, - { - "postId": 31, - "id": 154, - "name": "odit illo optio ea modi in", - "email": "Durward@cindy.com", - "body": "quod magni consectetur\nquod doloremque velit autem ipsam nisi praesentium ut\nlaboriosam quod deleniti\npariatur aliquam sint excepturi a consectetur quas eos" - }, - { - "postId": 31, - "id": 155, - "name": "adipisci laboriosam repudiandae omnis veritatis in facere similique rem", - "email": "Lester@chauncey.ca", - "body": "animi asperiores modi et tenetur vel magni\nid iusto aliquid ad\nnihil dolorem dolorum aut veritatis voluptates\nomnis cupiditate incidunt" - }, - { - "postId": 32, - "id": 156, - "name": "pariatur omnis in", - "email": "Telly_Lynch@karl.co.uk", - "body": "dolorum voluptas laboriosam quisquam ab\ntotam beatae et aut aliquid optio assumenda\nvoluptas velit itaque quidem voluptatem tempore cupiditate\nin itaque sit molestiae minus dolores magni" - }, - { - "postId": 32, - "id": 157, - "name": "aut nobis et consequatur", - "email": "Makenzie@libbie.io", - "body": "voluptas quia quo ad\nipsum voluptatum provident ut ipsam velit dignissimos aut assumenda\nut officia laudantium\nquibusdam sed minima" - }, - { - "postId": 32, - "id": 158, - "name": "explicabo est molestiae aut", - "email": "Amiya@perry.us", - "body": "et qui ad vero quis\nquisquam omnis fuga et vel nihil minima eligendi nostrum\nsed deserunt rem voluptates autem\nquia blanditiis cum sed" - }, - { - "postId": 32, - "id": 159, - "name": "voluptas blanditiis deserunt quia quis", - "email": "Meghan@akeem.tv", - "body": "deserunt deleniti officiis architecto consequatur molestiae facere dolor\nvoluptatem velit eos fuga dolores\nsit quia est a deleniti hic dolor quisquam repudiandae\nvoluptas numquam voluptatem impedit" - }, - { - "postId": 32, - "id": 160, - "name": "sint fugit esse", - "email": "Mitchel.Williamson@fletcher.io", - "body": "non reprehenderit aut sed quos est ad voluptatum\nest ut est dignissimos ut dolores consequuntur\ndebitis aspernatur consequatur est\nporro nulla laboriosam repellendus et nesciunt est libero placeat" - }, - { - "postId": 33, - "id": 161, - "name": "nesciunt quidem veritatis alias odit nisi voluptatem non est", - "email": "Ashlee_Jast@emie.biz", - "body": "sunt totam blanditiis\neum quos fugit et ab rerum nemo\nut iusto architecto\nut et eligendi iure placeat omnis" - }, - { - "postId": 33, - "id": 162, - "name": "animi vitae qui aut corrupti neque culpa modi", - "email": "Antwan@lori.ca", - "body": "nulla impedit porro in sed\nvoluptatem qui voluptas et enim beatae\nnobis et sit ipsam aut\nvoluptatem voluptatibus blanditiis officia quod eos omnis earum dolorem" - }, - { - "postId": 33, - "id": 163, - "name": "omnis ducimus ab temporibus nobis porro natus deleniti", - "email": "Estelle@valentina.info", - "body": "molestiae dolorem quae rem neque sapiente voluptatum nesciunt cum\nid rerum at blanditiis est accusantium est\neos illo porro ad\nquod repellendus ad et labore fugit dolorum" - }, - { - "postId": 33, - "id": 164, - "name": "eius corrupti ea", - "email": "Haylie@gino.name", - "body": "beatae aut ut autem sit officia rerum nostrum\nprovident ratione sed dicta omnis alias commodi rerum expedita\nnon nobis sapiente consectetur odit unde quia\nvoluptas in nihil consequatur doloremque ullam dolorem cum" - }, - { - "postId": 33, - "id": 165, - "name": "quia commodi molestiae assumenda provident sit incidunt laudantium", - "email": "Blake_Spinka@robyn.info", - "body": "sed praesentium ducimus minima autem corporis debitis\naperiam eum sit pariatur\nimpedit placeat illo odio\nodit accusantium expedita quo rerum magnam" - }, - { - "postId": 34, - "id": 166, - "name": "sint alias molestiae qui dolor vel", - "email": "Aimee.Bins@braeden.ca", - "body": "nam quas eaque unde\ndolor blanditiis cumque eaque omnis qui\nrerum modi sint quae numquam exercitationem\natque aut praesentium ipsa sit neque qui sint aut" - }, - { - "postId": 34, - "id": 167, - "name": "ea nam iste est repudiandae", - "email": "Eloy@vladimir.com", - "body": "molestiae voluptatem qui\nid facere nostrum quasi asperiores rerum\nquisquam est repellendus\ndeleniti eos aut sed nemo non" - }, - { - "postId": 34, - "id": 168, - "name": "quis harum voluptatem et culpa", - "email": "Gabrielle@jada.co.uk", - "body": "cupiditate optio in quidem adipisci sit dolor id\net tenetur quo sit odit\naperiam illum optio magnam qui\nmolestiae eligendi harum optio dolores dolor quaerat nostrum" - }, - { - "postId": 34, - "id": 169, - "name": "dolor dolore similique tempore ducimus", - "email": "Lee@dawn.net", - "body": "unde non aliquid magni accusantium architecto et\nrerum autem eos explicabo et\nodio facilis sed\nrerum ex esse beatae quia" - }, - { - "postId": 34, - "id": 170, - "name": "cupiditate labore omnis consequatur", - "email": "Gideon.Hyatt@jalen.tv", - "body": "amet id deserunt ipsam\ncupiditate distinctio nulla voluptatem\ncum possimus voluptate\nipsum quidem laudantium quos nihil" - }, - { - "postId": 35, - "id": 171, - "name": "voluptatibus qui est et", - "email": "Gerda.Reynolds@ceasar.co.uk", - "body": "sed non beatae placeat qui libero nam eaque qui\nquia ut ad doloremque\nsequi unde quidem adipisci debitis autem velit\narchitecto aperiam eos nihil enim dolores veritatis omnis ex" - }, - { - "postId": 35, - "id": 172, - "name": "corporis ullam quo", - "email": "Ivah@brianne.net", - "body": "nemo ullam omnis sit\nlabore perferendis et eveniet nostrum\ndignissimos expedita iusto\noccaecati quia sit quibusdam" - }, - { - "postId": 35, - "id": 173, - "name": "nulla accusamus saepe debitis cum", - "email": "Ethyl_Bogan@candace.co.uk", - "body": "asperiores hic fugiat aut et temporibus mollitia quo quam\ncumque numquam labore qui illum vel provident quod\npariatur natus incidunt\nsunt error voluptatibus vel voluptas maiores est vero possimus" - }, - { - "postId": 35, - "id": 174, - "name": "iure praesentium ipsam", - "email": "Janelle_Guann@americo.info", - "body": "sit dolores consequatur qui voluptas sunt\nearum at natus alias excepturi dolores\nmaiores pariatur at reiciendis\ndolor esse optio" - }, - { - "postId": 35, - "id": 175, - "name": "autem totam velit officiis voluptates et ullam rem", - "email": "Alfonzo.Barton@kelley.co.uk", - "body": "culpa non ea\nperspiciatis exercitationem sed natus sit\nenim voluptatum ratione omnis consequuntur provident commodi omnis\nquae odio sit at tempora" - }, - { - "postId": 36, - "id": 176, - "name": "ipsam deleniti incidunt repudiandae voluptatem maxime provident non dolores", - "email": "Esther@ford.me", - "body": "quam culpa fugiat\nrerum impedit ratione vel ipsam rem\ncommodi qui rem eum\nitaque officiis omnis ad" - }, - { - "postId": 36, - "id": 177, - "name": "ab cupiditate blanditiis ea sunt", - "email": "Naomie_Cronin@rick.co.uk", - "body": "ut facilis sapiente\nquia repellat autem et aut delectus sint\nautem nulla debitis\nomnis consequuntur neque" - }, - { - "postId": 36, - "id": 178, - "name": "rerum ex quam enim sunt", - "email": "Darryl@reginald.us", - "body": "sit maxime fugit\nsequi culpa optio consequatur voluptatem dolor expedita\nenim iure eum reprehenderit doloremque aspernatur modi\nvoluptatem culpa nostrum quod atque rerum sint laboriosam et" - }, - { - "postId": 36, - "id": 179, - "name": "et iure ex rerum qui", - "email": "Thea@aurelio.org", - "body": "non saepe ipsa velit sunt\ntotam ipsum optio voluptatem\nnesciunt qui iste eum\net deleniti ullam" - }, - { - "postId": 36, - "id": 180, - "name": "autem tempora a iusto eum aut voluptatum", - "email": "Carolyn@eloisa.biz", - "body": "recusandae temporibus nihil non alias consequatur\nlibero voluptatem sed soluta accusamus\na qui reiciendis officiis ad\nquia laborum libero et rerum voluptas sed ut et" - }, - { - "postId": 37, - "id": 181, - "name": "similique ut et non laboriosam in eligendi et", - "email": "Milan.Schoen@cortney.io", - "body": "dolor iure corrupti\net eligendi nesciunt voluptatum autem\nconsequatur in sapiente\ndolor voluptas dolores natus iusto qui et in perferendis" - }, - { - "postId": 37, - "id": 182, - "name": "soluta corporis excepturi consequatur perspiciatis quia voluptatem", - "email": "Sabrina@raymond.biz", - "body": "voluptatum voluptatem nisi consequatur et\nomnis nobis odio neque ab enim veniam\nsit qui aperiam odit voluptatem facere\nnesciunt esse nemo" - }, - { - "postId": 37, - "id": 183, - "name": "praesentium quod quidem optio omnis qui", - "email": "Hildegard@alford.ca", - "body": "tempora soluta voluptas deserunt\nnon fugiat similique\nest natus enim eum error magni soluta\ndolores sit doloremque" - }, - { - "postId": 37, - "id": 184, - "name": "veritatis velit quasi quo et voluptates dolore", - "email": "Lowell.Pagac@omari.biz", - "body": "odio saepe ad error minima itaque\nomnis fuga corrupti qui eaque cupiditate eum\nvitae laborum rerum ut reprehenderit architecto sit debitis magnam\nqui corrupti cum quidem commodi facere corporis" - }, - { - "postId": 37, - "id": 185, - "name": "natus assumenda ut", - "email": "Vivianne@ima.us", - "body": "deleniti non et corrupti delectus ea cupiditate\nat nihil fuga rerum\ntemporibus doloribus unde sed alias\nducimus perspiciatis quia debitis fuga" - }, - { - "postId": 38, - "id": 186, - "name": "voluptas distinctio qui similique quasi voluptatem non sit", - "email": "Yasmin.Prohaska@hanna.co.uk", - "body": "asperiores eaque error sunt ut natus et omnis\nexpedita error iste vitae\nsit alias voluptas voluptatibus quia iusto quia ea\nenim facere est quam ex" - }, - { - "postId": 38, - "id": 187, - "name": "maiores iste dolor itaque nemo voluptas", - "email": "Ursula.Kirlin@eino.org", - "body": "et enim necessitatibus velit autem magni voluptas\nat maxime error sunt nobis sit\ndolor beatae harum rerum\ntenetur facere pariatur et perferendis voluptas maiores nihil eaque" - }, - { - "postId": 38, - "id": 188, - "name": "quisquam quod quia nihil animi minima facere odit est", - "email": "Nichole_Bartoletti@mozell.me", - "body": "quam magni adipisci totam\nut reprehenderit ut tempore non asperiores repellendus architecto aperiam\ndignissimos est aut reiciendis consectetur voluptate nihil culpa at\nmolestiae labore qui ea" - }, - { - "postId": 38, - "id": 189, - "name": "ut iusto asperiores delectus", - "email": "Lottie_Wyman@jasen.biz", - "body": "nostrum excepturi debitis cum\narchitecto iusto laudantium odit aut dolor voluptatem consectetur nulla\nmollitia beatae autem quasi nemo repellendus ut ea et\naut architecto odio cum quod optio" - }, - { - "postId": 38, - "id": 190, - "name": "dignissimos voluptatibus libero", - "email": "Dominique_Hermann@paige.ca", - "body": "laudantium vero similique eum\niure iste culpa praesentium\nmolestias doloremque alias et at doloribus\naperiam natus est illo quo ratione porro excepturi" - }, - { - "postId": 39, - "id": 191, - "name": "est perferendis eos dolores maxime rerum qui", - "email": "Eugene@mohammed.net", - "body": "sit vero aut voluptatem soluta corrupti dolor cum\nnulla ipsa accusamus aut suscipit ut dicta ut nemo\nut et ut sit voluptas modi\nillum suscipit ea debitis aut ullam harum" - }, - { - "postId": 39, - "id": 192, - "name": "sunt veritatis quisquam est et porro nesciunt excepturi a", - "email": "Janick@marty.me", - "body": "dolore velit autem perferendis hic\ntenetur quo rerum\nimpedit error sit eaque ut\nad in expedita et nesciunt sit aspernatur repudiandae" - }, - { - "postId": 39, - "id": 193, - "name": "quia velit nostrum eligendi voluptates", - "email": "Alena@deron.name", - "body": "laudantium consequatur sed adipisci a\nodit quia necessitatibus qui\nnumquam expedita est accusantium nostrum\noccaecati perspiciatis molestiae nostrum atque" - }, - { - "postId": 39, - "id": 194, - "name": "non ut sunt ut eius autem ipsa eos sapiente", - "email": "Alphonso_Rosenbaum@valentin.co.uk", - "body": "aut distinctio iusto autem sit libero deleniti\nest soluta non perferendis illo\neveniet corrupti est sint quae\nsed sunt voluptatem" - }, - { - "postId": 39, - "id": 195, - "name": "tempore vel accusantium qui quidem esse ut aut", - "email": "Frank@rosalind.name", - "body": "culpa voluptas quidem eos quis excepturi\nquasi corporis provident enim\nprovident velit ex occaecati deleniti\nid aspernatur fugiat eligendi" - }, - { - "postId": 40, - "id": 196, - "name": "totam vel saepe aut qui velit quis", - "email": "Jenifer_Lowe@reuben.ca", - "body": "eum laborum quidem omnis facere harum ducimus dolores quaerat\ncorporis quidem aliquid\nquod aut aut at dolorum aspernatur reiciendis\nexercitationem quasi consectetur asperiores vero blanditiis dolor" - }, - { - "postId": 40, - "id": 197, - "name": "non perspiciatis omnis facere rem", - "email": "Cecelia_Nitzsche@marty.com", - "body": "fugit ut laborum provident\nquos provident voluptatibus quam non\nsed accusantium explicabo dolore quia distinctio voluptatibus et\nconsequatur eos qui iure minus eaque praesentium" - }, - { - "postId": 40, - "id": 198, - "name": "quod vel enim sit quia ipsa quo dolores", - "email": "Christop_Friesen@jordan.me", - "body": "est veritatis mollitia atque quas et sint et dolor\net ut beatae aut\nmagni corporis dolores voluptatibus optio molestiae enim minus est\nreiciendis facere voluptate rem officia doloribus ut" - }, - { - "postId": 40, - "id": 199, - "name": "pariatur aspernatur nam atque quis", - "email": "Cooper_Boehm@damian.biz", - "body": "veniam eos ab voluptatem in fugiat ipsam quis\nofficiis non qui\nquia ut id voluptates et a molestiae commodi quam\ndolorem enim soluta impedit autem nulla" - }, - { - "postId": 40, - "id": 200, - "name": "aperiam et omnis totam", - "email": "Amir@kaitlyn.org", - "body": "facere maxime alias aspernatur ab quibusdam necessitatibus\nratione similique error enim\nsed minus et\net provident minima voluptatibus" - }, - { - "postId": 41, - "id": 201, - "name": "et adipisci aliquam a aperiam ut soluta", - "email": "Cleve@royal.us", - "body": "est officiis placeat\nid et iusto ut fugit numquam\neos aut voluptas ad quia tempore qui quibusdam doloremque\nrecusandae tempora qui" - }, - { - "postId": 41, - "id": 202, - "name": "blanditiis vel fuga odio qui", - "email": "Donnell@polly.net", - "body": "sequi expedita quibusdam enim ipsam\nbeatae ad eum placeat\nperspiciatis quis in nulla porro voluptas quia\nesse et quibusdam" - }, - { - "postId": 41, - "id": 203, - "name": "ab enim adipisci laudantium impedit qui sed", - "email": "Bonita@karl.biz", - "body": "eum voluptates id autem sequi qui omnis commodi\nveniam et laudantium aut\net molestias esse asperiores et quaerat\npariatur non officia voluptatibus" - }, - { - "postId": 41, - "id": 204, - "name": "autem voluptates voluptas nihil", - "email": "Shea@angelina.biz", - "body": "voluptatibus pariatur illo\nautem quia aut ullam laudantium quod laborum officia\ndicta sit consequatur quis delectus vel\nomnis laboriosam laborum vero ipsa voluptas" - }, - { - "postId": 41, - "id": 205, - "name": "et reiciendis ullam quae", - "email": "Omari@veronica.us", - "body": "voluptatem accusamus delectus natus quasi aliquid\nporro ab id ea aut consequatur dignissimos quod et\naspernatur sapiente cum corrupti\npariatur veritatis unde" - }, - { - "postId": 42, - "id": 206, - "name": "deserunt eveniet quam vitae velit", - "email": "Sophie@antoinette.ca", - "body": "nam iusto minus expedita numquam\net id quis\nvoluptatibus minima porro facilis dolores beatae aut sit\naut quia suscipit" - }, - { - "postId": 42, - "id": 207, - "name": "asperiores sed voluptate est", - "email": "Jessika@crystel.ca", - "body": "nulla quos harum commodi\naperiam qui et dignissimos\nreiciendis ut quia est corrupti itaque\nlaboriosam debitis suscipit" - }, - { - "postId": 42, - "id": 208, - "name": "excepturi aut libero incidunt doloremque at", - "email": "Cesar_Volkman@letitia.biz", - "body": "enim aut doloremque mollitia provident molestiae omnis esse excepturi\nofficiis tempora sequi molestiae veniam voluptatem\nrecusandae omnis temporibus et deleniti laborum sed ipsa\nmolestiae eum aut" - }, - { - "postId": 42, - "id": 209, - "name": "repudiandae consectetur dolore", - "email": "Maureen_Mueller@lance.us", - "body": "officiis qui eos voluptas laborum error\nsunt repellat quis nisi unde velit\ndelectus eum molestias tempora quia ut aut\nconsequatur cupiditate quis sint in eum voluptates" - }, - { - "postId": 42, - "id": 210, - "name": "quibusdam provident accusamus id aut totam eligendi", - "email": "Eriberto@geovany.ca", - "body": "praesentium odit quos et tempora eum voluptatem non\nnon aut eaque consectetur reprehenderit in qui eos nam\nnemo ea eos\nea nesciunt consequatur et" - }, - { - "postId": 43, - "id": 211, - "name": "rerum voluptate dolor", - "email": "Faustino.Keeling@morris.co.uk", - "body": "odio temporibus est ut a\naut commodi minima tempora eum\net fuga omnis alias deleniti facere totam unde\nimpedit voluptas et possimus consequatur necessitatibus qui velit" - }, - { - "postId": 43, - "id": 212, - "name": "et maiores sed temporibus cumque voluptatem sunt necessitatibus in", - "email": "Viola@aric.co.uk", - "body": "aut vero sint ut et voluptate\nsunt quod velit impedit quia\ncupiditate dicta magni ut\neos blanditiis assumenda pariatur nemo est tempore velit" - }, - { - "postId": 43, - "id": 213, - "name": "ratione architecto in est voluptatem quibusdam et", - "email": "Felton_Huel@terrell.biz", - "body": "at non dolore molestiae\nautem rerum id\ncum facilis sit necessitatibus accusamus quia officiis\nsint ea sit natus rerum est nemo perspiciatis ea" - }, - { - "postId": 43, - "id": 214, - "name": "dicta deserunt tempore", - "email": "Ferne_Bogan@angus.info", - "body": "nam nesciunt earum sequi dolorum\net fuga sint quae architecto\nin et et ipsam veniam ad voluptas rerum animi\nillum temporibus enim rerum est" - }, - { - "postId": 43, - "id": 215, - "name": "sint culpa cupiditate ut sit quas qui voluptas qui", - "email": "Amy@reymundo.org", - "body": "esse ab est deleniti dicta non\ninventore veritatis cupiditate\neligendi sequi excepturi assumenda a harum sint aut eaque\nrerum molestias id excepturi quidem aut" - }, - { - "postId": 44, - "id": 216, - "name": "voluptatem esse sint alias", - "email": "Jaylan.Mayert@norbert.biz", - "body": "minima quaerat voluptatibus iusto earum\nquia nihil et\nminus deleniti aspernatur voluptatibus tempore sit molestias\narchitecto velit id debitis" - }, - { - "postId": 44, - "id": 217, - "name": "eos velit velit esse autem minima voluptas", - "email": "Cristina.DAmore@destini.biz", - "body": "aperiam rerum aut provident cupiditate laboriosam\nenim placeat aut explicabo\nvoluptatum similique rerum eaque eligendi\nnobis occaecati perspiciatis sint ullam" - }, - { - "postId": 44, - "id": 218, - "name": "voluptatem qui deserunt dolorum in voluptates similique et qui", - "email": "Ettie_Bashirian@lambert.biz", - "body": "rem qui est\nfacilis qui voluptatem quis est veniam quam aspernatur dicta\ndolore id sapiente saepe consequatur\nenim qui impedit culpa ex qui voluptas dolor" - }, - { - "postId": 44, - "id": 219, - "name": "qui unde recusandae omnis ut explicabo neque magni veniam", - "email": "Lizeth@kellen.org", - "body": "est et dolores voluptas aut molestiae nam eos saepe\nexpedita eum ea tempore sit iure eveniet\niusto enim quos quo\nrepellendus laudantium eum fugiat aut et" - }, - { - "postId": 44, - "id": 220, - "name": "vel autem quia in modi velit", - "email": "Vladimir_Schumm@sharon.tv", - "body": "illum ea eum quia\ndoloremque modi ducimus voluptatum eaque aperiam accusamus eos quia\nsed rerum aperiam sunt quo\nea veritatis natus eos deserunt voluptas ea voluptate" - }, - { - "postId": 45, - "id": 221, - "name": "reprehenderit rem voluptatem voluptate recusandae dolore distinctio", - "email": "Madonna@will.com", - "body": "rerum possimus asperiores non dolores maiores tenetur ab\nsuscipit laudantium possimus ab iure\ndistinctio assumenda iste adipisci optio est sed eligendi\ntemporibus perferendis tempore soluta" - }, - { - "postId": 45, - "id": 222, - "name": "rerum aliquam ducimus repudiandae perferendis", - "email": "Cicero_Goldner@elenor.tv", - "body": "cum officiis impedit neque a sed dolorum accusamus eaque\nrepellat natus aut commodi sint fugit consequatur corporis\nvoluptatum dolorum sequi perspiciatis ut facilis\ndelectus pariatur consequatur at aut temporibus facere vitae" - }, - { - "postId": 45, - "id": 223, - "name": "accusantium aliquid consequuntur minus quae quis et autem", - "email": "Zella@jan.net", - "body": "maiores perspiciatis quo alias doloremque\nillum iusto possimus impedit\nvelit voluptatem assumenda possimus\nut nesciunt eum et deleniti molestias harum excepturi" - }, - { - "postId": 45, - "id": 224, - "name": "eum dolorum ratione vitae expedita", - "email": "Robin_Jacobi@verdie.net", - "body": "perferendis quae est velit ipsa autem adipisci ex rerum\nvoluptatem occaecati velit perferendis aut tenetur\ndeleniti eaque quasi suscipit\ndolorum nobis vel et aut est eos" - }, - { - "postId": 45, - "id": 225, - "name": "occaecati et corrupti expedita", - "email": "Lawson@demarco.co.uk", - "body": "doloribus illum tempora aliquam qui perspiciatis dolorem ratione velit\nfacere nobis et fugiat modi\nfugiat dolore at\nducimus voluptate porro qui architecto optio unde deleniti" - }, - { - "postId": 46, - "id": 226, - "name": "assumenda officia quam ex natus minima sint quia", - "email": "Benton@jayde.tv", - "body": "provident sed similique\nexplicabo fugiat quasi saepe voluptatem corrupti recusandae\nvoluptas repudiandae illum tenetur mollitia\nsint in enim earum est" - }, - { - "postId": 46, - "id": 227, - "name": "omnis error aut doloremque ipsum ducimus", - "email": "Melody@london.name", - "body": "est quo quod tempora fuga debitis\neum nihil nemo nisi consequatur sequi nesciunt dolorum et\ncumque maxime qui consequatur mollitia dicta iusto aut\nvero recusandae ut dolorem provident voluptatibus suscipit sint" - }, - { - "postId": 46, - "id": 228, - "name": "eaque expedita temporibus iure velit eligendi labore dignissimos molestiae", - "email": "Wyman.Swaniawski@marjorie.name", - "body": "quibusdam dolores eveniet qui minima\nmagni perspiciatis pariatur\nullam dolor sit ex molestiae in nulla unde rerum\nquibusdam deleniti nisi" - }, - { - "postId": 46, - "id": 229, - "name": "maxime veniam at", - "email": "Deborah@fletcher.co.uk", - "body": "unde aliquam ipsam eaque quia laboriosam exercitationem totam illo\nnon et dolore ipsa\nlaborum et sapiente fugit voluptatem\net debitis quia optio et minima et nostrum" - }, - { - "postId": 46, - "id": 230, - "name": "illo dolor corrupti quia pariatur in", - "email": "Dario@barton.info", - "body": "neque ullam eos amet\nratione architecto doloribus qui est nisi\noccaecati unde expedita perspiciatis animi tenetur minus eveniet aspernatur\neius nihil adipisci aut" - }, - { - "postId": 47, - "id": 231, - "name": "omnis minima dicta aliquam excepturi", - "email": "Kelton_McKenzie@danial.us", - "body": "veritatis laudantium laboriosam ut maxime sed voluptate\nconsequatur itaque occaecati voluptatum est\nut itaque aperiam eligendi at vel minus\ndicta tempora nihil pariatur libero est" - }, - { - "postId": 47, - "id": 232, - "name": "voluptatem excepturi sit et sed qui ipsum quam consequatur", - "email": "Itzel@fritz.io", - "body": "ullam modi consequatur officia dolor non explicabo et\neum minus dicta dolores blanditiis dolore\nnobis assumenda harum velit ullam et cupiditate\net commodi dolor harum et sed cum reprehenderit omnis" - }, - { - "postId": 47, - "id": 233, - "name": "qui dolores maxime autem enim repellendus culpa nostrum consequuntur", - "email": "Jacquelyn_Kutch@kaya.co.uk", - "body": "aperiam quo quis\nnobis error et culpa veritatis\nquae sapiente nobis architecto doloribus quia laboriosam\nest consequatur et recusandae est eius" - }, - { - "postId": 47, - "id": 234, - "name": "natus et necessitatibus animi", - "email": "Cheyanne.Schowalter@alycia.biz", - "body": "itaque voluptatem voluptas velit non est rerum incidunt\nvitae aut labore accusantium in atque\nrepudiandae quos necessitatibus\nautem ea excepturi" - }, - { - "postId": 47, - "id": 235, - "name": "odio sed accusantium iure repudiandae officiis ut autem illo", - "email": "Macey@abbie.org", - "body": "ea iusto laboriosam sit\nvoluptatibus magni ratione eum\net minus perferendis\neius rerum suscipit velit culpa ipsa ipsam aperiam est" - }, - { - "postId": 48, - "id": 236, - "name": "cupiditate rerum voluptate quo facere repudiandae", - "email": "Freeda.Kirlin@eddie.ca", - "body": "itaque error cupiditate asperiores ut aspernatur veniam qui\ndoloribus sit aliquid pariatur dicta deleniti qui alias dignissimos\nrecusandae eaque repellendus est et dolorem aut non\nexplicabo voluptas est beatae vel temporibus" - }, - { - "postId": 48, - "id": 237, - "name": "recusandae deserunt possimus voluptatibus ipsam iste consequatur consequatur", - "email": "Jennifer.Rowe@zoe.org", - "body": "aut culpa quis modi\nlibero hic dolore provident officiis placeat minima vero\net iste dolores aut voluptatem saepe unde\nvero temporibus sunt corrupti voluptate" - }, - { - "postId": 48, - "id": 238, - "name": "voluptatem nam ducimus non molestiae", - "email": "Providenci.Heller@lenna.info", - "body": "et nostrum cupiditate nobis facere et est illo\nconsequatur harum voluptatem totam\nmolestiae voluptas consequatur quibusdam aut\nmodi impedit necessitatibus et nisi nesciunt adipisci" - }, - { - "postId": 48, - "id": 239, - "name": "voluptatum debitis qui aut voluptas eos quibusdam et", - "email": "Emerald_Murazik@darrell.biz", - "body": "esse rem ut neque magni voluptatem id qui\naut ut vel autem non qui quam sit\nimpedit quis sit illum laborum\naut at vel eos nihil quo" - }, - { - "postId": 48, - "id": 240, - "name": "est dolorem est placeat provident non nihil", - "email": "Joseph@corrine.com", - "body": "necessitatibus nulla perferendis ad inventore earum delectus\nvitae illo sed perferendis\nofficiis quo eligendi voluptatem animi totam perspiciatis\nrepellat quam eum placeat est tempore facere" - }, - { - "postId": 49, - "id": 241, - "name": "reprehenderit inventore soluta ut aliquam", - "email": "Lemuel@willow.name", - "body": "quisquam asperiores voluptas\nmodi tempore officia quod hic dolor omnis asperiores\narchitecto aut vel odio quisquam sunt\ndeserunt soluta illum" - }, - { - "postId": 49, - "id": 242, - "name": "quis sit aut vero quo accusamus", - "email": "Sven@gudrun.info", - "body": "dolores minus sequi laudantium excepturi deserunt rerum voluptatem\npariatur harum natus sed dolore quis\nconsectetur quod inventore laboriosam et in dolor beatae rerum\nquia rerum qui recusandae quo officiis fugit" - }, - { - "postId": 49, - "id": 243, - "name": "quaerat natus illum", - "email": "Jennifer@shania.ca", - "body": "rem ut cumque tempore sed\naperiam unde tenetur ab maiores officiis alias\naut nemo veniam dolor est eum sunt a\nesse ratione deserunt et" - }, - { - "postId": 49, - "id": 244, - "name": "labore temporibus ipsa at blanditiis autem", - "email": "Eldora@madge.com", - "body": "est et itaque qui laboriosam dolor ut debitis\ncumque et et dolor\neaque enim et architecto\net quia reiciendis quis" - }, - { - "postId": 49, - "id": 245, - "name": "et rerum fuga blanditiis provident eligendi iste eos", - "email": "Litzy@kaylie.io", - "body": "vel nam nemo sed vitae\nrepellat necessitatibus dolores deserunt dolorum\nminima quae velit et nemo\nsit expedita nihil consequatur autem quia maiores" - }, - { - "postId": 50, - "id": 246, - "name": "magnam earum qui eaque sunt excepturi", - "email": "Jaycee.Turner@euna.name", - "body": "quia est sed eos animi optio dolorum\nconsequatur reiciendis exercitationem ipsum nihil omnis\nbeatae sed corporis enim quisquam\net blanditiis qui nihil" - }, - { - "postId": 50, - "id": 247, - "name": "vel aut blanditiis magni accusamus dolor soluta", - "email": "Wilbert@cheyenne.ca", - "body": "explicabo nam nihil atque sint aut\nqui qui rerum excepturi soluta quis et\net mollitia et voluptate minima nihil\nsed quaerat dolor earum tempore et non est voluptatem" - }, - { - "postId": 50, - "id": 248, - "name": "voluptatum sint dicta voluptas aut ut", - "email": "Rebecca_Hessel@edna.net", - "body": "assumenda aut quis repellendus\nnihil impedit cupiditate nemo\nsit sequi laudantium aut voluptas nam dolore magnam\nminima aspernatur vero sapiente" - }, - { - "postId": 50, - "id": 249, - "name": "quibusdam dignissimos aperiam sint commodi", - "email": "Christiana@lawrence.info", - "body": "non repudiandae dicta et commodi\nsint dolores facere eos nesciunt autem quia\nplaceat quaerat non culpa quasi dolores voluptas\ndolorum placeat non atque libero odit autem sunt" - }, - { - "postId": 50, - "id": 250, - "name": "perferendis magnam natus exercitationem eveniet sunt", - "email": "Samara@shaun.org", - "body": "doloremque quae ratione cumque\nexcepturi eligendi delectus maiores necessitatibus veniam\nfugiat exercitationem consectetur vel earum\nquia illo explicabo molestiae enim rem deserunt et omnis" - }, - { - "postId": 51, - "id": 251, - "name": "veritatis sint eius", - "email": "Ayden_Hickle@stephany.tv", - "body": "sit vero at voluptatem corporis adipisci\nerror sit aut nihil rerum doloremque dolorum ipsum\neum ut numquam sapiente ipsam nam blanditiis ut quasi\nfacilis optio rerum qui temporibus esse excepturi eaque" - }, - { - "postId": 51, - "id": 252, - "name": "qui alias beatae iusto omnis placeat recusandae ut", - "email": "Carissa.Krajcik@jean.name", - "body": "exercitationem quisquam sed\neius et cum reiciendis deleniti non\nperspiciatis aut voluptatum deserunt\nsint dignissimos est sed architecto sed" - }, - { - "postId": 51, - "id": 253, - "name": "voluptate ipsum corporis quis provident voluptatem eos asperiores", - "email": "Jayde@geovanny.io", - "body": "debitis dignissimos ut illum\nrerum voluptatem ut qui labore\noptio quaerat iure\niste consequuntur praesentium vero blanditiis quibusdam aut" - }, - { - "postId": 51, - "id": 254, - "name": "velit inventore et eius saepe", - "email": "Ardella@khalid.biz", - "body": "laboriosam voluptas aut quibusdam mollitia sunt non\ndolores illum fugiat ex vero nemo aperiam porro quam\nexpedita est vel voluptatem sit voluptas consequuntur quis eligendi\nomnis id nisi ducimus sapiente odit quam" - }, - { - "postId": 51, - "id": 255, - "name": "impedit et sapiente et tempore repellendus", - "email": "Delta_Welch@carleton.tv", - "body": "nihil esse aut\ndebitis nostrum mollitia similique minus aspernatur possimus\nomnis eaque non eveniet\nrerum qui iure laboriosam" - }, - { - "postId": 52, - "id": 256, - "name": "tempore distinctio quam", - "email": "Carlee_Heathcote@harley.tv", - "body": "nemo deleniti sunt praesentium quis quam repellendus\nconsequatur non est ex fugiat distinctio aliquam explicabo\naspernatur omnis debitis sint consequatur\nquo autem natus veritatis" - }, - { - "postId": 52, - "id": 257, - "name": "illum non quod vel voluptas quos", - "email": "Delpha_Cormier@raymond.org", - "body": "facere at voluptatem\nrepellendus omnis perspiciatis placeat aspernatur nobis blanditiis ut deleniti\nquis non cumque laborum sit id ratione vel sequi\nfacere doloremque beatae aut maxime non" - }, - { - "postId": 52, - "id": 258, - "name": "omnis quia fugit nisi officiis aspernatur occaecati et", - "email": "Glenna@caesar.org", - "body": "aut cum sint qui facere blanditiis magnam consequuntur perspiciatis\nharum impedit reprehenderit iste doloribus quia quo facere\net explicabo aut voluptate modi dolorem\nrem aut nobis ut ad voluptatum ipsum eos maxime" - }, - { - "postId": 52, - "id": 259, - "name": "animi minima ducimus tempore officiis qui", - "email": "Hoyt_Dickens@napoleon.ca", - "body": "itaque occaecati non aspernatur\nvelit repudiandae sit rerum esse quibusdam unde molestias\nexplicabo dolorem vero consequatur quis et libero\nvoluptatem totam vel sapiente autem dolorum consequuntur" - }, - { - "postId": 52, - "id": 260, - "name": "qui dolore delectus et omnis quia", - "email": "Wendell.Marvin@maegan.net", - "body": "aliquid molestias nemo aut est maxime\nlaboriosam et consequatur laudantium\ncommodi et corrupti\nharum quasi minima ratione sint magni sapiente ut" - }, - { - "postId": 53, - "id": 261, - "name": "aut veritatis quasi voluptatem enim dolor soluta temporibus", - "email": "Virgie@layne.org", - "body": "sapiente qui est quod\ndebitis qui est optio consequuntur\nalias hic amet ut non ad qui provident\nquia provident aspernatur corrupti occaecati" - }, - { - "postId": 53, - "id": 262, - "name": "ipsa aliquid laborum quidem recusandae dolorum quia", - "email": "Tia@kirsten.info", - "body": "similique harum iste ipsam non dolores facere esse\net beatae error necessitatibus laboriosam fugiat culpa esse occaecati\nut provident ut et dolorum nam\ndelectus impedit aut blanditiis fugiat est unde" - }, - { - "postId": 53, - "id": 263, - "name": "vitae voluptatem dolor iure quo non atque", - "email": "Marco@jennyfer.biz", - "body": "debitis dolore est\nut eos velit accusamus\nnon nobis ipsa nemo quas facilis quia hic\nofficia quam et possimus voluptas voluptatem quisquam tempore delectus" - }, - { - "postId": 53, - "id": 264, - "name": "cum ab voluptates aut", - "email": "Taya@milan.biz", - "body": "consectetur maiores ab est qui aliquid porro\nipsa labore incidunt\niste deserunt quia aperiam quis sit perferendis\net sint iste" - }, - { - "postId": 53, - "id": 265, - "name": "omnis incidunt est molestias", - "email": "Lenora@derrick.biz", - "body": "et quibusdam saepe labore delectus et earum quis perferendis\nlaborum soluta veritatis\nea veritatis quidem accusantium est aut porro rerum\nquia est consequatur voluptatem numquam laudantium repellendus" - }, - { - "postId": 54, - "id": 266, - "name": "eum enim provident atque eum", - "email": "Carolina.Auer@polly.co.uk", - "body": "non et voluptas\neaque atque esse qui molestias porro quam veniam voluptatibus\nminima ut velit velit ut architecto deleniti\nab sint deserunt possimus quas velit et eum" - }, - { - "postId": 54, - "id": 267, - "name": "ea commodi provident veritatis voluptatem voluptates aperiam", - "email": "Jaylan.Braun@lane.us", - "body": "magnam similique animi eos explicabo natus\nprovident cumque sit maxime velit\nveritatis fuga esse dolor hic nihil nesciunt assumenda\naliquid vero modi alias qui quia doloribus est" - }, - { - "postId": 54, - "id": 268, - "name": "eum et eos delectus", - "email": "Javier.Dicki@damien.org", - "body": "velit earum perspiciatis ea recusandae nihil consectetur ut\nmaxime repellendus doloribus\naperiam ut ex ratione quia esse magni\nducimus rerum vel rerum officiis suscipit nihil qui" - }, - { - "postId": 54, - "id": 269, - "name": "molestiae vitae pariatur", - "email": "Khalil_Sawayn@tanya.net", - "body": "quos sed unde repudiandae aut porro dignissimos qui\noccaecati sed alias enim\nvoluptates nesciunt sit ut adipisci est\nexpedita quae corrupti" - }, - { - "postId": 54, - "id": 270, - "name": "rerum adipisci et ut sit sit dolores", - "email": "Tom.Russel@pattie.org", - "body": "quas placeat repudiandae a delectus facere exercitationem consectetur\nfacilis quas sequi est mollitia\nest vero hic laudantium maiores\nquisquam itaque aut maxime ut cumque quia doloremque voluptatem" - }, - { - "postId": 55, - "id": 271, - "name": "et et repellat quasi non ea similique", - "email": "Ethelyn.Moore@gabe.info", - "body": "quae eaque reprehenderit\nsuscipit facilis ut tenetur blanditiis sint occaecati\naccusantium expedita sed nostrum\nrerum sunt nam qui placeat consequatur et" - }, - { - "postId": 55, - "id": 272, - "name": "repudiandae ut velit dignissimos enim rem dolores odit", - "email": "Evangeline_Kuvalis@santina.ca", - "body": "consequuntur molestiae aut distinctio illo qui est sequi reprehenderit\nhic accusamus et officiis reprehenderit culpa\nest et numquam et\neius ipsa rerum velit" - }, - { - "postId": 55, - "id": 273, - "name": "et aperiam autem inventore nisi nulla reiciendis velit", - "email": "Orland@larry.name", - "body": "asperiores et minus non\ndolor dolorem et sint et ipsam\net enim quia sequi\nsed beatae culpa architecto nisi minima" - }, - { - "postId": 55, - "id": 274, - "name": "et vero nostrum tempore", - "email": "Micaela.Powlowski@saul.me", - "body": "quos illo consectetur dolores\ncupiditate enim rerum dicta sequi totam\naspernatur sed praesentium\nipsum voluptates perspiciatis ipsa accusantium et et" - }, - { - "postId": 55, - "id": 275, - "name": "error nulla est laudantium similique ad", - "email": "Imelda_Klein@melany.biz", - "body": "error et quasi qui facilis enim eum adipisci iste\nad nostrum sint corporis quam velit necessitatibus a\neius doloribus optio ad qui molestiae\nquaerat dignissimos voluptatem culpa aliquam explicabo commodi natus" - }, - { - "postId": 56, - "id": 276, - "name": "inventore amet ut debitis ipsam reiciendis molestiae autem sed", - "email": "Matt.Moen@gilda.org", - "body": "dolores tempora totam quas maxime voluptatem voluptas excepturi\nrecusandae quis odio exercitationem in\nconsectetur sed aut\nexcepturi eligendi sint consectetur repellendus aperiam" - }, - { - "postId": 56, - "id": 277, - "name": "dolorem aut ipsum alias ex ea quidem nostrum", - "email": "Rocky_Ullrich@rowena.name", - "body": "nihil ratione aliquam recusandae ipsa sunt doloribus labore molestiae\nofficia cum aliquid repudiandae et error\ninventore minima optio repellat aut\nea et maxime alias voluptas eius" - }, - { - "postId": 56, - "id": 278, - "name": "est pariatur similique quod voluptas et consequuntur nam molestiae", - "email": "Natalia@caitlyn.ca", - "body": "corporis perferendis dolorum error quo rerum aut odio veritatis\nsit deleniti aut eligendi quam doloremque aut ipsam sint\ndoloribus id voluptatem esse reprehenderit molestiae quia voluptatem\nincidunt illo beatae nihil corporis eligendi iure quo" - }, - { - "postId": 56, - "id": 279, - "name": "voluptas nihil aut dolor adipisci non", - "email": "Edythe@general.org", - "body": "natus atque ipsum voluptatem et\nnecessitatibus atque quia asperiores animi odit ratione quos\nest repellendus sit aut repudiandae animi aut\ncum blanditiis repudiandae saepe laborum" - }, - { - "postId": 56, - "id": 280, - "name": "culpa minima non consequatur sit autem quas sed ipsam", - "email": "Aglae@gerardo.name", - "body": "perferendis fugit expedita cumque\nexercitationem animi fugit aut earum\nnihil quia illum eum dicta ut\nquam commodi optio" - }, - { - "postId": 57, - "id": 281, - "name": "consequatur voluptates sed voluptatem fuga", - "email": "Bridie@pearl.ca", - "body": "eius voluptatem minus\net aliquid perspiciatis sint unde ut\nsimilique odio ullam vitae quisquam hic ex consequatur aliquid\nab nihil explicabo sint maiores aut et dolores nostrum" - }, - { - "postId": 57, - "id": 282, - "name": "et vitae culpa corrupti", - "email": "Aglae_Goldner@madisyn.co.uk", - "body": "ea consequatur placeat\nquo omnis illum voluptatem\nvoluptatem fugit aut dolorum recusandae ut et\ntenetur officia voluptas" - }, - { - "postId": 57, - "id": 283, - "name": "iste molestiae aut hic perspiciatis sint", - "email": "Owen_Moore@jeremy.org", - "body": "perspiciatis omnis eum nihil et porro facilis fuga qui\ndeleniti id et velit adipisci fuga voluptatibus voluptatum\ndebitis tempore dolorem atque consequatur ea perspiciatis sed\nqui temporibus doloremque" - }, - { - "postId": 57, - "id": 284, - "name": "soluta omnis maiores animi veniam voluptas et totam repellendus", - "email": "Jarred@dangelo.name", - "body": "rem ut sed\nnon cumque corrupti vel nam rerum autem\nnobis dolorem necessitatibus fugit corporis\nquos sint distinctio ex et animi tempore" - }, - { - "postId": 57, - "id": 285, - "name": "non est sunt consequatur reiciendis", - "email": "Remington_Mohr@vincenza.me", - "body": "est accusamus facere\nreprehenderit corporis ad et est fugit iure nulla et\ndoloribus reiciendis quasi autem voluptas\nipsam labore et pariatur quia" - }, - { - "postId": 58, - "id": 286, - "name": "dolore dignissimos distinctio", - "email": "Marco.Langworth@zoie.org", - "body": "doloremque accusantium necessitatibus architecto ut provident\nquaerat iusto eius omnis\nfuga laborum harum totam sunt velit\naut neque corporis atque" - }, - { - "postId": 58, - "id": 287, - "name": "voluptas ad autem maxime iusto eos dolorem ducimus est", - "email": "Sedrick@mertie.tv", - "body": "voluptatem perspiciatis voluptatum quaerat\nodit voluptates iure\nquisquam magnam voluptates ut non qui\naliquam aut ut amet sit consequatur ut suscipit" - }, - { - "postId": 58, - "id": 288, - "name": "numquam eius voluptas quibusdam soluta exercitationem", - "email": "Caleigh@eleanore.org", - "body": "est sed illo omnis delectus aut\nlaboriosam possimus incidunt est sunt at\nnemo voluptas ex ipsam\nvoluptatibus inventore velit sit et numquam omnis accusamus in" - }, - { - "postId": 58, - "id": 289, - "name": "voluptatem aut harum aut corporis dignissimos occaecati sequi quod", - "email": "Paolo@cristopher.com", - "body": "occaecati tempora unde\nmaiores aliquid in\nquo libero sint quidem at est facilis ipsa facere\nnostrum atque harum" - }, - { - "postId": 58, - "id": 290, - "name": "suscipit debitis eveniet nobis atque commodi quisquam", - "email": "Juana_Stamm@helmer.com", - "body": "pariatur veniam repellat quisquam tempore autem et voluptatem itaque\nea impedit ex molestiae placeat hic harum mollitia dolorem\ninventore accusantium aut quae quia rerum autem numquam\nnulla culpa quasi dolor" - }, - { - "postId": 59, - "id": 291, - "name": "occaecati et dolorum", - "email": "Pascale@fleta.ca", - "body": "nisi dicta numquam dolor\nrerum sed quaerat et\nsed sequi doloribus libero quos temporibus\nblanditiis optio est tempore qui" - }, - { - "postId": 59, - "id": 292, - "name": "consequatur et facere similique beatae explicabo eligendi consequuntur", - "email": "Molly_Kertzmann@tristin.me", - "body": "eos officiis omnis ab laborum nulla saepe exercitationem recusandae\nvoluptate minima voluptatem sint\nsunt est consequuntur dolor voluptatem odit\nmaxime similique deserunt et quod" - }, - { - "postId": 59, - "id": 293, - "name": "qui sint hic", - "email": "Kailee.Larkin@amina.org", - "body": "fugiat dicta quasi voluptatibus ea aut est aspernatur sed\ncorrupti harum non omnis eos eaque quos ut\nquia et et nisi rerum voluptates possimus quis\nrecusandae aperiam quia esse" - }, - { - "postId": 59, - "id": 294, - "name": "autem totam necessitatibus sit sunt minima aut quis", - "email": "Earnest.Sanford@lane.us", - "body": "ut est veritatis animi quos\nnam sed dolor\nitaque omnis nostrum autem molestiae\naut optio tempora ad sapiente quae voluptatem perferendis repellat" - }, - { - "postId": 59, - "id": 295, - "name": "ullam dignissimos non aut dolore", - "email": "Abigail@trudie.com", - "body": "voluptatem est aspernatur consequatur vel facere\nut omnis tenetur non ea eos\nquibusdam error odio\natque consectetur voluptatem eligendi" - }, - { - "postId": 60, - "id": 296, - "name": "hic eum sed dolore velit cupiditate quisquam ut inventore", - "email": "Name.Walter@zoie.me", - "body": "quasi dolorem veniam dignissimos\natque voluptas iure et quidem fugit velit et\nquod magnam illum quia et ea est modi\naut quis dolores" - }, - { - "postId": 60, - "id": 297, - "name": "dignissimos dolor facere", - "email": "Norma@abraham.co.uk", - "body": "eos exercitationem est ut voluptas accusamus qui\nvelit rerum ut\ndolorem eaque omnis eligendi mollitia\natque ea architecto dolorum delectus accusamus" - }, - { - "postId": 60, - "id": 298, - "name": "ipsam ut labore voluptatem quis id velit sunt", - "email": "Norberto_Weimann@ford.tv", - "body": "molestiae accusantium a tempore occaecati qui sunt optio eos\nexercitationem quas eius voluptatem\nomnis quibusdam autem\nmolestiae odio dolor quam laboriosam mollitia in quibusdam sunt" - }, - { - "postId": 60, - "id": 299, - "name": "laborum asperiores nesciunt itaque", - "email": "Nelson@charlene.biz", - "body": "voluptatem omnis pariatur aut saepe enim qui\naut illo aut sed aperiam expedita debitis\ntempore animi dolorem\nut libero et eos unde ex" - }, - { - "postId": 60, - "id": 300, - "name": "in dolore iusto ex molestias vero", - "email": "Letha@liliane.ca", - "body": "dolorem fugit quidem animi quas quisquam reprehenderit\noccaecati et dolor laborum nemo sed quas unde deleniti\nfacere eligendi placeat aliquid aspernatur commodi sunt impedit\nneque corrupti alias molestiae magni tempora" - }, - { - "postId": 61, - "id": 301, - "name": "id voluptatibus voluptas occaecati quia sunt eveniet et eius", - "email": "Tiana@jeramie.tv", - "body": "dolore maxime saepe dolor asperiores cupiditate nisi nesciunt\nvitae tempora ducimus vel eos perferendis\nfuga sequi numquam blanditiis sit sed inventore et\nut possimus soluta voluptas nihil aliquid sed earum" - }, - { - "postId": 61, - "id": 302, - "name": "quia voluptatem sunt voluptate ut ipsa", - "email": "Lindsey@caitlyn.net", - "body": "fuga aut est delectus earum optio impedit qui excepturi\niusto consequatur deserunt soluta sunt\net autem neque\ndolor ut saepe dolores assumenda ipsa eligendi" - }, - { - "postId": 61, - "id": 303, - "name": "excepturi itaque laudantium reiciendis dolorem", - "email": "Gregory.Kutch@shawn.info", - "body": "sit nesciunt id vitae ut itaque sapiente\nneque in at consequuntur perspiciatis dicta consequatur velit\nfacilis iste ut error sed\nin sequi expedita autem" - }, - { - "postId": 61, - "id": 304, - "name": "voluptatem quidem animi sit est nemo non omnis molestiae", - "email": "Murphy.Kris@casimer.me", - "body": "minus ab quis nihil quia suscipit vel\nperspiciatis sunt unde\naut ullam quo laudantium deleniti modi\nrerum illo error occaecati vel officiis facere" - }, - { - "postId": 61, - "id": 305, - "name": "non cum consequatur at nihil aut fugiat delectus quia", - "email": "Isidro_Kiehn@cristina.org", - "body": "repellendus quae labore sunt ut praesentium fuga reiciendis quis\ncorporis aut quis dolor facere earum\nexercitationem enim sunt nihil asperiores expedita\neius nesciunt a sit sit" - }, - { - "postId": 62, - "id": 306, - "name": "omnis nisi libero", - "email": "Kenton_Carter@yolanda.co.uk", - "body": "ab veritatis aspernatur molestiae explicabo ea saepe molestias sequi\nbeatae aut perferendis quaerat aut omnis illo fugiat\nquisquam hic doloribus maiores itaque\nvoluptas amet dolorem blanditiis" - }, - { - "postId": 62, - "id": 307, - "name": "id ab commodi est quis culpa", - "email": "Amos_Rohan@mozelle.tv", - "body": "sit tenetur aut eum quasi reiciendis dignissimos non nulla\nrepellendus ut quisquam\nnumquam provident et repellendus eum nihil blanditiis\nbeatae iusto sed eius sit sed doloremque exercitationem nihil" - }, - { - "postId": 62, - "id": 308, - "name": "enim ut optio architecto dolores nemo quos", - "email": "Timothy_Heathcote@jose.name", - "body": "officiis ipsa exercitationem impedit dolorem repellat adipisci qui\natque illum sapiente omnis et\nnihil esse et eum facilis aut impedit\nmaxime ullam et dolorem" - }, - { - "postId": 62, - "id": 309, - "name": "maiores et quisquam", - "email": "Otilia.Daniel@elvie.io", - "body": "impedit qui nemo\nreprehenderit sequi praesentium ullam veniam quaerat optio qui error\naperiam qui quisquam dolor est blanditiis molestias rerum et\nquae quam eum odit ab quia est ut" - }, - { - "postId": 62, - "id": 310, - "name": "sed qui atque", - "email": "Toni@joesph.biz", - "body": "quae quis qui ab rerum non hic\nconsequatur earum facilis atque quas dolore fuga ipsam\nnihil velit quis\nrerum sit nam est nulla nihil qui excepturi et" - }, - { - "postId": 63, - "id": 311, - "name": "veritatis nulla consequatur sed cumque", - "email": "Brisa@carrie.us", - "body": "officia provident libero explicabo tempora velit eligendi mollitia similique\nrerum sit aut consequatur ullam tenetur qui est vero\nrerum est et explicabo\nsit sunt ea exercitationem molestiae" - }, - { - "postId": 63, - "id": 312, - "name": "libero et distinctio repudiandae voluptatem dolores", - "email": "Jasen.Kihn@devon.biz", - "body": "ipsa id eum dolorum et officiis\nsaepe eos voluptatem\nnesciunt quos voluptas temporibus dolores ad rerum\nnon voluptatem aut fugit" - }, - { - "postId": 63, - "id": 313, - "name": "quia enim et", - "email": "Efren.Konopelski@madisyn.us", - "body": "corporis quo magnam sunt rerum enim vel\nrepudiandae suscipit corrupti ut ab qui debitis quidem adipisci\ndistinctio voluptatibus vitae molestias incidunt laboriosam quia quidem facilis\nquia architecto libero illum ut dicta" - }, - { - "postId": 63, - "id": 314, - "name": "enim voluptatem quam", - "email": "Demetris.Bergnaum@fae.io", - "body": "sunt cupiditate commodi est pariatur incidunt quis\nsuscipit saepe magnam amet enim\nquod quis neque\net modi rerum asperiores consequatur reprehenderit maiores" - }, - { - "postId": 63, - "id": 315, - "name": "maxime nulla perspiciatis ad quo quae consequatur quas", - "email": "Luella.Pollich@gloria.org", - "body": "repudiandae dolores nam quas\net incidunt odio dicta eum vero dolor quidem\ndolorem quisquam cumque\nmolestiae neque maxime rerum deserunt nam sequi" - }, - { - "postId": 64, - "id": 316, - "name": "totam est minima modi sapiente nobis impedit", - "email": "Sister.Morissette@adelia.io", - "body": "consequatur qui doloribus et rerum\ndebitis cum dolorem voluptate qui fuga\nnecessitatibus quod temporibus non voluptates\naut saepe molestiae" - }, - { - "postId": 64, - "id": 317, - "name": "iusto pariatur ea", - "email": "Shyanne@rick.info", - "body": "quam iste aut molestiae nesciunt modi\natque quo laudantium vel tempora quam tenetur neque aut\net ipsum eum nostrum enim laboriosam officia eligendi\nlaboriosam libero ullam sit nulla voluptate in" - }, - { - "postId": 64, - "id": 318, - "name": "vitae porro aut ex est cumque", - "email": "Freeman.Dare@ada.name", - "body": "distinctio placeat nisi repellat animi\nsed praesentium voluptatem\nplaceat eos blanditiis deleniti natus eveniet dolorum quia tempore\npariatur illum dolor aspernatur ratione tenetur autem ipsum fugit" - }, - { - "postId": 64, - "id": 319, - "name": "et eos praesentium porro voluptatibus quas quidem explicabo est", - "email": "Donnell@orland.org", - "body": "occaecati quia ipsa id fugit sunt velit iure adipisci\nullam inventore quidem dolorem adipisci optio quia et\nquis explicabo omnis ipsa quo ut voluptatem aliquam inventore\nminima aut tempore excepturi similique" - }, - { - "postId": 64, - "id": 320, - "name": "fugiat eos commodi consequatur vel qui quasi", - "email": "Robin@gaylord.biz", - "body": "nihil consequatur dolorem voluptatem non molestiae\nodit eum animi\nipsum omnis ut quasi\nvoluptas sed et et qui est aut" - }, - { - "postId": 65, - "id": 321, - "name": "rem ducimus ipsam ut est vero distinctio et", - "email": "Danyka_Stark@jedidiah.name", - "body": "ea necessitatibus eum nesciunt corporis\nminus in quisquam iste recusandae\nqui nobis deleniti asperiores non laboriosam sunt molestiae dolore\ndistinctio qui officiis tempora dolorem ea" - }, - { - "postId": 65, - "id": 322, - "name": "ipsam et commodi", - "email": "Margarita@casper.io", - "body": "id molestiae doloribus\nomnis atque eius sunt aperiam\ntenetur quia natus nihil sunt veritatis recusandae quia\ncorporis quam omnis veniam voluptas amet quidem illo deleniti" - }, - { - "postId": 65, - "id": 323, - "name": "et aut non illo cumque pariatur laboriosam", - "email": "Carlo@cortney.net", - "body": "explicabo dicta quas cum quis rerum dignissimos et\nmagnam sit mollitia est dolor voluptas sed\nipsum et tenetur recusandae\nquod facilis nulla amet deserunt" - }, - { - "postId": 65, - "id": 324, - "name": "ut ut architecto vero est ipsam", - "email": "Mina@nikita.tv", - "body": "ipsam eum ea distinctio\nducimus saepe eos quaerat molestiae\ncorporis aut officia qui ut perferendis\nitaque possimus incidunt aut quis" - }, - { - "postId": 65, - "id": 325, - "name": "odit sit numquam rerum porro dolorem", - "email": "Violette@naomi.tv", - "body": "qui vero recusandae\nporro esse sint doloribus impedit voluptatem commodi\nasperiores laudantium ut dolores\npraesentium distinctio magnam voluptatum aut" - }, - { - "postId": 66, - "id": 326, - "name": "voluptatem laborum incidunt accusamus", - "email": "Lauren.Hodkiewicz@jarret.info", - "body": "perspiciatis vero nulla aut consequatur fuga earum aut\nnemo suscipit totam vitae qui at omnis aut\nincidunt optio dolorem voluptatem vel\nassumenda vero id explicabo deleniti sit corrupti sit" - }, - { - "postId": 66, - "id": 327, - "name": "quisquam necessitatibus commodi iure eum", - "email": "Ernestina@piper.biz", - "body": "consequatur ut aut placeat harum\nquia perspiciatis unde doloribus quae non\nut modi ad unde ducimus omnis nobis voluptatem atque\nmagnam reiciendis dolorem et qui explicabo" - }, - { - "postId": 66, - "id": 328, - "name": "temporibus ut vero quas", - "email": "Hettie_Morar@wiley.info", - "body": "molestiae minima aut rerum nesciunt\nvitae iusto consequatur architecto assumenda dolorum\nnon doloremque tempora possimus qui mollitia omnis\nvitae odit sed" - }, - { - "postId": 66, - "id": 329, - "name": "quasi beatae sapiente voluptates quo temporibus", - "email": "Corbin.Hilll@modesto.biz", - "body": "nulla corrupti delectus est cupiditate explicabo facere\nsapiente quo id quis illo culpa\nut aut sit error magni atque asperiores soluta\naut cumque voluptatem occaecati omnis aliquid" - }, - { - "postId": 66, - "id": 330, - "name": "illo ab quae deleniti", - "email": "Kenyatta@renee.io", - "body": "dolores tenetur rerum et aliquam\nculpa officiis ea rem neque modi quaerat deserunt\nmolestias minus nesciunt iusto impedit enim laborum perferendis\nvelit minima itaque voluptatem fugiat" - }, - { - "postId": 67, - "id": 331, - "name": "nemo cum est officia maiores sint sunt a", - "email": "Don@cameron.co.uk", - "body": "maxime incidunt velit quam vel fugit nostrum veritatis\net ipsam nisi voluptatem voluptas cumque tempora velit et\net quisquam error\nmaiores fugit qui dolor sit doloribus" - }, - { - "postId": 67, - "id": 332, - "name": "dicta vero voluptas hic dolorem", - "email": "Jovan@aaliyah.tv", - "body": "voluptas iste deleniti\nest itaque vel ea incidunt quia voluptates sapiente repellat\naut consectetur vel neque tempora esse similique sed\na qui nobis voluptate hic eligendi doloribus molestiae et" - }, - { - "postId": 67, - "id": 333, - "name": "soluta dicta pariatur reiciendis", - "email": "Jeanie.McGlynn@enoch.ca", - "body": "et dolor error doloremque\nodio quo sunt quod\nest ipsam assumenda in veniam illum rerum deleniti expedita\nvoluptate hic nostrum sed dolor et qui" - }, - { - "postId": 67, - "id": 334, - "name": "et adipisci laboriosam est modi", - "email": "Garett_Gusikowski@abigale.me", - "body": "et voluptatibus est et aperiam quaerat voluptate eius quo\nnihil voluptas doloribus et ea tempore\nlabore non dolorem\noptio consequatur est id quia magni voluptas enim" - }, - { - "postId": 67, - "id": 335, - "name": "voluptatem accusantium beatae veniam voluptatem quo culpa deleniti", - "email": "Doug@alana.co.uk", - "body": "hic et et aspernatur voluptates voluptas ut ut id\nexcepturi eligendi aspernatur nulla dicta ab\nsuscipit quis distinctio nihil\ntemporibus unde quasi expedita et inventore consequatur rerum ab" - }, - { - "postId": 68, - "id": 336, - "name": "eveniet eligendi nisi sunt a error blanditiis et ea", - "email": "Yoshiko@viviane.name", - "body": "similique autem voluptatem ab et et\nodio animi repellendus libero voluptas voluptas quia\nlibero facere saepe nobis\nconsequatur et qui non hic ea maxime nihil" - }, - { - "postId": 68, - "id": 337, - "name": "beatae esse tenetur aut est", - "email": "Micaela_Bins@mertie.us", - "body": "est ut aut ut omnis distinctio\nillum quisquam pariatur qui aspernatur vitae\ndolor explicabo architecto veritatis ipsa et aut est molestiae\nducimus et sapiente error sed omnis" - }, - { - "postId": 68, - "id": 338, - "name": "qui sit quo est ipsam minima neque nobis", - "email": "Loy@gillian.me", - "body": "maiores totam quo atque\nexplicabo perferendis iste facilis odio ab eius consequatur\nsit praesentium ea vitae optio minus\nvoluptate necessitatibus omnis itaque omnis qui" - }, - { - "postId": 68, - "id": 339, - "name": "accusantium et sit nihil quibusdam voluptatum provident est qui", - "email": "Tyrel@hunter.net", - "body": "dicta dolorem veniam ipsa harum minus sequi\nomnis quia voluptatem autem\nest optio doloribus repellendus id commodi quas exercitationem eum\net eum dignissimos accusamus est eaque doloremque" - }, - { - "postId": 68, - "id": 340, - "name": "rerum et quae tenetur soluta voluptatem tempore laborum enim", - "email": "Otilia.Schuppe@randal.com", - "body": "est aut consequatur error illo ut\nenim nihil fuga\nsuscipit inventore officiis iure earum pariatur temporibus in\naperiam qui quod vel necessitatibus velit eos exercitationem culpa" - }, - { - "postId": 69, - "id": 341, - "name": "sunt ut voluptatem cupiditate maxime dolores eligendi", - "email": "April@larissa.co.uk", - "body": "iure ea ea neque est\nesse ab sed hic et ullam sed sequi a\nnon hic tenetur sunt enim ea\nlaudantium ea natus" - }, - { - "postId": 69, - "id": 342, - "name": "corporis at consequuntur consequatur", - "email": "Glenna_Waters@retha.me", - "body": "quis beatae qui\nsequi dicta quas et dolor\nnon enim aspernatur excepturi aut rerum asperiores\naliquid animi nulla ea tempore esse" - }, - { - "postId": 69, - "id": 343, - "name": "repellat sed consequatur suscipit aliquam", - "email": "Cordelia.Oberbrunner@peyton.com", - "body": "ea alias eos et corrupti\nvoluptatem ab incidunt\nvoluptatibus voluptas ea nesciunt\ntotam corporis dolor recusandae voluptas harum" - }, - { - "postId": 69, - "id": 344, - "name": "blanditiis rerum voluptatem quaerat modi saepe ratione assumenda qui", - "email": "Zander@santino.net", - "body": "iusto nihil quae rerum laborum recusandae voluptatem et necessitatibus\nut deserunt cumque qui qui\nnon et et eos adipisci cupiditate dolor sed voluptates\nmaiores commodi eveniet consequuntur" - }, - { - "postId": 69, - "id": 345, - "name": "ut deleniti autem ullam quod provident ducimus enim explicabo", - "email": "Camila_Runolfsdottir@tressa.tv", - "body": "omnis et fugit eos sint saepe ipsam unde est\ndolores sit sit assumenda laboriosam\ndolor deleniti voluptatem id nesciunt et\nplaceat dolorem cumque laboriosam sunt non" - }, - { - "postId": 70, - "id": 346, - "name": "beatae in fuga assumenda dolorem accusantium blanditiis mollitia", - "email": "Kirstin@tina.info", - "body": "quas non magnam\nquia veritatis assumenda reiciendis\nsimilique dolores est ab\npraesentium fuga ut" - }, - { - "postId": 70, - "id": 347, - "name": "tenetur id delectus recusandae voluptates quo aut", - "email": "Anthony.Koepp@savannah.tv", - "body": "consectetur illo corporis sit labore optio quod\nqui occaecati aut sequi quia\nofficiis quia aut odio quo ad\nrerum tenetur aut quasi veniam" - }, - { - "postId": 70, - "id": 348, - "name": "molestias natus autem quae sint qui", - "email": "Bradley.Lang@marilyne.tv", - "body": "perferendis dignissimos soluta ut provident sit et\ndelectus ratione ad sapiente qui excepturi error qui quo\nquo illo commodi\nrerum maxime voluptas voluptatem" - }, - { - "postId": 70, - "id": 349, - "name": "odio maiores a porro dolorum ut pariatur inventore", - "email": "Loren@aric.biz", - "body": "dicta impedit non\net laborum laudantium qui eaque et beatae suscipit\nsequi magnam rem dolorem non quia vel adipisci\ncorrupti officiis laudantium impedit" - }, - { - "postId": 70, - "id": 350, - "name": "eius quia pariatur", - "email": "Arjun@natalie.ca", - "body": "eaque rerum tempore distinctio\nconsequatur fugiat veniam et incidunt ut ut et\nconsequatur blanditiis magnam\ndoloremque voluptate ut architecto facere in dolorem et aut" - }, - { - "postId": 71, - "id": 351, - "name": "quia ex perspiciatis sunt voluptatem quidem", - "email": "Solon.Goldner@judah.org", - "body": "quo nisi impedit velit repellendus esse itaque ut saepe\nvoluptatibus occaecati ab eaque dolores\nmaxime alias velit ducimus placeat sit laudantium quia\ncorrupti doloremque ut" - }, - { - "postId": 71, - "id": 352, - "name": "sit ipsam voluptatem velit", - "email": "Nina@osbaldo.name", - "body": "dolorem eius voluptatem vitae aliquid unde labore est\nmolestiae labore dolorem beatae voluptatem soluta eum eos dolore\net ea quasi aut doloribus sint\nvel suscipit tempora delectus soluta" - }, - { - "postId": 71, - "id": 353, - "name": "consequatur reprehenderit similique vitae dolor debitis", - "email": "Madaline@marlin.org", - "body": "nemo aut laborum expedita nisi sed illum\nab asperiores provident\na sunt recusandae ut rerum itaque est voluptatibus nihil\nesse ipsum et repellendus nobis rerum voluptas et" - }, - { - "postId": 71, - "id": 354, - "name": "eligendi tempora eum deserunt", - "email": "Mike.Kozey@gladyce.us", - "body": "delectus est consequatur\nat excepturi asperiores dolor nesciunt ad\nid non aut ad ut\nnon et voluptatem" - }, - { - "postId": 71, - "id": 355, - "name": "reiciendis ad ea", - "email": "Orval.Treutel@arnold.me", - "body": "vel cumque labore vitae quisquam magnam sequi ut\nmolestiae dolores vel minus aut\nquas repellat nostrum fugit molestiae veritatis sequi\nvel quidem in molestiae id doloribus sed" - }, - { - "postId": 72, - "id": 356, - "name": "qui vel id qui est", - "email": "Trent@samir.net", - "body": "fugiat dolore voluptas tempore\naspernatur quibusdam rem iste sit fugiat nesciunt consequatur\ndolor sed odit similique minima corporis quae in adipisci\nimpedit dolores et cupiditate accusantium perferendis dignissimos error" - }, - { - "postId": 72, - "id": 357, - "name": "consectetur totam fugit et occaecati minima aliquid hic adipisci", - "email": "Ashleigh@annette.ca", - "body": "et eos est quis quia molestiae est\nquasi est quos omnis\naut et sit consectetur ex molestiae\nest sed accusamus asperiores" - }, - { - "postId": 72, - "id": 358, - "name": "accusantium natus ex et consequuntur neque", - "email": "Douglas@anabel.org", - "body": "unde ad id nemo ipsam dolorem autem quaerat\nperspiciatis voluptas corrupti laborum rerum est architecto\neius quos aut et voluptate voluptatem atque necessitatibus\nvoluptate fugiat aut iusto et atque" - }, - { - "postId": 72, - "id": 359, - "name": "esse quia quidem quisquam consequatur nisi deleniti", - "email": "Lowell@mossie.com", - "body": "et explicabo voluptatem ut est nihil culpa et\nveritatis repellendus ipsum velit qui eligendi maxime voluptatem est\ndicta rerum et et nemo quia\neveniet aspernatur nostrum molestiae mollitia ut dolores rem fugiat" - }, - { - "postId": 72, - "id": 360, - "name": "rerum tempore facilis ut quod sit", - "email": "Jacquelyn@kristian.net", - "body": "sit et aut recusandae\ncorrupti nisi vero eius nulla voluptates\nvoluptatem placeat est commodi impedit odio omnis\nsimilique debitis et in molestiae omnis sed non magni" - }, - { - "postId": 73, - "id": 361, - "name": "voluptates qui et corporis", - "email": "Antwon@domenico.me", - "body": "cum ad porro fuga sequi dolores\nipsa error magni itaque labore accusamus\ncorporis odit consequatur quis debitis\ncum et voluptas facilis incidunt ut itaque dolores error" - }, - { - "postId": 73, - "id": 362, - "name": "quia qui quia qui", - "email": "Kenyon@retha.me", - "body": "excepturi omnis occaecati officiis enim saepe id\nnon quo et dignissimos voluptates ipsum\nmolestias facere dolorem qui iure similique corrupti\nneque ducimus sit alias dolor earum autem doloribus consequatur" - }, - { - "postId": 73, - "id": 363, - "name": "nihil consequatur quibusdam", - "email": "Ben@elouise.net", - "body": "est magni totam est\net enim nam voluptas veritatis est\nsint doloremque incidunt et cum a\net eligendi nobis ratione delectus" - }, - { - "postId": 73, - "id": 364, - "name": "vel architecto assumenda et maiores", - "email": "Madisen.Hauck@barney.co.uk", - "body": "architecto quo enim ad et reprehenderit\nlaboriosam quia commodi officia iusto\ndolorem totam consequuntur cupiditate\nveritatis voluptates aspernatur earum saepe et sed consequatur" - }, - { - "postId": 73, - "id": 365, - "name": "aliquam officiis omnis", - "email": "Dock.Parker@roy.biz", - "body": "modi sed aut quidem quisquam optio est\naut facilis sit quia quis facere quod\nfugiat recusandae ex et quisquam ipsum sed sit\nexercitationem quia recusandae dolorem quasi iusto ipsa qui et" - }, - { - "postId": 74, - "id": 366, - "name": "aperiam ut deserunt minus quo dicta nisi", - "email": "Pablo.Ritchie@tyrique.co.uk", - "body": "explicabo perspiciatis quae sit qui nulla incidunt facilis\nrepudiandae perspiciatis voluptate expedita sunt consectetur quasi\nid occaecati nesciunt dolorem aliquid perspiciatis repellat inventore esse\nut possimus exercitationem facere modi" - }, - { - "postId": 74, - "id": 367, - "name": "praesentium eos quam eius optio eveniet", - "email": "Sebastian_Gaylord@freda.org", - "body": "nostrum modi et et dolores maxime facere\nalias doloribus eaque expedita et similique voluptatum magnam est\nomnis eos voluptatem\net unde fugit voluptatem asperiores" - }, - { - "postId": 74, - "id": 368, - "name": "fugiat aliquid sint", - "email": "Lazaro@nadia.ca", - "body": "est dolor eveniet\nest minus eveniet recusandae\niure quo aut eos ut sed ipsa\nharum earum aut nesciunt non dolores" - }, - { - "postId": 74, - "id": 369, - "name": "qui incidunt vel iusto eligendi amet quia qui", - "email": "Jessy.Boyle@vernice.biz", - "body": "qui fugit accusamus\net quo minus cumque hic adipisci\nodio blanditiis omnis et est\narchitecto et facilis inventore quasi provident quaerat ex rem" - }, - { - "postId": 74, - "id": 370, - "name": "libero vero voluptatum sed facilis quos aut reprehenderit ad", - "email": "Mitchel@hal.co.uk", - "body": "beatae hic est et deserunt eius\ncorrupti quam ut commodi sit modi est corporis animi\nharum ut est\naperiam non fugit excepturi quo tenetur totam" - }, - { - "postId": 75, - "id": 371, - "name": "ut quia sequi sed eius voluptas", - "email": "Lindsay@kiley.name", - "body": "est dicta totam architecto et minus id aut non\nut et fugit eaque culpa modi repellendus\naliquid qui veritatis doloribus aut consequatur voluptas sequi accusantium\nvoluptas occaecati saepe reprehenderit ut" - }, - { - "postId": 75, - "id": 372, - "name": "qui cumque eos consequatur fuga ut", - "email": "Erika.Murazik@jorge.me", - "body": "aut illum est asperiores\nrerum laboriosam quis sit dolores magni minima fuga atque\nomnis at et quibusdam earum rem\nearum distinctio autem et enim dolore eos" - }, - { - "postId": 75, - "id": 373, - "name": "nemo voluptatum quo qui atque", - "email": "Olin@edmund.ca", - "body": "iure aliquid qui sit\nexcepturi dolorem rerum possimus suscipit atque nisi\nlabore ut aut nihil voluptatum ut aliquid praesentium\nassumenda tempore dolor velit ratione et corrupti" - }, - { - "postId": 75, - "id": 374, - "name": "quam exercitationem alias totam", - "email": "Lacey@novella.biz", - "body": "eligendi et consequuntur dolor nihil quaerat doloremque ut\ndignissimos sunt veniam non ratione esse\ndebitis omnis similique maxime dolores tempora laborum rerum adipisci\nreiciendis explicabo error quidem quo necessitatibus voluptatibus vitae ipsum" - }, - { - "postId": 75, - "id": 375, - "name": "similique doloribus odit quas magnam omnis dolorem dolore et", - "email": "Sister@miller.net", - "body": "non ea sed reprehenderit reiciendis eaque et neque adipisci\nipsa architecto deserunt ratione nesciunt tempore similique occaecati non\nhic vitae sit neque\nrerum quod dolorem ratione esse aperiam necessitatibus" - }, - { - "postId": 76, - "id": 376, - "name": "dolorem qui architecto provident", - "email": "Raphaelle@miller.com", - "body": "sint qui aut aspernatur necessitatibus\nlaboriosam autem occaecati nostrum non\nofficiis consequuntur odit\net itaque quam placeat aut molestiae saepe veniam provident" - }, - { - "postId": 76, - "id": 377, - "name": "nemo hic sapiente placeat quidem omnis", - "email": "Jaren.Schiller@augusta.org", - "body": "sint fugit et\nid et saepe non molestiae sit earum doloremque\ndolorem nemo earum dignissimos ipsa soluta deleniti quos\nquis numquam ducimus sed corporis dolores sed quisquam suscipit" - }, - { - "postId": 76, - "id": 378, - "name": "vitae aut perspiciatis quia enim voluptas", - "email": "Nikko_Reynolds@harry.me", - "body": "est molestiae non fugiat voluptatem quo porro\naut praesentium ipsam aspernatur perferendis fuga\nofficia sit ut\naspernatur rerum est" - }, - { - "postId": 76, - "id": 379, - "name": "est qui quos exercitationem", - "email": "Afton.Medhurst@mina.info", - "body": "laboriosam quia animi ut\nquasi aut enim sequi numquam similique fugiat voluptatum non\nsed velit quod nisi id quidem\nmagni in eveniet hic" - }, - { - "postId": 76, - "id": 380, - "name": "similique fugiat tenetur ea incidunt numquam", - "email": "Wilson.Nikolaus@fredrick.org", - "body": "voluptatum quis ipsa voluptatem saepe est\nillum error repellat eaque dolor quae qui\neum rerum sunt quam illo\nvoluptates fuga possimus nemo nihil distinctio" - }, - { - "postId": 77, - "id": 381, - "name": "sint porro optio voluptatem", - "email": "Tomasa@lee.us", - "body": "consequatur possimus sit itaque distinctio fugit aut quod\nexplicabo exercitationem voluptas labore rerum\nporro ut in voluptas maiores tempora accusantium\nvoluptatum et sapiente sit quas quis et veniam" - }, - { - "postId": 77, - "id": 382, - "name": "eius itaque ut ipsa quia quis labore", - "email": "Ally_Kassulke@rashad.ca", - "body": "eaque eius delectus molestias suscipit nulla quisquam\ntotam vel quos et autem sed\neligendi et pariatur earum molestias magnam autem\nplaceat culpa est et qui commodi illo et" - }, - { - "postId": 77, - "id": 383, - "name": "provident voluptas perferendis quibusdam libero", - "email": "Reagan_Ziemann@ross.io", - "body": "qui quaerat id repellendus aut qui\nmaiores quidem consequatur dignissimos deleniti deserunt eveniet libero a\nrepellat ducimus quia aut dignissimos numquam molestiae\nconsequatur sit impedit nostrum et sunt iure" - }, - { - "postId": 77, - "id": 384, - "name": "et et voluptas et eligendi distinctio accusantium temporibus enim", - "email": "Angelita@sally.org", - "body": "blanditiis dolor sint nulla cum quidem aliquid voluptatem\nperferendis dolor consequatur voluptas et ut quisquam tempora tenetur\nmaxime minus animi qui id\neum accusantium et optio et blanditiis maxime" - }, - { - "postId": 77, - "id": 385, - "name": "qui voluptates molestias necessitatibus eos odio quo minima", - "email": "Lonzo@lorena.org", - "body": "sit fugiat est autem quia ipsam error ab\nvoluptatem sed ab labore molestiae qui debitis exercitationem\nnon et sunt officia illo possimus iste tenetur est\ndolores voluptas ad aspernatur nihil" - }, - { - "postId": 78, - "id": 386, - "name": "temporibus minus debitis deleniti repellat unde eveniet", - "email": "Alexandre@derrick.co.uk", - "body": "et dicta dolores sit\nrepudiandae id harum temporibus\nvoluptas quia blanditiis numquam a enim quae\nquisquam assumenda nam doloribus vel temporibus distinctio eveniet dolores" - }, - { - "postId": 78, - "id": 387, - "name": "magnam nihil delectus dolor natus ab ea et", - "email": "Judd@lucinda.ca", - "body": "qui recusandae veniam sed voluptatem ullam facilis consequatur\nnumquam ut quod aut et\nnon alias ex quam aut quasi ipsum praesentium\nut aspernatur sit" - }, - { - "postId": 78, - "id": 388, - "name": "laudantium quibusdam blanditiis pariatur non vero deleniti a perferendis", - "email": "Eleanora@karson.net", - "body": "facilis et totam\nvoluptatibus est optio cum\nfacilis qui aut blanditiis rerum voluptatem accusamus\net omnis quasi sint" - }, - { - "postId": 78, - "id": 389, - "name": "excepturi nam cum molestiae et totam voluptatem nisi", - "email": "Enrico_Feil@liana.biz", - "body": "dolore nihil perferendis\ndolor hic repudiandae iste\ndoloribus labore quaerat et molestiae dolores sit excepturi sint\net eum et aut" - }, - { - "postId": 78, - "id": 390, - "name": "temporibus aut et", - "email": "Beverly@perry.org", - "body": "dolor ratione ab repellendus aut quia reiciendis sed\nest alias ex\nodio voluptatem velit odit tempora nihil optio aperiam blanditiis\nlabore porro id velit dolor veritatis" - }, - { - "postId": 79, - "id": 391, - "name": "sed ratione nesciunt odit expedita", - "email": "Corene_Mante@rory.com", - "body": "aut repellat tenetur delectus eaque est nihil consequatur quae\ndeleniti assumenda voluptates sit sit cupiditate maiores\nautem suscipit sint tenetur dolor tempore\ndolorem dolorum alias adipisci" - }, - { - "postId": 79, - "id": 392, - "name": "rerum officiis qui quaerat omnis dolorem iure est repudiandae", - "email": "Emily_Flatley@ephraim.name", - "body": "aut aut ea ut repudiandae ea assumenda laboriosam\nsunt qui laboriosam dicta omnis sit corporis\nvoluptas eos amet quam quisquam officiis facilis laborum\nvoluptatibus accusantium ab aliquid sed id doloremque" - }, - { - "postId": 79, - "id": 393, - "name": "illo quis nostrum accusantium architecto et aliquam ratione", - "email": "Donna@frederik.com", - "body": "et quia explicabo\nut hic commodi quas provident aliquam nihil\nvitae in voluptatem commodi\nvero velit optio omnis accusamus corrupti voluptatem" - }, - { - "postId": 79, - "id": 394, - "name": "reprehenderit eos voluptatem ut", - "email": "Kyleigh@ruben.org", - "body": "voluptatem quisquam pariatur voluptatum qui quaerat\net minus ea aliquam ullam dolorem consequatur\nratione at ad nemo aperiam excepturi deleniti\nqui numquam quis hic nostrum tempora quidem" - }, - { - "postId": 79, - "id": 395, - "name": "excepturi esse laborum ut qui culpa", - "email": "Noemy.Hammes@lisette.net", - "body": "esse vel reiciendis nobis inventore vero est\nfugit inventore ea quo consequatur aut\nautem deserunt ratione et repellendus nihil quam\nquidem iure est nihil mollitia" - }, - { - "postId": 80, - "id": 396, - "name": "qui eos vitae possimus reprehenderit voluptatem voluptatem repellendus", - "email": "Margarett_Jenkins@harley.us", - "body": "perferendis veritatis saepe voluptatem\neum voluptas quis\nsed occaecati nostrum\nfugit animi omnis ratione molestias" - }, - { - "postId": 80, - "id": 397, - "name": "quasi exercitationem molestias dolore non non sed est", - "email": "Dexter.Pacocha@lauren.biz", - "body": "ut nisi sunt perspiciatis qui doloribus quas\nvelit molestiae atque corrupti corporis voluptatem\nvel ratione aperiam tempore est eos\nquia a voluptas" - }, - { - "postId": 80, - "id": 398, - "name": "labore consequuntur vel qui", - "email": "Gennaro@jaunita.co.uk", - "body": "libero atque accusamus blanditiis minima eveniet corporis est aliquid\ndolores asperiores neque quibusdam quaerat error esse non\nqui et adipisci\nmagni illo hic qui qui dignissimos earum" - }, - { - "postId": 80, - "id": 399, - "name": "sunt ut eos", - "email": "Jaycee@aimee.us", - "body": "corrupti ut et eveniet culpa\nveritatis eos sequi fugiat commodi consequuntur\nipsa totam voluptatem perferendis ducimus aut exercitationem magni\neos mollitia quia" - }, - { - "postId": 80, - "id": 400, - "name": "quia aut consequatur sunt iste aliquam impedit sit", - "email": "Brennon@carmela.tv", - "body": "natus iure velit impedit sed officiis sint\nmolestiae non beatae\nillo consequatur minima\nsed ratione est tenetur" - }, - { - "postId": 81, - "id": 401, - "name": "cum voluptate sint voluptas veritatis", - "email": "Vella.Mayer@colten.net", - "body": "sit delectus recusandae qui\net cupiditate sed ipsum culpa et fugiat ab\nillo dignissimos quo est repellat dolorum neque\nvoluptates sed sapiente ab aut rerum enim sint voluptatum" - }, - { - "postId": 81, - "id": 402, - "name": "ut eos mollitia eum eius", - "email": "Caleb_Dach@kathleen.us", - "body": "et nisi fugit totam\nmaiores voluptatibus quis ipsa sunt debitis assumenda\nullam non quasi numquam ut dolores modi recusandae\nut molestias magni est voluptas quibusdam corporis eius" - }, - { - "postId": 81, - "id": 403, - "name": "architecto voluptatum eos blanditiis aliquam debitis beatae nesciunt dolorum", - "email": "Patience_Bahringer@dameon.biz", - "body": "et a et perspiciatis\nautem expedita maiores dignissimos labore minus molestiae enim\net ipsam ea et\nperspiciatis veritatis debitis maxime" - }, - { - "postId": 81, - "id": 404, - "name": "officia qui ut explicabo eos fugit", - "email": "Destinee.Simonis@jose.tv", - "body": "modi est et eveniet facilis explicabo\nvoluptatem saepe quo et sint quas quia corporis\npariatur voluptatibus est iste fugiat delectus animi rerum\ndoloribus est enim" - }, - { - "postId": 81, - "id": 405, - "name": "incidunt commodi voluptatem maiores asperiores blanditiis omnis ratione", - "email": "Keshaun@brown.biz", - "body": "aut aut sit cupiditate maxime praesentium occaecati cumque\nvero sint sit aliquam porro quo consequuntur ut\nnumquam qui maxime voluptas est consequatur ullam\ntenetur commodi qui consectetur distinctio eligendi atque" - }, - { - "postId": 82, - "id": 406, - "name": "sint eaque rerum voluptas fugiat quia qui", - "email": "Merle.Schultz@marcel.org", - "body": "dicta in quam tenetur\nsed molestiae a sit est aut quia autem aut\nnam voluptatem reiciendis corporis voluptatem\nsapiente est id quia explicabo enim tempora asperiores" - }, - { - "postId": 82, - "id": 407, - "name": "eius tempora sint reprehenderit", - "email": "Malvina_Fay@louie.name", - "body": "totam ad quia non vero dolor laudantium sed temporibus\nquia aperiam corrupti sint accusantium eligendi\naliquam rerum voluptatem delectus numquam nihil\nsoluta qui sequi nisi voluptatum eaque voluptas animi ipsam" - }, - { - "postId": 82, - "id": 408, - "name": "non excepturi enim est sapiente numquam repudiandae illo", - "email": "Domenick_Douglas@gabe.us", - "body": "suscipit quidem fugiat consequatur\nquo sequi nesciunt\naliquam ratione possimus\nvoluptatem sit quia repellendus libero excepturi ut temporibus" - }, - { - "postId": 82, - "id": 409, - "name": "dicta dolor voluptate vel praesentium", - "email": "Isaac@allene.net", - "body": "provident illo quis dolor distinctio laborum eius enim\nsuscipit quia error enim eos consequuntur\nest incidunt adipisci beatae tenetur excepturi in labore commodi\nfugiat omnis in et at nam accusamus et" - }, - { - "postId": 82, - "id": 410, - "name": "et dolore hic a cupiditate beatae natus iusto soluta", - "email": "Marianna.Pacocha@george.net", - "body": "in consequatur corporis qui a et magni eum illum\ncorrupti veniam debitis ab iure harum\nenim ut assumenda cum adipisci veritatis et veniam\nrem eius expedita quos corrupti incidunt" - }, - { - "postId": 83, - "id": 411, - "name": "hic rem eligendi tenetur ipsum dolore maxime eum", - "email": "Sister_Barton@lela.com", - "body": "nam voluptatem ex aut voluptatem mollitia sit sapiente\nqui hic ut\nqui natus in iste et magnam dolores et fugit\nea sint ut minima quas eum nobis at reprehenderit" - }, - { - "postId": 83, - "id": 412, - "name": "quaerat et quia accusamus provident earum cumque", - "email": "Autumn.Lebsack@kasandra.ca", - "body": "veniam non culpa aut voluptas rem eum officiis\nmollitia placeat eos cum\nconsequatur eos commodi dolorem\nanimi maiores qui" - }, - { - "postId": 83, - "id": 413, - "name": "atque porro quo voluptas", - "email": "Irma.OKon@arden.me", - "body": "consequatur harum est omnis\nqui recusandae qui voluptatem et distinctio sint eaque\ndolores quo dolorem asperiores\naperiam non quis asperiores aut praesentium" - }, - { - "postId": 83, - "id": 414, - "name": "ut qui voluptatem hic maxime", - "email": "Alaina_Hammes@carter.info", - "body": "molestias debitis magni illo sint officiis ut quia\nsed tenetur dolorem soluta\nvoluptatem fugiat voluptas molestiae magnam fuga\nsimilique enim illum voluptas aspernatur officia" - }, - { - "postId": 83, - "id": 415, - "name": "rerum consequatur ut et voluptate harum amet accusantium est", - "email": "Alia@addison.org", - "body": "iure vitae accusamus tenetur autem ipsa deleniti\nsunt laudantium ut beatae repellendus non eos\nut consequuntur repudiandae ducimus enim\nreiciendis rem explicabo magni dolore" - }, - { - "postId": 84, - "id": 416, - "name": "neque nemo consequatur ea fugit aut esse suscipit dolore", - "email": "Aurelie_McKenzie@providenci.biz", - "body": "enim velit consequatur excepturi corporis voluptatem nostrum\nnesciunt alias perspiciatis corporis\nneque at eius porro sapiente ratione maiores natus\nfacere molestiae vel explicabo voluptas unde" - }, - { - "postId": 84, - "id": 417, - "name": "quia reiciendis nobis minima quia et saepe", - "email": "May_Steuber@virgil.net", - "body": "et vitae consectetur ut voluptatem\net et eveniet sit\nincidunt tenetur voluptatem\nprovident occaecati exercitationem neque placeat" - }, - { - "postId": 84, - "id": 418, - "name": "nesciunt voluptates amet sint et delectus et dolore culpa", - "email": "Tessie@emilie.co.uk", - "body": "animi est eveniet officiis qui\naperiam dolore occaecati enim aut reiciendis\nanimi ad sint labore blanditiis adipisci voluptatibus eius error\nomnis rerum facere architecto occaecati rerum" - }, - { - "postId": 84, - "id": 419, - "name": "omnis voluptate dolorem similique totam", - "email": "Priscilla@colten.org", - "body": "cum neque recusandae occaecati aliquam reprehenderit ullam saepe veniam\nquasi ea provident tenetur architecto ad\ncupiditate molestiae mollitia molestias debitis eveniet doloremque voluptatem aut\ndolore consequatur nihil facere et" - }, - { - "postId": 84, - "id": 420, - "name": "aut recusandae a sit voluptas explicabo nam et", - "email": "Aylin@abigale.me", - "body": "voluptas cum eum minima rem\ndolorem et nemo repellendus voluptatem sit\nrepudiandae nulla qui recusandae nobis\nblanditiis perspiciatis dolor ipsam reprehenderit odio" - }, - { - "postId": 85, - "id": 421, - "name": "non eligendi ipsam provident", - "email": "Holden@kenny.io", - "body": "voluptate libero corrupti facere totam eaque consequatur nemo\nenim aliquid exercitationem nulla dignissimos illo\nest amet non iure\namet sed dolore non ipsam magni" - }, - { - "postId": 85, - "id": 422, - "name": "sit molestiae corporis", - "email": "Guillermo_Dare@dorothea.tv", - "body": "ducimus ut ut fugiat nesciunt labore\ndeleniti non et aut voluptatum quidem consectetur\nincidunt voluptas accusantium\nquo fuga eaque quisquam et et sapiente aut" - }, - { - "postId": 85, - "id": 423, - "name": "assumenda iure a", - "email": "Oscar@pearline.com", - "body": "rerum laborum voluptas ipsa enim praesentium\nquisquam aliquid perspiciatis eveniet id est est facilis\natque aut facere\nprovident reiciendis libero atque est" - }, - { - "postId": 85, - "id": 424, - "name": "molestiae dolores itaque dicta earum eligendi dolores", - "email": "Jonathon_Feest@maxime.io", - "body": "ducimus hic ea velit\ndolorum soluta voluptas similique rerum\ndolorum sint maxime et vel\nvoluptatum nesciunt et id consequatur earum sed" - }, - { - "postId": 85, - "id": 425, - "name": "cumque expedita consequatur qui", - "email": "Micah_Wolf@lennie.co.uk", - "body": "labore necessitatibus et eum quas id ut\ndoloribus aspernatur nostrum sapiente quo aut quia\neos rerum voluptatem\nnumquam minima soluta velit recusandae ut" - }, - { - "postId": 86, - "id": 426, - "name": "deleniti tempora non quia et aut", - "email": "Shany@daisha.biz", - "body": "reiciendis consequatur sunt atque quisquam ut sed iure\nconsequatur laboriosam dicta odio\nquas cumque iure blanditiis ad sed ullam dignissimos\nsunt et exercitationem saepe" - }, - { - "postId": 86, - "id": 427, - "name": "delectus illum minus odit", - "email": "Drew_Lemke@alexis.net", - "body": "in laborum et distinctio nobis maxime\nmaxime id commodi eaque enim amet qui autem\ndebitis et porro eum dicta sapiente iusto nulla sunt\nvoluptate excepturi sint dolorem voluptatem quae explicabo id" - }, - { - "postId": 86, - "id": 428, - "name": "voluptas dolores dolor nisi voluptatem ratione rerum", - "email": "Karina.Donnelly@liam.com", - "body": "excepturi quos omnis aliquam voluptatem iste\nsit unde ab quam ipsa delectus culpa rerum\ncum delectus impedit ut qui modi\nasperiores qui sapiente quia facilis in iure" - }, - { - "postId": 86, - "id": 429, - "name": "sed omnis dolore aperiam", - "email": "Ahmed_Runolfsson@claire.name", - "body": "ab voluptatem nobis unde\ndoloribus aut fugiat\nconsequuntur laboriosam minima inventore sint quis\ndelectus hic et enim sit optio consequuntur" - }, - { - "postId": 86, - "id": 430, - "name": "sint ullam alias et at et", - "email": "Marilou_Halvorson@kane.io", - "body": "debitis ut maiores ut harum sed voluptas\nquae amet eligendi quo quidem odit atque quisquam animi\nut autem est corporis et\nsed tempora facere corrupti magnam" - }, - { - "postId": 87, - "id": 431, - "name": "velit incidunt ut accusantium odit maiores quaerat", - "email": "Bernie.Schoen@seamus.co.uk", - "body": "voluptas minus fugiat vel\nest quos soluta et veniam quia incidunt unde ut\nlaborum odio in eligendi distinctio odit repellat\nnesciunt consequatur blanditiis cupiditate consequatur at et" - }, - { - "postId": 87, - "id": 432, - "name": "quod quia nihil nisi perferendis laborum blanditiis tempora eos", - "email": "Joesph@darryl.net", - "body": "quam et et harum\nplaceat minus neque quae magni inventore saepe deleniti quisquam\nsuscipit dolorum error aliquid dolores\ndignissimos dolorem autem natus iste molestiae est id impedit" - }, - { - "postId": 87, - "id": 433, - "name": "qui ea voluptatem reiciendis enim enim nisi aut", - "email": "Timmothy.Corwin@augustus.co.uk", - "body": "voluptatem minus asperiores quasi\nperspiciatis et aut blanditiis illo deserunt molestiae ab aperiam\nex minima sed omnis at\net repellat aut incidunt" - }, - { - "postId": 87, - "id": 434, - "name": "doloremque eligendi quas voluptatem non quos ex", - "email": "Julien_OHara@vance.io", - "body": "ex eum at culpa quam aliquam\ncupiditate et id dolorem sint quasi et quos et\nomnis et qui minus est quisquam non qui rerum\nquas molestiae tempore veniam" - }, - { - "postId": 87, - "id": 435, - "name": "id voluptatum nulla maiores ipsa eos", - "email": "Susan.Bartell@euna.org", - "body": "reprehenderit molestias sit nemo quas culpa dolorem exercitationem\neos est voluptatem dolores est fugiat dolorem\neos aut quia et amet et beatae harum vitae\nofficia quia animi dicta magnam accusantium" - }, - { - "postId": 88, - "id": 436, - "name": "ea illo ab et maiores eaque non nobis", - "email": "Selena.Quigley@johan.co.uk", - "body": "sit non facilis commodi sapiente officiis aut facere libero\nsed voluptatum eligendi veniam velit explicabo\nsint laborum sunt reprehenderit dolore id nobis accusamus\nfugit voluptatem magni dolor qui dolores ipsa" - }, - { - "postId": 88, - "id": 437, - "name": "magni asperiores in cupiditate", - "email": "Clifton_Boehm@jacynthe.io", - "body": "suscipit ab qui eos et commodi\nquas ad maiores repellat laboriosam voluptatem exercitationem\nquibusdam ullam ratione nulla\nquia iste error dolorem consequatur beatae temporibus fugit" - }, - { - "postId": 88, - "id": 438, - "name": "ullam autem aliquam", - "email": "Lizzie_Bartell@diamond.net", - "body": "voluptas aspernatur eveniet\nquod id numquam dolores quia perspiciatis eum\net delectus quia occaecati adipisci nihil velit accusamus esse\nminus aspernatur repudiandae" - }, - { - "postId": 88, - "id": 439, - "name": "voluptates quasi minus dolorem itaque nemo", - "email": "Yasmeen@golda.ca", - "body": "cupiditate laborum sit reprehenderit ratione est ad\ncorporis rem pariatur enim et omnis dicta\nnobis molestias quo corporis et nihil\nsed et impedit aut quisquam natus expedita voluptate at" - }, - { - "postId": 88, - "id": 440, - "name": "adipisci sapiente libero beatae quas eveniet", - "email": "Adolf.Russel@clark.ca", - "body": "ut nam ut asperiores quis\nexercitationem aspernatur eligendi autem repellendus\nest repudiandae quisquam rerum ad explicabo suscipit deserunt eius\nalias aliquid eos pariatur rerum magnam provident iusto" - }, - { - "postId": 89, - "id": 441, - "name": "nisi qui voluptates recusandae voluptas assumenda et", - "email": "Elian@matilda.me", - "body": "illum qui quis optio\nquasi eius dolores et non numquam et\nqui necessitatibus itaque magnam mollitia earum et\nnisi voluptate eum accusamus ea" - }, - { - "postId": 89, - "id": 442, - "name": "sed molestias sit voluptatibus sit aut alias sunt inventore", - "email": "Salma@francis.net", - "body": "velit ut incidunt accusantium\nsuscipit animi officia iusto\nnemo omnis sunt nobis repellendus corporis\nconsequatur distinctio dolorem" - }, - { - "postId": 89, - "id": 443, - "name": "illum pariatur aliquam esse nisi voluptas quisquam ea", - "email": "Orlando_Dickinson@vern.org", - "body": "reiciendis et distinctio qui totam non aperiam voluptas\nveniam in dolorem pariatur itaque\nvoluptas adipisci velit\nqui voluptates voluptas ut ullam veritatis repudiandae" - }, - { - "postId": 89, - "id": 444, - "name": "incidunt aut qui quis est sit corporis pariatur qui", - "email": "Elda@orval.name", - "body": "eligendi labore aut non modi vel facere qui\naccusamus qui maxime aperiam\ntotam et non ut repudiandae eum corrupti pariatur quia\nnecessitatibus et adipisci ipsa consequuntur enim et nihil vero" - }, - { - "postId": 89, - "id": 445, - "name": "temporibus adipisci eveniet libero ullam", - "email": "Dennis@karley.net", - "body": "est consequuntur cumque\nquo dolorem at ut dolores\nconsequatur quia voluptates reiciendis\nvel rerum id et" - }, - { - "postId": 90, - "id": 446, - "name": "dicta excepturi aut est dolor ab dolores rerum", - "email": "Jedediah@mason.io", - "body": "cum fugit earum vel et nulla et voluptatem\net ipsam aut\net nihil officia nemo eveniet accusamus\nnulla aut impedit veritatis praesentium" - }, - { - "postId": 90, - "id": 447, - "name": "molestiae qui quod quo", - "email": "Maryam@jack.name", - "body": "rerum omnis voluptatem harum aliquid voluptas accusamus\neius dicta animi\nodio non quidem voluptas tenetur\nnostrum deserunt laudantium culpa dolorum" - }, - { - "postId": 90, - "id": 448, - "name": "pariatur consequatur sit commodi aliquam", - "email": "Rick@carlos.tv", - "body": "odio maxime beatae ab labore rerum\nalias ipsa nam est nostrum\net debitis aut\nab molestias assumenda eaque repudiandae" - }, - { - "postId": 90, - "id": 449, - "name": "sunt quia soluta quae sit deleniti dolor ullam veniam", - "email": "Vallie@jerrod.net", - "body": "dolor at accusantium eveniet\nin voluptatem quam et fugiat et quasi dolores\nsunt eligendi voluptatum id voluptas vitae\nquibusdam iure eum perspiciatis" - }, - { - "postId": 90, - "id": 450, - "name": "dolorem corporis facilis et", - "email": "Adolph.Hayes@isobel.biz", - "body": "et provident quo necessitatibus harum excepturi\nsed est ut sed est doloremque labore quod\nquia optio explicabo adipisci magnam doloribus\nveritatis illo aut est inventore" - }, - { - "postId": 91, - "id": 451, - "name": "maiores ut dolores quo sapiente nisi", - "email": "Duane_Dach@demario.us", - "body": "dolor veritatis ipsum accusamus quae voluptates sint voluptatum et\nharum saepe dolorem enim\nexpedita placeat qui quidem aut et et est\nminus odit qui possimus qui saepe" - }, - { - "postId": 91, - "id": 452, - "name": "quia excepturi in harum repellat consequuntur est vel qui", - "email": "General@schuyler.org", - "body": "ratione sequi sed\nearum nam aut sunt\nquam cum qui\nsimilique consequatur et est" - }, - { - "postId": 91, - "id": 453, - "name": "doloremque ut est eaque", - "email": "Stephania_Stanton@demond.biz", - "body": "quidem nisi reprehenderit eligendi fugiat et et\nsapiente adipisci natus nulla similique et est\nesse ea accusantium sunt\ndeleniti molestiae perferendis quam animi similique ut" - }, - { - "postId": 91, - "id": 454, - "name": "magni quos voluptatibus earum et inventore suscipit", - "email": "Reinhold.Schiller@kelly.info", - "body": "consequatur accusamus maiores dolorem impedit repellendus voluptas rerum eum\nquam quia error voluptatem et\ndignissimos fugit qui\net facilis necessitatibus dignissimos consequatur iusto nihil possimus" - }, - { - "postId": 91, - "id": 455, - "name": "assumenda qui et aspernatur", - "email": "Royce@jaiden.co.uk", - "body": "animi qui nostrum rerum velit\nvoluptates sit in laborum dolorum omnis ut omnis\nea optio quia necessitatibus delectus molestias sapiente perferendis\ndolores vel excepturi expedita" - }, - { - "postId": 92, - "id": 456, - "name": "quod voluptatem qui qui sit sed maiores fugit", - "email": "Cassie@diana.org", - "body": "sunt ipsam illum consequuntur\nquasi enim possimus unde qui beatae quo eligendi\nvel quia asperiores est quae voluptate\naperiam et iste perspiciatis" - }, - { - "postId": 92, - "id": 457, - "name": "ipsa animi saepe veritatis voluptatibus ad amet id aut", - "email": "Jena.OKeefe@adonis.net", - "body": "incidunt itaque enim pariatur quibusdam voluptatibus blanditiis sint\nerror laborum voluptas sed officiis molestiae nostrum\ntemporibus culpa aliquam sit\nconsectetur dolores tempore id accusantium dignissimos vel" - }, - { - "postId": 92, - "id": 458, - "name": "fugiat consectetur saepe dicta", - "email": "Magdalen@holly.io", - "body": "eos hic deserunt necessitatibus sed id ut esse nam\nhic eveniet vitae corrupti mollitia doloremque sit ratione\ndeleniti perspiciatis numquam est sapiente quaerat\nest est sit" - }, - { - "postId": 92, - "id": 459, - "name": "nesciunt numquam alias doloremque minus ipsam optio", - "email": "Nyah@otho.com", - "body": "veniam natus aut vero et aliquam doloremque\nalias cupiditate non est\ntempore et non vel error placeat est quisquam ea\nnon dolore aliquid non fuga expedita dicta ut quos" - }, - { - "postId": 92, - "id": 460, - "name": "eum fugit omnis optio", - "email": "Kara_Stokes@connie.co.uk", - "body": "qui qui deserunt expedita at\nprovident sequi veritatis sit qui nam tempora mollitia ratione\ncorporis vitae rerum pariatur unde deleniti ut eos ad\naut non quae nisi saepe" - }, - { - "postId": 93, - "id": 461, - "name": "perferendis nobis praesentium accusantium culpa et et", - "email": "Conner@daron.info", - "body": "eos quidem temporibus eum\nest ipsa sunt illum a facere\nomnis suscipit dolorem voluptatem incidunt\ntenetur deleniti aspernatur at quis" - }, - { - "postId": 93, - "id": 462, - "name": "assumenda quia sint", - "email": "Nathanael@jada.org", - "body": "adipisci et accusantium hic deserunt voluptates consequatur omnis\nquod dolorem voluptatibus quis velit laboriosam mollitia illo et\niure aliquam dolorem nesciunt laborum\naperiam labore repellat et maxime itaque" - }, - { - "postId": 93, - "id": 463, - "name": "cupiditate quidem corporis totam tenetur rem nesciunt et", - "email": "Nicklaus@talon.io", - "body": "voluptate officiis nihil laudantium sint autem adipisci\naspernatur voluptas debitis nam omnis ut non eligendi\naliquam vel commodi velit officiis laboriosam corporis\nquas aliquid aperiam autem" - }, - { - "postId": 93, - "id": 464, - "name": "quisquam quaerat rerum dolor asperiores doloremque", - "email": "Jerald@laura.io", - "body": "consequatur aliquam illum quis\nfacere vel voluptatem rem sint atque\nin nam autem impedit dolores enim\nsoluta rem adipisci odit sint voluptas aliquam" - }, - { - "postId": 93, - "id": 465, - "name": "est sunt est nesciunt distinctio quaerat reprehenderit in vero", - "email": "Jamey_Dare@johnny.org", - "body": "ex corrupti ut pariatur voluptas illo labore non voluptates\nvoluptas sint et est impedit cum\nin fugiat cumque eum id rerum error\nut rerum voluptates facilis molestiae et labore voluptatem corrupti" - }, - { - "postId": 94, - "id": 466, - "name": "impedit autem distinctio omnis ipsam voluptas eaque", - "email": "Brant@yasmin.co.uk", - "body": "aut dignissimos eos facere velit totam\neaque aut voluptas ex similique ut ipsa est\nvoluptates ut tempora\nquis commodi officia et consequatur cumque delectus" - }, - { - "postId": 94, - "id": 467, - "name": "voluptas unde perferendis ut eaque dicta", - "email": "Adrianna_Howell@molly.io", - "body": "deleniti fuga hic autem\nsed rerum non voluptate sit totam consequuntur illo\nquasi quod aut ducimus dolore distinctio molestias\nnon velit quis debitis cumque voluptas" - }, - { - "postId": 94, - "id": 468, - "name": "nam praesentium est ipsa libero aut", - "email": "Amiya.Morar@emma.tv", - "body": "facilis repellendus inventore aperiam corrupti saepe culpa velit\ndolores sint ut\naut quis voluptates iure et a\nneque harum quia similique sunt eum voluptatem a" - }, - { - "postId": 94, - "id": 469, - "name": "vel eum quia esse sapiente", - "email": "Destany@bailey.info", - "body": "dolor unde numquam distinctio\nducimus eum hic rerum non expedita\ndolores et dignissimos rerum\nperspiciatis et porro est minus" - }, - { - "postId": 94, - "id": 470, - "name": "deleniti vitae alias distinctio dignissimos ab accusantium pariatur dicta", - "email": "Katarina.Wolff@joel.io", - "body": "molestias incidunt eaque\nnumquam reprehenderit rerum ut ex ad\nomnis porro maiores quaerat harum nihil non quasi ea\nasperiores quisquam sunt fugiat eos natus iure adipisci" - }, - { - "postId": 95, - "id": 471, - "name": "nihil ad debitis rerum optio est cumque sed voluptates", - "email": "Pearline@veda.ca", - "body": "quia non dolor\ncorporis consectetur velit eos quis\nincidunt ut eos nesciunt repellendus voluptas voluptate sint neque\ndoloribus est minima autem quis velit illo ea neque" - }, - { - "postId": 95, - "id": 472, - "name": "aspernatur ex dolor optio", - "email": "Belle.Braun@otis.name", - "body": "et necessitatibus earum qui velit id explicabo harum optio\ndolor dolores reprehenderit in\na itaque odit esse et et id\npossimus est ut consequuntur velit autem iure ut" - }, - { - "postId": 95, - "id": 473, - "name": "quaerat et excepturi autem animi fuga", - "email": "Eliane@libby.net", - "body": "quod corrupti eum quisquam rerum accusantium tempora\nreprehenderit qui voluptate et sunt optio et\niusto nihil amet omnis labore cumque quo\nsaepe omnis aut quia consectetur" - }, - { - "postId": 95, - "id": 474, - "name": "natus consequatur deleniti ipsum delectus", - "email": "Trey.Harber@christop.biz", - "body": "tempora sint qui iste itaque non neque qui suscipit\nenim quas rerum totam impedit\nesse nulla praesentium natus explicabo doloremque atque maxime\nmollitia impedit dolorem occaecati officia in provident eos" - }, - { - "postId": 95, - "id": 475, - "name": "cumque consequuntur excepturi consequatur consequatur est", - "email": "Kailyn@ivory.info", - "body": "ut in nostrum\nut et incidunt et minus nulla perferendis libero delectus\nnulla nemo deleniti\ndeleniti facere autem vero velit non molestiae assumenda" - }, - { - "postId": 96, - "id": 476, - "name": "quia hic adipisci modi fuga aperiam", - "email": "Amely.Kunde@rodrigo.co.uk", - "body": "officia quas aut culpa eum\neaque quia rem unde ea quae reiciendis omnis\nexcepturi nemo est vel sequi accusantium tenetur at earum\net rerum quisquam temporibus cupiditate" - }, - { - "postId": 96, - "id": 477, - "name": "ut occaecati non", - "email": "Thaddeus.Halvorson@ruthe.ca", - "body": "nulla veniam quo consequuntur ullam\nautem nisi error aut facere distinctio rerum quia tempore\nvelit distinctio occaecati ducimus\nratione similique doloribus" - }, - { - "postId": 96, - "id": 478, - "name": "quo error dignissimos numquam qui nam fugit voluptates et", - "email": "Hannah@emma.ca", - "body": "non similique illo\nquia et rem placeat reprehenderit voluptas\nvelit officiis fugit blanditiis nihil\nab deserunt ullam" - }, - { - "postId": 96, - "id": 479, - "name": "distinctio minima error aspernatur reiciendis inventore quo", - "email": "Maryam.Mann@thelma.info", - "body": "totam explicabo harum quam impedit sunt\ndoloremque consectetur id et minima eos incidunt quibusdam omnis\nsaepe maiores officiis eligendi alias sint est aut cumque\ndebitis cumque hic aut ut dolorum" - }, - { - "postId": 96, - "id": 480, - "name": "accusantium quo error repudiandae", - "email": "Michel@keira.us", - "body": "tenetur qui ut\narchitecto officiis voluptatem velit eos molestias incidunt eum dolorum\ndistinctio quam et\nsequi consequatur nihil voluptates animi" - }, - { - "postId": 97, - "id": 481, - "name": "recusandae dolor similique autem saepe voluptate aut vel sit", - "email": "Domenick@russell.ca", - "body": "dignissimos nobis vitae corporis delectus eligendi et ut ut\namet laudantium neque\net quia cupiditate debitis aliquid\ndolorem aspernatur libero aut autem quo et" - }, - { - "postId": 97, - "id": 482, - "name": "placeat eveniet sunt ut quis", - "email": "Chanelle@samson.me", - "body": "aliquid natus voluptas doloremque fugiat ratione adipisci\nunde eum facilis enim omnis ipsum nobis nihil praesentium\nut blanditiis voluptatem veniam\ntenetur fugit et distinctio aspernatur" - }, - { - "postId": 97, - "id": 483, - "name": "a ipsa nihil sed impedit", - "email": "Hermann.Kunde@rosina.us", - "body": "quos aut rerum nihil est et\ndolores commodi voluptas voluptatem excepturi et\net expedita dignissimos atque aut reprehenderit\nquis quo soluta" - }, - { - "postId": 97, - "id": 484, - "name": "hic inventore sint aut", - "email": "Olen@bryce.net", - "body": "vel libero quo sit vitae\nid nesciunt ipsam non a aut enim itaque totam\nillum est cupiditate sit\nnam exercitationem magnam veniam" - }, - { - "postId": 97, - "id": 485, - "name": "enim asperiores illum", - "email": "Lorenza.Carter@consuelo.ca", - "body": "soluta quia porro mollitia eos accusamus\nvoluptatem illo perferendis earum quia\nquo sed ipsam in omnis cum earum tempore eos\nvoluptatem illum doloremque corporis ipsam facere" - }, - { - "postId": 98, - "id": 486, - "name": "et aut qui eaque porro quo quis velit rerum", - "email": "Lamont@georgiana.biz", - "body": "iste maxime et molestiae\nqui aliquam doloremque earum beatae repellat\nin aut eum libero eos itaque pariatur exercitationem\nvel quam non" - }, - { - "postId": 98, - "id": 487, - "name": "sunt omnis aliquam labore eveniet", - "email": "Colin_Gutkowski@muriel.net", - "body": "sint delectus nesciunt ipsum et aliquid et libero\naut suscipit et molestiae nemo pariatur sequi\nrepudiandae ea placeat neque quas eveniet\nmollitia quae laboriosam" - }, - { - "postId": 98, - "id": 488, - "name": "quo neque dolorem dolorum non incidunt", - "email": "Albert@johnny.biz", - "body": "aut sunt recusandae laboriosam omnis asperiores et\nnulla ipsum rerum quis doloremque rerum optio mollitia provident\nsed iste aut id\nnumquam repudiandae veritatis" - }, - { - "postId": 98, - "id": 489, - "name": "aut quia et corporis voluptas quisquam voluptatem", - "email": "Hilma.Kutch@ottilie.info", - "body": "et dolorem sit\nreprehenderit sapiente occaecati iusto sit impedit nobis ut quia\nmaiores debitis pariatur nostrum et aut\nassumenda error qui deserunt laborum quaerat et" - }, - { - "postId": 98, - "id": 490, - "name": "et eum provident maxime beatae minus et doloremque perspiciatis", - "email": "Donnie@alfreda.biz", - "body": "minus nihil sunt dolor\nipsum a illum quis\nquasi officiis cupiditate architecto sit consequatur ut\net sed quasi quam doloremque" - }, - { - "postId": 99, - "id": 491, - "name": "eos enim odio", - "email": "Maxwell@adeline.me", - "body": "natus commodi debitis cum ex rerum alias quis\nmaxime fugiat fugit sapiente distinctio nostrum tempora\npossimus quod vero itaque enim accusantium perferendis\nfugit ut eum labore accusantium voluptas" - }, - { - "postId": 99, - "id": 492, - "name": "consequatur alias ab fuga tenetur maiores modi", - "email": "Amina@emmet.org", - "body": "iure deleniti aut consequatur necessitatibus\nid atque voluptas mollitia\nvoluptates doloremque dolorem\nrepudiandae hic enim laboriosam consequatur velit minus" - }, - { - "postId": 99, - "id": 493, - "name": "ut praesentium sit eos rerum tempora", - "email": "Gilda@jacques.org", - "body": "est eos doloremque autem\nsimilique sint fuga atque voluptate est\nminus tempore quia asperiores aliquam et corporis voluptatem\nconsequatur et eum illo aut qui molestiae et amet" - }, - { - "postId": 99, - "id": 494, - "name": "molestias facere soluta mollitia totam dolorem commodi itaque", - "email": "Kadin@walter.io", - "body": "est illum quia alias ipsam minus\nut quod vero aut magni harum quis\nab minima voluptates nemo non sint quis\ndistinctio officia ea et maxime" - }, - { - "postId": 99, - "id": 495, - "name": "dolor ut ut aut molestiae esse et tempora numquam", - "email": "Alice_Considine@daren.com", - "body": "pariatur occaecati ea autem at quis et dolorem similique\npariatur ipsa hic et saepe itaque cumque repellendus vel\net quibusdam qui aut nemo et illo\nqui non quod officiis aspernatur qui optio" - }, - { - "postId": 100, - "id": 496, - "name": "et occaecati asperiores quas voluptas ipsam nostrum", - "email": "Zola@lizzie.com", - "body": "neque unde voluptatem iure\nodio excepturi ipsam ad id\nipsa sed expedita error quam\nvoluptatem tempora necessitatibus suscipit culpa veniam porro iste vel" - }, - { - "postId": 100, - "id": 497, - "name": "doloribus dolores ut dolores occaecati", - "email": "Dolly@mandy.co.uk", - "body": "non dolor consequatur\nlaboriosam ut deserunt autem odit\nlibero dolore non nesciunt qui\naut est consequatur quo dolorem" - }, - { - "postId": 100, - "id": 498, - "name": "dolores minus aut libero", - "email": "Davion@eldora.net", - "body": "aliquam pariatur suscipit fugiat eos sunt\noptio voluptatem eveniet rerum dignissimos\nquia aut beatae\nmodi consequatur qui rerum sint veritatis deserunt est" - }, - { - "postId": 100, - "id": 499, - "name": "excepturi sunt cum a et rerum quo voluptatibus quia", - "email": "Wilburn_Labadie@araceli.name", - "body": "et necessitatibus tempora ipsum quaerat inventore est quasi quidem\nea repudiandae laborum omnis ab reprehenderit ut\nratione sit numquam culpa a rem\natque aut et" - }, - { - "postId": 100, - "id": 500, - "name": "ex eaque eum natus", - "email": "Emma@joanny.ca", - "body": "perspiciatis quis doloremque\nveniam nisi eos velit sed\nid totam inventore voluptatem laborum et eveniet\naut aut aut maxime quia temporibus ut omnis" - } -] \ No newline at end of file diff --git a/examples/fetch-json.js b/examples/fetch-json.js deleted file mode 100644 index d99aa94..0000000 --- a/examples/fetch-json.js +++ /dev/null @@ -1,33 +0,0 @@ -'use strict'; - -/** - * Fetching JSON results from a REST API - * - * The following example retrieves a list of comments and lists them in Alfred. The entries are filtered by user input - * and both the name and email fields are searched for matches. - */ - -const Hugo = require('../'); - -Hugo.fetch('http://jsonplaceholder.typicode.com/comments') - .then(function (body) { - let items = body; - - // Filter items name and email fields by user input - items = Hugo.matches(items, Hugo.input, { - keys: ['name', 'email'] - }); - - // Map our filtered API response items to Alfred items - items = items.map(x => ({ - title: x.name, - subtitle: x.email, - arg: x.id - })); - - // Add items to Hugo - Hugo.addItems(items); - - // Display items - Hugo.feedback(); - }); diff --git a/examples/file-cache.js b/examples/file-cache.js deleted file mode 100644 index 3a0d787..0000000 --- a/examples/file-cache.js +++ /dev/null @@ -1,95 +0,0 @@ -'use strict'; - -/** - * Process a file and cache results - * This example shows how to use the cacheFile method to process a file once and cache the results until the file has - * changed again. - */ - -const Hugo = require('../'); -const path = require('path'); -const process = require('process'); - -// Number of milliseconds per nanosecond -const MS_PER_NS = 1e-6; - -/** - * PHP-like rounding with precision - * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round - * @param {number} number - * @param {number} precision - * @return {number} - */ -function round (number, precision) { - var factor = Math.pow(10, precision); - var tempNumber = number * factor; - var roundedTempNumber = Math.round(tempNumber); - return roundedTempNumber / factor; -}; - -/** - * My fancy processing function that takes longer than I'd like to complete - * @param {string} file Input file - * @return {Object} - */ -function processComments(file) { - let data = JSON.parse(file); - - return data.map(x => ({ - title: x.name, - subtitle: x.email, - arg: x.id, - valid: true - })); -} - -// Get cached file instance -let file = Hugo.cacheFile(path.join(__dirname, 'comments.json'), 'comments'); - -// Subscribe to change event -file.on('change', function (cache, file) { - let result = processComments(file); - - cache.store(result); -}); - -// == Benchmark == - -const benchRuns = 200; - -console.log('Processing comments took:'); - -// Measture time (uncached) -let uncachedMeasurements = []; -let avgUncached = 0; - -for (let i = 0; i < benchRuns; i++) { - let now = process.hrtime(); - file.get(); - uncachedMeasurements[uncachedMeasurements.length] = process.hrtime(now); - file.clearCacheSync(); -} - -for (let i = 0; i < uncachedMeasurements.length; i++) { - avgUncached = round((uncachedMeasurements[i][0] * 1000) + (uncachedMeasurements[i][1] * MS_PER_NS), 3); -} - -console.log(`uncached (${uncachedMeasurements.length}x avg): ${avgUncached}ms`); - -// Measture time again (cached) -let cachedMeasurements = []; -let avgCached = 0; - -for (let i = 0; i < benchRuns; i++) { - let now = process.hrtime(); - file.get(); - cachedMeasurements[cachedMeasurements.length] = process.hrtime(now); -} - -for (let i = 0; i < cachedMeasurements.length; i++) { - avgCached = round((cachedMeasurements[i][0] * 1000) + (cachedMeasurements[i][1] * MS_PER_NS), 3); -} - -console.log(`cached (${cachedMeasurements.length}x avg): ${avgCached}ms`); - -file.clearCacheSync(); From 59cca5a087088718a31856847958da67abed5a42 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Tue, 18 Jun 2019 00:49:30 +0200 Subject: [PATCH 12/35] Update docs --- docs/actions.md | 77 ++++++++++++++++++++++++++++++++++++++++++++++ docs/file-cache.md | 34 ++++++++++++++++++++ 2 files changed, 111 insertions(+) create mode 100644 docs/actions.md create mode 100644 docs/file-cache.md diff --git a/docs/actions.md b/docs/actions.md new file mode 100644 index 0000000..de10403 --- /dev/null +++ b/docs/actions.md @@ -0,0 +1,77 @@ +# Actions + +Actions are an easy way to structure your workflow in-code without having to drag all kinds of nodes in to launch different script for each action. Now you can run one script and have it handle all your actions. + +Best way to understand is to look at the examples below! + +### Examples + +##### Simple action + +```js +import { Hugo } from "alfred-hugo"; + +const hugo = new Hugo(); + +// Hello action +hugo.action("hello", (query) => { + console.log(`Hello ${query}!`); +}); + +// Run matching actions +hugo.run(); +``` +```sh +node index.js hello world +# Hello world! +``` + +##### Action with nested sub-actions + +```js +import { Hugo } from "alfred-hugo"; + +const hugo = new Hugo(); + +// List action +const listAction = hugo.action("list", (query) => { + console.log("Usage: list "); +}); + +// List bikes sub-action +listAction.action("bikes", (query) => { + const brand = query[0] || ""; + + console.log(`Here be a list of ${brand} bikes.`); +}); + +// List cars sub-action +const listCarsAction = listAction.action("cars", (query) => { + const brand = query[0] || ""; + + console.log(`Here be a list of ${brand} cars.`); +}); + +// Sub-action of the list cars sub-action. +listCarsAction.action("Porsche", (query) => { + console.log("Porsche, ahh very fancy cars!"); +}); + +// Run matching actions +hugo.run(); +``` + +```sh +node index.js list +# Usage: list + +node index.js list bikes Ducati +# Here be a list of Ducati bikes. + +node index.js list cars Ferrari +# Here be a list of Ferrari cars. + +node index.js list cars Porsche +# Porsche, ahh very fancy cars! +``` + diff --git a/docs/file-cache.md b/docs/file-cache.md new file mode 100644 index 0000000..e0f252f --- /dev/null +++ b/docs/file-cache.md @@ -0,0 +1,34 @@ +# File Cache + +Processing files is often takes time and waste of resources when the file hardly ever changes. Caching the processed data isn't very hard but you'd still have to check if the file has been changed over time and reprocess it, cache it again and so on. + +The built-in file cache (for lack of a better name) does all this for you and is built upon the built-in [cache](./cache). Take a look at the examples on how to use it. + +### Example + +```js +import { Hugo } from "alfred-hugo"; + +const hugo = new Hugo(); + +// Create the file cache +const fc = hugo.cacheFile('/path/to/file.to.process'); + +// Define the change handler for processing your file +fc.on("change", (cache, fileContents) => { + // Process the file contents + const foo = processFoo(fileContents); + const bar = processBar(fileContents); + + // Set the results + cache.set("foo", foo); + cache.set("bar", bar); +}); + +// Get the results +const results = fc.get(); + +console.log(results.foo); // Will output processed foo data +console.log(results.bar); // Will output processed bar data +``` + From 022b89b19594e5d092d78aa9f0791c3adf76c00d Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Fri, 21 Jun 2019 14:23:36 +0200 Subject: [PATCH 13/35] Update documentation --- docs/items.md | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++ docs/match.md | 34 ++++++++++++++++++++++++ 2 files changed, 107 insertions(+) create mode 100644 docs/items.md create mode 100644 docs/match.md diff --git a/docs/items.md b/docs/items.md new file mode 100644 index 0000000..9b71d75 --- /dev/null +++ b/docs/items.md @@ -0,0 +1,73 @@ +# Items & Variables + +Hugo is mainly intended as a framework for writing [script filters](https://www.alfredapp.com/help/workflows/inputs/script-filter/), therefore you have direct access to the items that will be sent to Alfred and displayed. The same goes for variables and the rerun parameter, all part of the output sent to Alfred. + +To learn more about items, variables and the rerun parameter, please see the Alfred documentation at https://www.alfredapp.com/help/workflows/inputs/script-filter/json + +### Examples + +#### Items + +```js +import { Hugo } from "alfred-hugo"; + +const hugo = new Hugo(); + +// Add single item +hugo.items.push({ + title: "Foo", + subtitle: "Bar", + arg: "foobar" +}); + +// Add multiple items +const items = [ + { + title: "Foo", + subtitle: "Bar", + arg: "foobar" + }, + { + title: "Apple", + subtitle: "Pie", + arg: "omnomnom" + } +]; + +hugo.items = hugo.items.concat(items); +``` + +#### Variables + +Besides item variables you can also set global/session variables (please see the [documentation](https://www.alfredapp.com/help/workflows/inputs/script-filter/json/#variables)). Much like items, the variables are directly exposed as an object. + +```js +import { Hugo } from "alfred-hugo"; + +const hugo = new Hugo(); + +// Set a variable +hugo.variables.foo = "bar"; + +// Set (override) multiple +hugo.variables = { + foo: "bar", + apple: "pie" +}; +``` + +#### Rerun + +> Scripts can be set to re-run automatically after an interval using the 'rerun' key with a value of 0.1 to 5.0 seconds. The script will only be re-run if the script filter is still active and the user hasn't changed the state of the filter by typing and triggering a re-run. + +```js +import { Hugo } from "alfred-hugo"; + +const hugo = new Hugo(); + +// Will re-run the script each 650ms after output +hugo.rerun = 0.65; + +hugo. +``` + diff --git a/docs/match.md b/docs/match.md new file mode 100644 index 0000000..c0688ca --- /dev/null +++ b/docs/match.md @@ -0,0 +1,34 @@ +# Matching + +Alfred has a [pretty good matching](https://www.alfredapp.com/help/workflows/inputs/script-filter/#alfred-filters-results) algorithm which might good enough for most purposes. However, if you need more control over how your items are filtered you can use Hugo's `match` method which is a simple wrapper around [Fuse.js](https://fusejs.io/). + +### Example + +```js +import { Hugo } from "alfred-hugo"; + +const hugo = new Hugo(); + +// Add multiple items +hugo.items.push( + { + title: "Foo", + subtitle: "Bar", + arg: "foobar" + }, + { + title: "Apple", + subtitle: "Pie", + arg: "omnomnom" + } +); + +// Match items on arg +const results = hugo.match(hugo.items, "omnom", { + keys: ["arg"] +}); + +// Filter items, discarding non-matching items +hugo.items = results; +``` + From a8ae1eb76794354b099237c4eefc61503f148558 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Fri, 21 Jun 2019 14:47:37 +0200 Subject: [PATCH 14/35] Update README --- README.md | 483 ++---------------------------------------------- docs/updates.md | 6 + 2 files changed, 24 insertions(+), 465 deletions(-) diff --git a/README.md b/README.md index 5e925c4..9cc1fc8 100644 --- a/README.md +++ b/README.md @@ -1,489 +1,42 @@ # ![Hugo](https://cdn.rawgit.com/cloudstek/alfred-hugo/master/media/logo-hugo.svg) -> Alfred workflow bindings for NodeJS. Inspired by [Alfy](https://github.com/sindresorhus/alfy) and [alfred-workflow-nodejs](https://github.com/giangvo/alfred-workflow-nodejs). +![CircleCI](https://img.shields.io/circleci/build/github/Cloudstek/alfred-hugo.svg) [![Coverage Status](https://coveralls.io/repos/github/Cloudstek/alfred-hugo/badge.svg?branch=master)](https://coveralls.io/github/Cloudstek/alfred-hugo?branch=master) [![Open Issues](https://img.shields.io/github/issues/Cloudstek/alfred-hugo.svg)](https://github.com/Cloudstek/alfred-hugo/issues) ![npm](https://img.shields.io/npm/dt/alfred-hugo.svg) ![GitHub](https://img.shields.io/github/license/Cloudstek/alfred-hugo.svg) ![GitHub stars](https://img.shields.io/github/stars/Cloudstek/alfred-hugo.svg) -[![Build Status](https://travis-ci.org/Cloudstek/alfred-hugo.svg?branch=master)](https://travis-ci.org/Cloudstek/alfred-hugo) [![Open Issues](https://img.shields.io/github/issues/Cloudstek/alfred-hugo.svg)](https://github.com/Cloudstek/alfred-hugo/issues) +Hugo is a [script filter](https://www.alfredapp.com/help/workflows/inputs/script-filter/) framework for your Alfred workflows. It can handle fetching and caching data, configuration storage, checking for updates and much much more. But I suppose you can use it for other purposes in your workflow as well :man_shrugging: ### Highlights -* Written in [Flow](https://flowtype.org) using [Babel](https://babeljs.io). -* Fuzzy search/filter your data using [Fuse.js](http://fusejs.io). -* Fetch (JSON) from REST API's using [Got](https://github.com/sindresorhus/got). -* Group multiple actions in one file. -* Update notifications (for both NPM and Packal workflows). +* Written in Typescript :star: +* Well tested :thumbsup: +* Built-in cache and configuration storage +* Advanced filtering of items using [Fuse.js](http://fusejs.io) :mag: +* Fetch (JSON) from REST API's using [Axios](https://github.com/axios/axios) :earth_americas: +* Update notifications (for both NPM and Packal workflows) :mailbox: -## Index +## Getting started -* [Prerequisites](#prerequisites) -* [Installing](#installing) -* [Usage](#usage) -* [Examples](#examples) -* [API](#api) - * [Options](#options) - * [Properties](#properties) - * [Methods](#methods) -* [Publishing your workflow to NPM](#publishing-your-workflow-to-npm) -* [Workflows using Hugo](#workflows-using-hugo) -* [Contributing](#contributing) -* [Authors](#authors) - * [Contributors](#contributors) -* [License](#license) - -## Prerequisites +### Prerequisites * NodeJS 8 or higher * Alfred 3.4.1+ with [paid powerpack addon](https://www.alfredapp.com/powerpack/buy/) -## Installing +### Installing -Hugo is available as NPM package and can be installed with `npm`. +Hugo can be installed using Yarn or NPM: ```bash -$ npm install --save alfred-hugo -``` - -## Usage - -In your project simply require/import Hugo and off you go :sunglasses: - -```javascript -var Hugo = require('alfred-hugo'); -// or -import Hugo from 'alfred-hugo'; -``` - -When you decide to write your Alfred workflow in [Flow](https://flowtype.org), you'll benefit from static type checking. Flow will automatically find and use the Flow annotations in the Hugo package and any other packages written in Flow. Please see the [Flow documentation](https://flowtype.org/docs/declarations.html#declaration-files) for more info about declarations. - -Example: - -```javascript -// @flow -var Hugo = require('alfred-hugo'); - -var myOptions = false; -Hugo.options(myOptions); // Will cause an error as Hugo.options expects an Object -``` - -​If you feel like writing your code in plain Javascript … that's fine too :smile: You can still use all the wonderful features of Hugo. - -## Examples - -Please see the [examples](examples) directory for, well ... examples. - -## API - -### Options - -#### checkUpdates - -Type: `boolean` - -Default: `true` - -Enable/disable checking for updates. - -#### updateSource - -Type: `string` - -Default: `packal` - -Possible values: `packal` `npm` - -Check Packal or NPM for updates of the workflow. If the package can't be found on NPM then Packal will be checked as fallback. - -#### updateInterval - -Type: `number` [`Duration`](https://momentjs.com/docs/#/durations/) - -Default: 1 day (86400 seconds) - -Interval to check for updates in seconds or as [Duration](https://momentjs.com/docs/#/durations/). - -#### updateNotification - -Type: `boolean` - -Default: `true` - -Display a notification bubble when a workflow update is available. The notification bubble will only display once every `updateInterval`. - -*Clicking the notification won't do anything at this moment but [`node-notifier`](https://github.com/mikaelbr/node-notifier) has extensive support for user interaction. Pull requests are welcome!* - -#### updateItem - -Type: `boolean` - -Default: `true` - -Display an update item at the bottom of the list when an update is available. - -When the item is activated, it will set a variable named `task` (`{var:task}` in Alfred) with the value `wfUpdate`. The argument is set to the URL where the update can be found, either on Packal or NPM depending on `updateSource`. You can link the output to an [Open URL](https://www.alfredapp.com/help/workflows/actions/open-url/) action so a browser opens when the user selects the update item. - -![Opening a browser for updates](media/update-action.png) - -#### useTmpCache - -Type: `boolean` - -Default: `true` - -Use the OS temp directory for your workflow cache when `true`, otherwise use the directory set by Alfred in the`alfred_workflow_cache` environment variable. It's recommended to leave this set at `true` unless you want your cache to survive reboots and clean it up yourself every once in a while. - -### Properties - -#### Hugo.alfredMeta - -Type: `Object` - -Collection of Alfred metadata that is available to the script through environment variables. See the alfred documentation for more info: https://www.alfredapp.com/help/workflows/script-environment-variables/. - -When you use a custom Alfred theme, the `themeFile` property will be set to the path of the theme file (which is a JSON file). Also see [Hugo.alfredTheme](#hugo.alfredtheme). - -```javascript -{ - version: process.env.alfred_version, - theme: process.env.alfred_theme, - themeFile: '', - themeBackground: process.env.alfred_theme_background, - themeSelectionBackground: process.env.alfred_theme_selection_background, - themeSubtext: parseFloat(process.env.alfred_theme_subtext), - preferences: process.env.alfred_preferences, - preferencesLocalHash: process.env.alfred_preferences_localhash, - debug: process.env.alfred_debug === '1' -} +$ yarn add alfred-hugo ``` -*Also see: [Hugo.workflowMeta](#hugo.workflowmeta)* - -#### Hugo.alfredTheme - -Type: `Object` - -When a custom Alfred theme is used, this will return the contents of the theme file. Usefull if you need to render icons on-the-fly and want to know the background colour. - -#### Hugo.cache - -Type: [`cache-conf `](https://github.com/samverschueren/cache-conf) - -> Simple cache config handling for your app or module - -#### Hugo.config - -Type: [`conf `](https://github.com/sindresorhus/conf) - -> Simple config handling for your app or module - -#### Hugo.input - -Type: `string` - -Hugo.input contains the user input (first argument to the script) and can be used to filter your items. - -Even if you use this inside an `action` method, it will still return the correct user input, though I recommend using the provided query argument as can be seen in the [examples](#multiple-actions-in-one-file). - -#### Hugo.itemCount - -Type: `number` - -Number of Alfred items in the current output buffer. - -#### Hugo.outputBuffer - -Type: `Object` - -Current output buffer (read-only). - -#### Hugo.workflowMeta - -Type: `Object` - -Collection of workflow metadata that is available to the script through environment variables. See the alfred documentation for more info: https://www.alfredapp.com/help/workflows/script-environment-variables/. - -```javascript -{ - name: process.env.alfred_workflow_name, - version: process.env.alfred_workflow_version, - uid: process.env.alfred_workflow_uid, - bundleId: process.env.alfred_workflow_bundleid, - data: process.env.alfred_workflow_data, - cache: process.env.alfred_workflow_cache, - icon: path.join(process.cwd(), 'icon.png') -} -``` - -### Methods - -#### Hugo.addItem(item) - -##### item - -Type: `Object` - -Item to add to the list of items which will be displayed. The only property that is required is `title`, all the others are optional. See the [Alfred documentation](https://www.alfredapp.com/help/workflows/inputs/script-filter/json/) for all the supported properties. - -###### Item variables - -~~One thing that is simplified in Hugo (and quite undocumented in Alfred) is the way to add variables to items using the `arg` property. Instead of supplying a `string` you can supply an `Object` to assign variables to an item instead of globally. Now when an item is activated it will set those environment variables during this session so you can use them throughout your Alfred workflow in other actions.~~ - -Since [version 3.4.1](https://www.alfredapp.com/help/workflows/inputs/script-filter/json/#variables) Alfred now supports item and item modifier variables and have added documentation on the subject. You don't have to worry about what version of Alfred is running, Hugo takes care of that so you can use either syntax, though we prefer the new ​:smile:​. - -Old syntax: - -```javascript -{ - title: 'My item', - valid: true, - arg: { - arg: 'my argument', - variables: { - foo: 'bar', - bleep: 'bloop' - } - } -} -``` - -New (preferred) syntax: - -```javascript -{ - title: 'My item', - valid: true, - arg: 'my argument', - variables: { - foo: 'bar', - bleep: 'bloop' - }, - mods: { - alt: { - valid: true, - arg: 'my alt argument', - variables: { - bar: 'foo' - } - } - } -} -``` - -#### Hugo.addItems(items) - -##### items - -Type: `Array` - -Add multiple items to the list of items which will be displayed. See Hugo.addItem for more info. - -#### Hugo.addVariable(key, value) - -##### key - -Type: `string` - -##### value - -Type: `string` `Object` - -###### Variables - -> Variables can be passed out of the script filter within a `variables` object. This is useful for two things. Firstly, these variables will be passed out of the script filter's outputs when actioning a result. Secondly, any variables passed out of a script will be passed back in as environment variables when the script is run within the same session. This can be used for very simply managing state between runs as the user types input or when the script is set to re-run after an interval. - -```json -{ - "variables": { - "foo": "bar" - }, - "items": [ - ... - ] -} -``` - -See the [Alfred documentation](https://www.alfredapp.com/help/workflows/inputs/script-filter/json/) for more info about session variables. - -#### Hugo.getVariable(key) - -Type: `string` - -Get the value of a session variable, see Hugo.addVariable for more info. - -##### key - -Type: `string` - -#### Hugo.addVariables(variables) - -##### variables - -Type: `Object` - -#### Hugo.getVariables() - -Type: `Object` - -Get all the session variables, , see Hugo.addVariables for more info. - -#### Hugo.getItemVariables(item) - -Type: `Object` - -Get all the item variables without having to deal with version differences, see Hugo.addItem for more info. - -##### item - -Type: `Object` - -#### Hugo.action(keyword, callback) - -##### keyword - -Type: `string` - -Action name (myaction in the example below), - -##### callback - -Type: `function` - -Callback to execute when the keyword matches the first argument. The callback takes one argument, the user input (myquery in the example below). - -###### Example ```bash -/usr/local/bin/node index.js myaction "myquery" -``` - -#### Hugo.cacheFile(filepath, cacheName) - -Processing/parsing files often takes time and is only needed when the file has changed. You can cache the results for a period of time, but you'll be left with an outdated cache when the file changes. - -This method makes caching the processed results a lot easier by checking whether a file has changed. If it hasn't changed, `get()` will return the cached value. If no cached result is found or the file has changed, the `change` event will be emitted with a reference to the cache store, file contents and SHA-1 hash so you can process your file and store the results in the cache store. - -*\* It's recommended to have the `useTmpCache` option set to `true` to prevent the cache from piling up as it isn't cleaned from time to time, unlike your OS temporary folder (for example `/tmp`) which is cleared after a reboot.* - -##### filepath - -Type: `string` - -Absolute path to the file that you like to process and check for changes. - -##### cacheName - -Type: `string` - -Cache name, this will be the name of the directory where the cached results are stored. It's possible but not recommended to share one cache name with other `cacheFile` instances. - -Check out [file-cache.js.flow](file-cache.js.flow) and the [example](examples/file-cache.js) to see how to implement it. - -#### Hugo.checkUpdates() - -Checks for workflow package updates on either NPM or Packal when enabled. No need to call this method manually, updates will be checked automagically ​:sparkles:​ - -#### Hugo.clearCache() - -Empties the workflow cache directory but doesn't remove the directory itself. - -Call `Hugo.clearCacheSync()` if you need it synchronously. - -#### Hugo.filterItems(query, options) - -Fuzzy filter the output buffer by search query using Fuse.js. Add items to the output buffer first and then call `filterItems` to remove the items that do not match the search query. This method alters the output buffer directly. - -##### query - -Type: `string` - -Search query - -##### options - -Type: `Object` - -[Fuse.js](http://fusejs.io) options, please see the [documentation](https://github.com/krisk/fuse#usage) for available options. - -#### Hugo.options(options) - -##### options - -Type: `Object` - -Set Hugo options, see below for available options and their defaults: - -```javascript -{ - checkUpdates: true, - updateSource: 'packal', - updateInterval: moment.duration(1, 'days'), // 86.400 seconds - updateNotification: true, - updateItem: true -} +$ npm install --save alfred-hugo ``` -#### Hugo.matches(candidates, query, options) - -Filter the list of candidates by search query using Fuse.js. This will return the filtered candidates list. - -##### candidates - -Type: `Array` - -List of candidates to filter. This may be any object, not specifically an Alfred item. - -##### query - -Type: `string` - -Search query +### Writing your script filter -##### options +Please see the [docs](./docs) for documentation and examples on how to use Hugo to write your script filters. -Type: `Object` - -[Fuse.js](http://fusejs.io) options, please see the [documentation](https://github.com/krisk/fuse#usage) for available options. - -#### Hugo.notification(options) - -Display a notification using [node-notifier](https://www.npmjs.com/package/node-notifier). For all available configuration options see their documentation. - -The title option defaults to the workflow name or 'Alfred' when not available for some reason. - -##### option - -Type: `Object` - -#### Hugo.rerun(value) - -> Scripts can be set to re-run automatically after an interval using the 'rerun' key with a value of 0.1 to 5.0 seconds. The script will only be re-run if the script filter is still active and the user hasn't changed the state of the filter by typing and triggering a re-run. - -##### value - -Type: `number` - -#### Hugo.feedback() - -Checks for updates (if enabled) and flushes the output buffer to the console so Alfred can display the items. - -#### Hugo.fetch(url, options, cacheAge) - -Helper method to fetch an URL with `got` and optionally cache the result. Useful when working with REST API's. - -##### url - -Type: `string` - -##### options - -Type: `Object` - -See the [got documentation](https://www.npmjs.com/package/got#api) for all available options. - -##### cacheAge - -Type: `number` `null` - -Number of seconds to cache the result. - -## Publishing your workflow to NPM +### Publishing your workflow to NPM To publish your workflow to NPM, use [alfred-link](github.com/samverschueren/alfred-link). @@ -501,7 +54,7 @@ To publish your workflow to NPM, use [alfred-link](github.com/samverschueren/alf > You can now install the `alfred-unicorn` package like this -``` +```bash $ npm install -g alfred-unicorn ``` diff --git a/docs/updates.md b/docs/updates.md index 472809f..d56dc43 100644 --- a/docs/updates.md +++ b/docs/updates.md @@ -4,6 +4,12 @@ If your workflow has been published on NPM or Packal, Hugo can automatically not There are two ways to notify the user of an available update, with a notification and with an item on the bottom of the list. You're free to choose either one or both. If you disable both methods, you effectively disable checking for updates. +### Update item option + +When the item is activated, it will set a variable named `task` (`{var:task}` in Alfred) with the value `wfUpdate`. The argument is set to the URL where the update can be found, either on Packal or NPM depending on `updateSource`. You can link the output to an [Open URL](https://www.alfredapp.com/help/workflows/actions/open-url/) action so a browser opens when the user selects the update item. + +![Opening a browser for updates](../media/update-action.png) + ### Examples #### Defaults From 0e24fcbabcea313fdd194371461c26d1c9bad54e Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Fri, 21 Jun 2019 14:47:44 +0200 Subject: [PATCH 15/35] Add CI --- .circleci/config.yml | 17 +++++++++++++++++ package.json | 2 +- 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..1ff3307 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,17 @@ +version: 2 + +jobs: + test: + docker: + - image: node:8 + steps: + - checkout + + - run: yarn + - run: yarn test:ci + +workflows: + version: 2 + test: + jobs: + - test diff --git a/package.json b/package.json index bb0dd87..7d0cb2d 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "build:dist": "npm-run-all -s clean && tsc -p tsconfig.dist.json", "test": "npm-run-all clean:test clean:coverage build test:run clean:test", "test:run": "nyc ava", - "test:ci": "npm-run-all -p clean:* -s build:test && nyc -s ava && nyc report --reporter=text-lcov | coveralls", + "test:ci": "npm-run-all -p clean:* -s build && nyc -s ava && nyc report --reporter=text-lcov | coveralls", "lint": "npm-run-all -l -p lint:*", "lint:src": "tslint src/**/*.ts", "lint:test": "tslint test/**/*.ts" From 69f1435d2f1219b38503050f4e26ea2c0c7ef04b Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Fri, 21 Jun 2019 17:41:05 +0200 Subject: [PATCH 16/35] Fix icon path in snapshots --- test/helpers/init.ts | 18 +++++++++++++++++- test/snapshots/feedback.ts.md | 2 +- test/snapshots/feedback.ts.snap | Bin 447 -> 421 bytes test/updates/snapshots/updater.ts.md | 4 ++-- test/updates/snapshots/updater.ts.snap | Bin 482 -> 456 bytes 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/test/helpers/init.ts b/test/helpers/init.ts index f1e0d5c..8188da0 100644 --- a/test/helpers/init.ts +++ b/test/helpers/init.ts @@ -4,6 +4,7 @@ import path from "path"; import moment from "moment"; import fs from "fs-extra"; import nock from "nock"; +import sinon from "sinon"; import { Updater, Hugo, HugoOptions } from "../../src"; @@ -34,7 +35,22 @@ export function hugo(options?: HugoOptions) { }; } - return new Hugo(options); + // Init hugo + const h = new Hugo(options); + + // Init another Hugo that has no stubs and stuff + const originalHugo = new Hugo(options); + + sinon.stub(h, "workflowMeta").get(() => { + const workflowMeta = originalHugo.workflowMeta; + + // Give workflow icon a fixed path + workflowMeta.icon = "/foo/bar/icon.png"; + + return workflowMeta; + }); + + return h; } export function updater(cacheTtl?: number | moment.Duration) { diff --git a/test/snapshots/feedback.ts.md b/test/snapshots/feedback.ts.md index 0e43ac5..7101f3e 100644 --- a/test/snapshots/feedback.ts.md +++ b/test/snapshots/feedback.ts.md @@ -14,7 +14,7 @@ Generated by [AVA](https://ava.li). "title": "Workflow update available!",␊ "subtitle": "Version 2.0.0 is available. Current version: 1.0.0.",␊ "icon": {␊ - "path": "/Users/maarten/Projects/Alfred/alfred-hugo/icon.png"␊ + "path": "/foo/bar/icon.png"␊ },␊ "arg": "https://encrypted.google.com/search?sourceid=chrome&ie=UTF-8&q=site%3Apackal.org%20my.work.flow&btnI",␊ "variables": {␊ diff --git a/test/snapshots/feedback.ts.snap b/test/snapshots/feedback.ts.snap index 73dffc84352f7120cd4161063a0fc1b97053a8eb..7cedbf0139a9dc90546b0def2c4050110230a863 100644 GIT binary patch literal 421 zcmV;W0b2e+RzVp-P8v=10RbB00000000Ah zkwHttFcinriAa0%D0+yM)q^vw+hq)f3_^@_*$`qD)p~)fU6#FsJv?j~C!hFmXR#?T)UKM6c{#QR^e9({C2 z_hf&&>0Gsin!VcSWH=b$7%?7J>s~TOBQ-YCb349F59cO-uU78~i-C4A>UYci%nbhZ P9cufZ?;_-WBmw{cOpeQa literal 447 zcmV;w0YLsiRzVElU%yj%LOI@Biwynpu?J2Gz zraN9o2v2uLj(ujx9tBQY5i_(Q^SQ=a6f`z+MnCT=+*-r`)lUR;JCW$SS=y$GxwJ=l zWb~K3^_-Mh>kB?+Ah}4~GA`kg%jGwX-R%s3CCcrMnVP$4AUsjwzDOp9b(K;T8a>jK znkF%&pjbloL0m9jNz#Zqz}kf7$3~b1f*1juCV`2<9*spQ1V$xPDwQ=tSmMJVRjiEz zAp-5m7cr5Hf*)>4k%7;6yY7b|Vpim=-aOjbs1`5lQm3<0X{6Ne(g+I(R?4M#fcrWa pY?3LqRI)dD#_#Y=l2mq$i+-n>Cpb3v*N5r<`2+^RJex)W002oh%zyv@ diff --git a/test/updates/snapshots/updater.ts.md b/test/updates/snapshots/updater.ts.md index 9b9a7f3..fb92080 100644 --- a/test/updates/snapshots/updater.ts.md +++ b/test/updates/snapshots/updater.ts.md @@ -11,7 +11,7 @@ Generated by [AVA](https://ava.li). { arg: 'https://encrypted.google.com/search?sourceid=chrome&ie=UTF-8&q=site%3Apackal.org%20my.work.flow&btnI', icon: { - path: '/Users/maarten/Projects/Alfred/alfred-hugo/icon.png', + path: '/foo/bar/icon.png', }, subtitle: 'Version 2.0.0 is available. Current version: 1.0.0.', title: 'Workflow update available!', @@ -27,7 +27,7 @@ Generated by [AVA](https://ava.li). { arg: 'https://encrypted.google.com/search?sourceid=chrome&ie=UTF-8&q=site%3Apackal.org%20my.work.flow&btnI', icon: { - path: '/Users/maarten/Projects/Alfred/alfred-hugo/icon.png', + path: '/foo/bar/icon.png', }, subtitle: 'Version 2.0.0 is available. Current version: 1.0.0.', title: 'Workflow update available!', diff --git a/test/updates/snapshots/updater.ts.snap b/test/updates/snapshots/updater.ts.snap index 79160a29d225335a97156eb0dc49ea89d388a3ee..41f8d741a9c437617c2d21caa95e17cc64be5f9e 100644 GIT binary patch literal 456 zcmV;(0XP0ZRzV0l%D}rDhPp)n7UAqfW=AO)HIEQ?Y3g%1(ljUN^MeX?u!p>I5}y z8b~;~t64>)tX5bhihkvr?lL_8#xUI`f<;F%Qr>vbM~`u(jX|X~%+y6o8!?#qqaYBY ynFxuh_kyflJR7$ z0}@Mr09BcpSXkJZn3x#w9ZGK7rlnE|!6bq)1fLAXnt_~IOhb-JZ#Z{-ts_+@goTbgh%|GtCxjO;?1&ywj7rD< zrbH|q#@&YFOVMLh&Kj-l^@Ww{&xYcfRhF6&b-FabLVA_OTJHc4gzVx@AO_X84mS`? z0UR2k!&md%5n)DEQN?Y|b-;!jOFK*|E<$?|*Kp0|%BFqF1KKv??6p`*7HYfygsIzK z6A;dDj=dr*?;2H!C_9c^s@XH&Y^w11g~EwGl{`68iSyQ_Il9U^ZM}Bdz$)g`=B*4Y z_vS+&BQqaS?T^wXEoG7-JxZl!A=#25xvNMs=t$-gnhpzo>gl7N{%1Ws0;el?YT5(<0G?ptCjbBd From 2bb9721a51708cc5452cc714bef811459115d289 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Fri, 21 Jun 2019 17:44:01 +0200 Subject: [PATCH 17/35] Fix notification testing on linux --- src/hugo.ts | 4 +++- test/helpers/init.ts | 1 + test/hugo.ts | 11 +++++++++++ test/updates/updater.ts | 1 + 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/hugo.ts b/src/hugo.ts index 2d9ed5d..1224a68 100644 --- a/src/hugo.ts +++ b/src/hugo.ts @@ -62,7 +62,9 @@ export class Hugo { this.updater = new Updater(this.cache, this.options.updateInterval); // Notofier - this.notifier = new NotificationCenter(); + this.notifier = new NotificationCenter({ + withFallback: true, + }); // Actions this.actions = []; diff --git a/test/helpers/init.ts b/test/helpers/init.ts index 8188da0..133e2c7 100644 --- a/test/helpers/init.ts +++ b/test/helpers/init.ts @@ -1,6 +1,7 @@ import { Cache } from "@cloudstek/cache"; import crypto from "crypto"; import path from "path"; +import os from "os"; import moment from "moment"; import fs from "fs-extra"; import nock from "nock"; diff --git a/test/hugo.ts b/test/hugo.ts index 8932e1e..00563fc 100644 --- a/test/hugo.ts +++ b/test/hugo.ts @@ -2,6 +2,7 @@ import test from "ava"; import moment from "moment"; import fs from "fs-extra"; import path from "path"; +import os from "os"; import * as utils from "../src/utils"; @@ -128,6 +129,11 @@ test("input with no input", (t) => { }); test("notify", async (t) => { + if (os.platform() !== "darwin") { + t.pass("Notifications only work on MacOS."); + return; + } + const h = hugo(); await t.notThrowsAsync(async () => { @@ -140,6 +146,11 @@ test("notify", async (t) => { }); test("notify with missing options", async (t) => { + if (os.platform() !== "darwin") { + t.pass("Notifications only work on MacOS."); + return; + } + const h = hugo(); await t.throwsAsync(async () => { diff --git a/test/updates/updater.ts b/test/updates/updater.ts index 4bfd84f..890029f 100644 --- a/test/updates/updater.ts +++ b/test/updates/updater.ts @@ -101,6 +101,7 @@ test.serial("update item only", async (t) => { test.serial("check update item", async (t) => { const h = hugo({ updateSource: "packal", + updateNotification: false, }); // Mock request From 2dab035eac2de76df1946d4140e251a7cb083cf4 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Fri, 21 Jun 2019 18:22:20 +0200 Subject: [PATCH 18/35] Add missing coveralls --- package.json | 1 + yarn.lock | 338 ++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 335 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 7d0cb2d..535e841 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ "@types/semver": "^6.0.0", "@types/sinon": "^7.0.12", "ava": "^2.0.0", + "coveralls": "^3.0.4", "del-cli": "^2.0.0", "mockdate": "^2.0.2", "nock": "^10.0.6", diff --git a/yarn.lock b/yarn.lock index d0c5b86..ef79e4e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -419,6 +419,16 @@ resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-2.3.5.tgz#9da44ed75571999b65c37b60c9b2b88db54c585d" integrity sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg== +ajv@^6.5.5: + version "6.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1" + integrity sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + alfred-link@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/alfred-link/-/alfred-link-0.3.0.tgz#d7afce495c04d85c6293c9a5abefbe7506ef8dd5" @@ -586,6 +596,18 @@ arrify@^2.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== +asn1@~0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" + integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== + dependencies: + safer-buffer "~2.1.0" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= + assertion-error@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" @@ -601,6 +623,11 @@ async-each@^1.0.3: resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= + atob@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" @@ -688,6 +715,16 @@ ava@^2.0.0: update-notifier "^3.0.0" write-file-atomic "^3.0.0" +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= + +aws4@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" + integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== + axios@^0.19.0: version "0.19.0" resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8" @@ -732,6 +769,13 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= + dependencies: + tweetnacl "^0.14.3" + big-integer@^1.6.7: version "1.6.43" resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.43.tgz#8ac15bf13e93e509500859061233e19d8d0d99d1" @@ -886,6 +930,11 @@ camelcase@^5.0.0, camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= + chai@^4.1.2: version "4.2.0" resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" @@ -1066,6 +1115,13 @@ color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +combined-stream@^1.0.6, combined-stream@~1.0.6: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + commander@^2.12.1, commander@~2.20.0: version "2.20.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" @@ -1142,6 +1198,23 @@ core-js@^2.0.0: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A== +core-util-is@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +coveralls@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.0.4.tgz#f50233c9c62fd0973f710fce85fd19dba24cff4b" + integrity sha512-eyqUWA/7RT0JagiL0tThVhjbIjoiEUyWCjtUJoOPcWoeofP5WK/jb2OJYoBFrR6DvplR+AxOyuBqk4JHkk5ykA== + dependencies: + growl "~> 1.10.0" + js-yaml "^3.11.0" + lcov-parse "^0.0.10" + log-driver "^1.2.7" + minimist "^1.2.0" + request "^2.86.0" + cp-file@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-6.2.0.tgz#40d5ea4a1def2a9acdd07ba5c0b0246ef73dc10d" @@ -1193,6 +1266,13 @@ currently-unhandled@^0.4.1: dependencies: array-find-index "^1.0.1" +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= + dependencies: + assert-plus "^1.0.0" + date-time@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/date-time/-/date-time-2.1.0.tgz#0286d1b4c769633b3ca13e1e62558d2dbdc2eba2" @@ -1345,6 +1425,11 @@ del@^4.1.1: pify "^4.0.1" rimraf "^2.6.3" +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= + diff@^3.2.0, diff@^3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -1376,6 +1461,14 @@ duplexer3@^0.1.4: resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= +ecc-jsbn@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" + integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= + dependencies: + jsbn "~0.1.0" + safer-buffer "^2.1.0" + emittery@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.4.1.tgz#abe9d3297389ba424ac87e53d1c701962ce7433d" @@ -1540,6 +1633,11 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + extglob@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" @@ -1554,6 +1652,21 @@ extglob@^2.0.4: snapdragon "^0.8.1" to-regex "^3.0.1" +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + fast-diff@^1.1.2: version "1.2.0" resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" @@ -1571,6 +1684,11 @@ fast-glob@^2.2.6: merge2 "^1.2.3" micromatch "^3.1.10" +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + figures@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.0.0.tgz#756275c964646163cc6f9197c7a0295dbfd04de9" @@ -1653,6 +1771,20 @@ foreground-child@^1.5.6: cross-spawn "^4" signal-exit "^3.0.0" +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= + +form-data@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" + integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.6" + mime-types "^2.1.12" + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -1730,6 +1862,13 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= + dependencies: + assert-plus "^1.0.0" + glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" @@ -1833,6 +1972,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== +"growl@~> 1.10.0": + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" @@ -1849,6 +1993,19 @@ handlebars@^4.1.2: optionalDependencies: uglify-js "^3.1.4" +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= + +har-validator@~5.1.0: + version "5.1.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" + integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== + dependencies: + ajv "^6.5.5" + har-schema "^2.0.0" + has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" @@ -1934,6 +2091,15 @@ http-cache-semantics@^4.0.0: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz#495704773277eeef6e43f9ab2c2c7d259dda25c5" integrity sha512-TcIMG3qeVLgDr1TEd2XvHaTnMPwYQUQMIBLy+5pLSDKYFc7UIqj39w8EGzZkaxoLv/l2K8HaI0t5AVA+YYgUew== +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + ignore-by-default@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" @@ -2252,7 +2418,7 @@ is-symbol@^1.0.2: dependencies: has-symbols "^1.0.0" -is-typedarray@^1.0.0: +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -2314,6 +2480,11 @@ isobject@^4.0.0: resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= + istanbul-lib-coverage@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#675f0ab69503fad4b1d849f736baaca803344f49" @@ -2376,7 +2547,7 @@ js-tokens@^4.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^3.10.0, js-yaml@^3.13.1: +js-yaml@^3.10.0, js-yaml@^3.11.0, js-yaml@^3.13.1: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== @@ -2384,6 +2555,11 @@ js-yaml@^3.10.0, js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= + jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -2404,7 +2580,17 @@ json-parse-better-errors@^1.0.1: resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== -json-stringify-safe@^5.0.1: +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= + +json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= @@ -2428,6 +2614,16 @@ jsonify@~0.0.0: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + just-extend@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.0.2.tgz#f3f47f7dfca0f989c55410a7ebc8854b07108afc" @@ -2478,6 +2674,11 @@ lcid@^2.0.0: dependencies: invert-kv "^2.0.0" +lcov-parse@^0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" + integrity sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM= + load-json-file@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" @@ -2558,6 +2759,11 @@ lodash@^4.17.11, lodash@^4.17.5: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== +log-driver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8" + integrity sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg== + log-symbols@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" @@ -2749,6 +2955,18 @@ micromatch@^4.0.2: braces "^3.0.1" picomatch "^2.0.5" +mime-db@1.40.0: + version "1.40.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.40.0.tgz#a65057e998db090f732a68f6c276d387d4126c32" + integrity sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA== + +mime-types@^2.1.12, mime-types@~2.1.19: + version "2.1.24" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.24.tgz#b6f8d0b3e951efb77dedeca194cff6d16f676f81" + integrity sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ== + dependencies: + mime-db "1.40.0" + mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" @@ -2971,6 +3189,11 @@ nyc@^14.1.1: yargs "^13.2.2" yargs-parser "^13.0.0" +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + object-assign@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -3255,6 +3478,11 @@ pathval@^1.1.0: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= + picomatch@^2.0.4, picomatch@^2.0.5: version "2.0.7" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6" @@ -3350,6 +3578,11 @@ pseudomap@^1.0.2: resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= +psl@^1.1.24: + version "1.1.33" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.33.tgz#5533d9384ca7aab86425198e10e8053ebfeab661" + integrity sha512-LTDP2uSrsc7XCb5lO7A8BI1qYxRe/8EqlRvMeEl6rsnYAqDOl8xHR+8lSAIVfrNaSAlTPTNOCgNjWcoUL3AZsw== + pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -3358,11 +3591,26 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" +punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + qs@^6.5.1: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== + quick-lru@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-1.1.0.tgz#4360b17c61136ad38078397ff11416e186dcfbb8" @@ -3521,6 +3769,32 @@ repeat-string@^1.6.1: resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= +request@^2.86.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -3615,7 +3889,7 @@ rimraf@^2.2.8, rimraf@^2.6.2, rimraf@^2.6.3: dependencies: glob "^7.1.3" -safe-buffer@^5.0.1, safe-buffer@~5.1.1: +safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== @@ -3627,6 +3901,11 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" +safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36" @@ -3850,6 +4129,21 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= +sshpk@^1.7.0: + version "1.16.1" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" + integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + bcrypt-pbkdf "^1.0.0" + dashdash "^1.12.0" + ecc-jsbn "~0.1.1" + getpass "^0.1.1" + jsbn "~0.1.0" + safer-buffer "^2.0.2" + tweetnacl "~0.14.0" + stack-utils@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.2.tgz#33eba3897788558bebfc2db059dc158ec36cebb8" @@ -4052,6 +4346,14 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" +tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ== + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + trim-newlines@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-2.0.0.tgz#b403d0b91be50c331dfc4b82eeceb22c3de16d20" @@ -4098,6 +4400,18 @@ tsutils@^2.29.0: dependencies: tslib "^1.8.1" +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0= + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= + type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" @@ -4223,6 +4537,13 @@ update-notifier@^3.0.0: semver-diff "^2.0.0" xdg-basedir "^3.0.0" +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" @@ -4260,6 +4581,15 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + wcwidth@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" From 5ce009b43c5964ffe706f6965eefdeba94d16f69 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Fri, 21 Jun 2019 18:49:44 +0200 Subject: [PATCH 19/35] Update package.json with beta version, types and files --- package.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 535e841..536f8ea 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "alfred-hugo", - "version": "2.0.0", + "version": "2.0.0-beta.0", "description": "Alfred workflow bindings for NodeJS", "author": "Maarten de Boer (https://cloudstek.nl)", "contributors": [ @@ -9,6 +9,10 @@ "repository": "Cloudstek/alfred-hugo", "bugs": "https://github.com/Cloudstek/alfred-hugo/issues", "main": "dist/main.js", + "types": "./dist/index.d.ts", + "files": [ + "/dist" + ], "keywords": [ "alfred", "workflow", From c2cec145055cca995aedc8649ac0678aac0ab587 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sun, 23 Jun 2019 15:16:10 +0200 Subject: [PATCH 20/35] Fix return type for alfredTheme --- src/hugo.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hugo.ts b/src/hugo.ts index 1224a68..f395dd5 100644 --- a/src/hugo.ts +++ b/src/hugo.ts @@ -152,7 +152,7 @@ export class Hugo { /** * Alfred theme */ - public get alfredTheme(): object { + public get alfredTheme(): any { const themeFile = this.alfredMeta.themeFile; if (!themeFile || utils.fileExists(themeFile) === false) { From cd1116123733f1e57eae7c39ae59d3c9d922ccdf Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sun, 23 Jun 2019 23:37:13 +0200 Subject: [PATCH 21/35] Fix invalid main entry in package.json --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 536f8ea..0184f43 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ ], "repository": "Cloudstek/alfred-hugo", "bugs": "https://github.com/Cloudstek/alfred-hugo/issues", - "main": "dist/main.js", + "main": "dist/index.js", "types": "./dist/index.d.ts", "files": [ "/dist" From 49681784903f25a1528d34636c4ff75cc358cd90 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sun, 23 Jun 2019 23:37:25 +0200 Subject: [PATCH 22/35] Fix tsconfig and tslint --- tsconfig.dist.json | 2 +- tsconfig.json | 2 +- tslint.json | 7 +++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/tsconfig.dist.json b/tsconfig.dist.json index 64f05d3..af41878 100644 --- a/tsconfig.dist.json +++ b/tsconfig.dist.json @@ -4,7 +4,7 @@ "declaration": true, "declarationMap": false, "sourceMap": false, - "outDir": "dist", + "outDir": "dist" }, "include": [ "src/**/*" diff --git a/tsconfig.json b/tsconfig.json index 0098e14..bda41fc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,7 @@ "declarationMap": false, "sourceMap": true, "esModuleInterop": true, - "outDir": "build", + "outDir": "build" }, "include": [ "src/**/*", diff --git a/tslint.json b/tslint.json index bb79f93..4159f2a 100644 --- a/tslint.json +++ b/tslint.json @@ -1,5 +1,4 @@ { - "defaultSeverity": "error", "extends": [ "tslint:recommended" ], @@ -9,7 +8,11 @@ "no-console": false, "interface-name": false, "ordered-imports": false, - "variable-name": false + "variable-name": false, + "max-line-length": { + "options": { "limit": 120 }, + "severity": "warning" + } }, "rulesDirectory": [] } From 450f22076e02c28e94cdf57f987a1e51f30a278a Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sun, 23 Jun 2019 23:38:39 +0200 Subject: [PATCH 23/35] Properly resolve alfred preferences and theme files --- src/hugo.ts | 28 +++++++++++++--------------- src/types/bplist.d.ts | 8 ++++++++ src/utils.ts | 39 +++++++++++++++++++++++++++++++++++---- 3 files changed, 56 insertions(+), 19 deletions(-) create mode 100644 src/types/bplist.d.ts diff --git a/src/hugo.ts b/src/hugo.ts index f395dd5..506e61d 100644 --- a/src/hugo.ts +++ b/src/hugo.ts @@ -1,13 +1,12 @@ -import { Cache } from "@cloudstek/cache"; -import { ICacheOptions } from "@cloudstek/cache"; import fs from "fs-extra"; import crypto from "crypto"; import Fuse from "fuse.js"; import Axios, { AxiosRequestConfig } from "axios"; import moment from "moment"; import path from "path"; -import Semver from "semver"; +import semver from "semver"; import NotificationCenter from "node-notifier/notifiers/notificationcenter"; +import { Cache, ICacheOptions } from "@cloudstek/cache"; import { Action } from "./action"; import { FileCache } from "./file-cache"; @@ -106,7 +105,7 @@ export class Hugo { * @return */ public get alfredMeta(): AlfredMeta { - let version = Semver.valid(Semver.coerce(process.env.alfred_version)); + let version = semver.valid(semver.coerce(process.env.alfred_version)); // Check if version is valid if (version === null) { @@ -120,7 +119,7 @@ export class Hugo { // Gather environment information const data: AlfredMeta = { debug: process.env.alfred_debug === "1", - preferences: process.env.alfred_preferences, + preferences: process.env.alfred_preferences || utils.resolveAlfredPrefs(version), preferencesLocalHash: process.env.alfred_preferences_localhash, theme: process.env.alfred_theme, themeBackground: process.env.alfred_theme_background, @@ -131,10 +130,7 @@ export class Hugo { // Find and load curent Alfred theme file if (process.env.HOME && data.theme) { - const homedir: string = process.env.HOME; - - const themeFile = path.resolve(homedir, "Library", "Application Support", "Alfred " + Semver.major(version), - "Alfred.alfredpreferences", "themes", data.theme, "theme.json"); + const themeFile = path.resolve(data.preferences, "themes", data.theme, "theme.json"); try { fs.statSync(themeFile); @@ -152,21 +148,23 @@ export class Hugo { /** * Alfred theme */ - public get alfredTheme(): any { + public get alfredTheme(): any | null { const themeFile = this.alfredMeta.themeFile; if (!themeFile || utils.fileExists(themeFile) === false) { - return {}; + return null; } - return fs.readJsonSync(themeFile); + const theme = fs.readJsonSync(themeFile); + + return theme.alfredtheme; } /** * Workflow metadata */ public get workflowMeta(): WorkflowMeta { - let version = Semver.valid(Semver.coerce(process.env.alfred_workflow_version)); + let version = semver.valid(semver.coerce(process.env.alfred_workflow_version)); // Check if version is valid if (version === null) { @@ -345,7 +343,7 @@ export class Hugo { * * @param notification Notification options */ - public async notify(notification: NotificationCenter.Notification) { + public async notify(notification: NotificationCenter.Notification): Promise { return new Promise((resolve, reject) => { const defaults: NotificationCenter.Notification = { contentImage: this.workflowMeta.icon, @@ -394,7 +392,7 @@ export class Hugo { } // Display notification - if (Semver.gt(latest, current)) { + if (semver.gt(latest, current)) { if (result.checkedOnline === true && this.options.updateNotification === true) { this.notify({ message: `Workflow version ${latest} available. Current version: ${current}.`, diff --git a/src/types/bplist.d.ts b/src/types/bplist.d.ts new file mode 100644 index 0000000..9c41ccc --- /dev/null +++ b/src/types/bplist.d.ts @@ -0,0 +1,8 @@ +declare module "bplist-parser" { + function parseFile(fileNameOrBuffer: string | Buffer, callback?: (error: Error, result: any) => void): any; + function parseBuffer(buffer: Buffer): any; +} + +declare module "bplist-creator" { + export default function(dicts: any): Buffer; +} diff --git a/src/utils.ts b/src/utils.ts index f19875e..0424a69 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,15 +1,46 @@ -import * as fs from "fs-extra"; +import fs from "fs-extra"; +import untildify from "untildify"; +import bplist from "bplist-parser"; +import semver from "semver"; /** * Check if file exists - * - * @param file */ export function fileExists(file: string): boolean { try { - fs.statSync(file); + fs.statSync(untildify(file)); return true; } catch (err) { return false; } } + +/** + * Resolve alfred prefrerences file path + */ +export function resolveAlfredPrefs(version: string | semver.SemVer): string | null { + if (typeof version === "string") { + version = semver.coerce(version); + } + + let plistPath = untildify("~/Library/Preferences/com.runningwithcrayons.Alfred-Preferences.plist"); + let settingsPath = untildify("~/Library/Application Support/Alfred"); + + if ((fileExists(plistPath) === false && version !== null) || version.major <= 3) { + plistPath = untildify(`~/Library/Preferences/com.runningwithcrayons.Alfred-Preferences-${version.major}.plist`); + settingsPath = untildify(`~/Library/Application Support/Alfred ${version.major}`); + + if (fileExists(plistPath) === false) { + throw new Error(`Alfred preferences not found at location ${plistPath}`); + } + } + + // Read settings file + const data = bplist.parseBuffer(fs.readFileSync(plistPath)); + + if (data && data[0] && data[0].syncfolder) { + settingsPath = untildify(data[0].syncfolder); + } + + return `${settingsPath}/Alfred.alfredpreferences`; +} From cd3ae30e0d6baf0232e37be196f344df2060074f Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sun, 23 Jun 2019 23:39:33 +0200 Subject: [PATCH 24/35] Strongly type file-cache event emitter --- src/file-cache.ts | 3 ++- src/types.ts | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/file-cache.ts b/src/file-cache.ts index f75cd0e..488359f 100644 --- a/src/file-cache.ts +++ b/src/file-cache.ts @@ -5,13 +5,14 @@ import { EventEmitter } from "events"; import fs from "fs-extra"; import * as utils from "./utils"; +import { FileCacheEventEmitter } from "./types"; /** * File cache. * * This allows you to read and process the data once, then storing it in cache until the file has changed again. */ -export class FileCache extends EventEmitter { +export class FileCache extends (EventEmitter as new() => FileCacheEventEmitter) { private filePath: string; private cache: Cache; diff --git a/src/types.ts b/src/types.ts index d130894..ba9b05f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,7 @@ import { Duration } from "moment"; +import StrictEventEmitter from "strict-event-emitter-types"; +import { EventEmitter } from "events"; +import { Cache } from "@cloudstek/cache"; export enum IconType { fileIcon = "fileicon", @@ -98,3 +101,9 @@ export interface LatestVersion { url: string; checkedOnline: boolean; } + +export interface FileCacheEvents { + change: (cache: Cache, file: string) => void; +} + +export type FileCacheEventEmitter = StrictEventEmitter; From b20ffcfe27adf120d2379416c9158278a09d92e7 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sun, 23 Jun 2019 23:39:42 +0200 Subject: [PATCH 25/35] Update tests --- test/helpers/init.ts | 5 +- test/meta/alfred.ts | 9 ++- test/meta/theme.ts | 18 ++--- test/utils.ts | 184 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 201 insertions(+), 15 deletions(-) create mode 100644 test/utils.ts diff --git a/test/helpers/init.ts b/test/helpers/init.ts index 133e2c7..5815543 100644 --- a/test/helpers/init.ts +++ b/test/helpers/init.ts @@ -1,7 +1,6 @@ import { Cache } from "@cloudstek/cache"; import crypto from "crypto"; import path from "path"; -import os from "os"; import moment from "moment"; import fs from "fs-extra"; import nock from "nock"; @@ -10,13 +9,15 @@ import sinon from "sinon"; import { Updater, Hugo, HugoOptions } from "../../src"; export function setAlfredEnv() { - process.env.alfred_version = "3.0.0"; + process.env.alfred_version = "4.0.0"; process.env.alfred_workflow_version = "1.0.0"; process.env.alfred_workflow_bundleid = "my.work.flow"; + process.env.alfred_preferences = path.join("build", "cache", crypto.randomBytes(8).toString("hex")); process.env.alfred_workflow_data = path.join("build", "cache", crypto.randomBytes(8).toString("hex")); process.env.alfred_workflow_cache = path.join("build", "cache", crypto.randomBytes(8).toString("hex")); process.env.alfred_debug = "0"; + fs.ensureDirSync(process.env.alfred_preferences); fs.ensureDirSync(process.env.alfred_workflow_data); fs.ensureDirSync(process.env.alfred_workflow_cache); diff --git a/test/meta/alfred.ts b/test/meta/alfred.ts index d7af0e9..3f69d96 100644 --- a/test/meta/alfred.ts +++ b/test/meta/alfred.ts @@ -80,14 +80,15 @@ test.serial("invalid version", (t) => { test.serial("existing theme", (t) => { const h = hugo(); - process.env.alfred_theme = "default"; + process.env.alfred_theme = "foo"; - const themeFilePath = path.resolve(process.env.HOME, "Library", "Application Support", "Alfred 3", - "Alfred.alfredpreferences", "themes", process.env.alfred_theme, "theme.json"); + const themeFilePath = path.resolve(process.env.alfred_preferences, "themes", process.env.alfred_theme, "theme.json"); fs.ensureFileSync(themeFilePath); fs.writeJsonSync(themeFilePath, { - foo: "bar", + alfredtheme: { + foo: "bar", + }, }); t.is(typeof h.alfredMeta, "object"); diff --git a/test/meta/theme.ts b/test/meta/theme.ts index 4032214..d97fd0d 100644 --- a/test/meta/theme.ts +++ b/test/meta/theme.ts @@ -4,17 +4,18 @@ import path from "path"; import { hugo } from "../helpers/init"; -test("existing theme", (t) => { +test.serial("existing theme", (t) => { const h = hugo(); - process.env.alfred_theme = "default"; + process.env.alfred_theme = "foo"; - const themeFilePath = path.resolve(process.env.HOME, "Library", "Application Support", "Alfred 3", - "Alfred.alfredpreferences", "themes", process.env.alfred_theme, "theme.json"); + const themeFilePath = path.resolve(process.env.alfred_preferences, "themes", process.env.alfred_theme, "theme.json"); fs.ensureFileSync(themeFilePath); fs.writeJsonSync(themeFilePath, { - foo: "bar", + alfredtheme: { + foo: "bar", + }, }); t.is(typeof h.alfredTheme, "object"); @@ -23,12 +24,11 @@ test("existing theme", (t) => { }); }); -test("non-existing theme", (t) => { +test.serial("non-existing theme", (t) => { const h = hugo(); // Valid theme name but directory doesn't exist. - process.env.alfred_theme = "default"; + process.env.alfred_theme = "foo"; - t.is(typeof h.alfredTheme, "object"); - t.deepEqual(h.alfredTheme, {}); + t.is(h.alfredTheme, null); }); diff --git a/test/utils.ts b/test/utils.ts new file mode 100644 index 0000000..e39a7e1 --- /dev/null +++ b/test/utils.ts @@ -0,0 +1,184 @@ +import test from "ava"; +import os from "os"; +import path from "path"; +import fs from "fs-extra"; +import crypto from "crypto"; +import sinon from "sinon"; +import bplist from "bplist-creator"; +import semver from "semver"; + +// Stub home directory +const homeDir = path.resolve("build", "cache", crypto.randomBytes(8).toString("hex")); +sinon.stub(os, "homedir").returns(homeDir); + +import * as utils from "../src/utils"; + +test.serial("resolve alfred 3 preferences", (t) => { + // Write new binary plist + const plist = bplist({}); + + // Write file to expected path + const plistPath = path.join(homeDir, "/Library/Preferences/com.runningwithcrayons.Alfred-Preferences-3.plist"); + + fs.ensureFileSync(plistPath); + fs.writeFileSync(plistPath, plist); + + // Resolve preferences file + const p = utils.resolveAlfredPrefs("3.0.0"); + const pSemver = utils.resolveAlfredPrefs(semver.parse("3.0.0")); + + t.is(p, path.join(homeDir, "Library/Application Support/Alfred 3/Alfred.alfredpreferences")); + t.is(pSemver, p); +}); + +test.serial("resolve alfred 4 preferences", (t) => { + // Write new binary plist + const plist = bplist({}); + + // Write file to expected path + const plistPath = path.join(homeDir, "/Library/Preferences/com.runningwithcrayons.Alfred-Preferences.plist"); + + fs.ensureFileSync(plistPath); + fs.writeFileSync(plistPath, plist); + + // Resolve preferences file + const p = utils.resolveAlfredPrefs("4.0.0"); + const pSemver = utils.resolveAlfredPrefs(semver.parse("4.0.0")); + + t.is(p, path.join(homeDir, "Library/Application Support/Alfred/Alfred.alfredpreferences")); + t.is(pSemver, p); +}); + +test.serial("resolve randomly versioned preferences", (t) => { + // Write new binary plist + const plist = bplist({}); + + const major = Math.floor(Math.random() * (15 - 5)) + 5; + const version = `${major}.0.0`; + + t.log(`Using version: ${version}`); + + // Write file to expected path + const plistPath = path.join(homeDir, `/Library/Preferences/com.runningwithcrayons.Alfred-Preferences-${major}.plist`); + + fs.ensureFileSync(plistPath); + fs.writeFileSync(plistPath, plist); + + // Resolve preferences file + const p = utils.resolveAlfredPrefs(version); + const pSemver = utils.resolveAlfredPrefs(semver.parse(version)); + + t.is(p, path.join(homeDir, `Library/Application Support/Alfred ${major}/Alfred.alfredpreferences`)); + t.is(pSemver, p); +}); + +test.serial("prefer unversioned preferences over versioned preferences", (t) => { + // Write new binary plist + const plist = bplist({}); + + // Write file to expected path + const plist3Path = path.join(homeDir, "/Library/Preferences/com.runningwithcrayons.Alfred-Preferences-3.plist"); + const plist4Path = path.join(homeDir, "/Library/Preferences/com.runningwithcrayons.Alfred-Preferences.plist"); + + fs.ensureFileSync(plist3Path); + fs.writeFileSync(plist3Path, plist); + + fs.ensureFileSync(plist4Path); + fs.writeFileSync(plist4Path, plist); + + // Resolve preferences file + const p = utils.resolveAlfredPrefs("4.0.0"); + const pSemver = utils.resolveAlfredPrefs(semver.parse("4.0.0")); + + t.is(p, path.join(homeDir, "Library/Application Support/Alfred/Alfred.alfredpreferences")); + t.is(pSemver, p); +}); + +test.serial("resolve synced alfred 3 preferences", (t) => { + // Write new binary plist + const plist = bplist({ + syncfolder: "~/Dropbox", + }); + + // Write file to expected path + const plistPath = path.join(homeDir, "/Library/Preferences/com.runningwithcrayons.Alfred-Preferences-3.plist"); + + fs.ensureFileSync(plistPath); + fs.writeFileSync(plistPath, plist); + + // Resolve preferences file + const p = utils.resolveAlfredPrefs("3.0.0"); + const pSemver = utils.resolveAlfredPrefs(semver.parse("3.0.0")); + + t.is(p, path.join(homeDir, "Dropbox/Alfred.alfredpreferences")); + t.is(pSemver, p); +}); + +test("resolve synced alfred 4 preferences", (t) => { + // Write new binary plist + const plist = bplist({ + syncfolder: "~/Dropbox", + }); + + // Write file to expected path + const plistPath = path.join(homeDir, "/Library/Preferences/com.runningwithcrayons.Alfred-Preferences.plist"); + + fs.ensureFileSync(plistPath); + fs.writeFileSync(plistPath, plist); + + // Resolve preferences file + const p = utils.resolveAlfredPrefs("4.0.0"); + const pSemver = utils.resolveAlfredPrefs(semver.parse("4.0.0")); + + t.is(p, path.join(homeDir, "Dropbox/Alfred.alfredpreferences")); + t.is(pSemver, p); +}); + +test.serial("resolve randomly versioned synced preferences", (t) => { + // Write new binary plist + const plist = bplist({ + syncfolder: "~/Dropbox", + }); + + const major = Math.floor(Math.random() * (15 - 5)) + 5; + const version = `${major}.0.0`; + + t.log(`Using version: ${version}`); + + // Write file to expected path + const plistPath = path.join(homeDir, `/Library/Preferences/com.runningwithcrayons.Alfred-Preferences-${major}.plist`); + + fs.ensureFileSync(plistPath); + fs.writeFileSync(plistPath, plist); + + // Resolve preferences file + const p = utils.resolveAlfredPrefs(version); + const pSemver = utils.resolveAlfredPrefs(semver.parse(version)); + + t.is(p, path.join(homeDir, "Dropbox/Alfred.alfredpreferences")); + t.is(pSemver, p); +}); + +test.serial("resolve non-existing alfred 3 preferences", (t) => { + // Write new binary plist + const plist = bplist({}); + + // Write alfred 4 preferences file + const plistPath = path.join(homeDir, "/Library/Preferences/com.runningwithcrayons.Alfred-Preferences.plist"); + + fs.ensureFileSync(plistPath); + fs.writeFileSync(plistPath, plist); + + // Resolve preferences file for alfred 3 + t.throws(() => { + utils.resolveAlfredPrefs("3.0.0"); + }); + + t.throws(() => { + utils.resolveAlfredPrefs(semver.parse("3.0.0")); + }); +}); + +test.afterEach.always(() => { + fs.removeSync(homeDir); +}); From 62f1906aa63081b7b6294cb3fa90a080d4778b1b Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sun, 23 Jun 2019 23:44:26 +0200 Subject: [PATCH 26/35] Update dependencies --- package.json | 8 ++- yarn.lock | 187 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 126 insertions(+), 69 deletions(-) diff --git a/package.json b/package.json index 0184f43..2aada5a 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "@types/semver": "^6.0.0", "@types/sinon": "^7.0.12", "ava": "^2.0.0", + "bplist-creator": "^0.0.8", "coveralls": "^3.0.4", "del-cli": "^2.0.0", "mockdate": "^2.0.2", @@ -42,19 +43,22 @@ "npm-run-all": "^4.1.5", "nyc": "^14.1.1", "sinon": "^7.3.2", - "tslint": "^5.16.0", + "strict-event-emitter-types": "^2.0.0", + "tslint": "^5.18.0", "typescript": "^3.4.5" }, "dependencies": { "@cloudstek/cache": "^1.0.1", "alfred-link": "^0.3.0", "axios": "^0.19.0", + "bplist-parser": "^0.1.1", "fs-extra": "^8.0.1", "fuse.js": "^3.4.4", "moment": "^2.17.1", "node-notifier": "^5.0.2", "read-pkg": "^5.1.1", - "semver": "^6.1.0" + "semver": "^6.1.0", + "untildify": "^4.0.0" }, "engines": { "node": ">=8" diff --git a/yarn.lock b/yarn.lock index ef79e4e..5ff9dd7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -314,9 +314,9 @@ "@sinonjs/samsam" "^3.1.0" "@sinonjs/samsam@^3.1.0", "@sinonjs/samsam@^3.3.1": - version "3.3.1" - resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-3.3.1.tgz#e88c53fbd9d91ad9f0f2b0140c16c7c107fe0d07" - integrity sha512-wRSfmyd81swH0hA1bxJZJ57xr22kC07a1N4zuIL47yTS04bDk6AoCkczcqHEjcRPmJ+FruGJ9WBQiJwMtIElFw== + version "3.3.2" + resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-3.3.2.tgz#63942e3d5eb0b79f6de3bef9abfad15fb4b6401b" + integrity sha512-ILO/rR8LfAb60Y1Yfp9vxfYAASK43NFC2mLzpvLUbCQY/Qu8YwReboseu8aheCEkyElZF2L2T9mHcR2bgdvZyA== dependencies: "@sinonjs/commons" "^1.0.2" array-from "^2.1.1" @@ -356,9 +356,9 @@ "@types/node" "*" "@types/got@^9.4.4": - version "9.4.4" - resolved "https://registry.yarnpkg.com/@types/got/-/got-9.4.4.tgz#78129553f6a41715df601db43532cd0b87a55d3f" - integrity sha512-IGAJokJRE9zNoBdY5csIwN4U5qQn+20HxC0kM+BbUdfTKIXa7bOX/pdhy23NnLBRP8Wvyhx7X5e6EHJs+4d8HA== + version "9.6.0" + resolved "https://registry.yarnpkg.com/@types/got/-/got-9.6.0.tgz#bba73ff0a46b2691ddb3d86e89f8b2f43ebb829d" + integrity sha512-t00QebxBllcawe7uMxi9jsfWfbki4+/zpJEPyoGWjUvnFOy4EkAzoYOI2UJt2+Fx0yIcDX2+us93k6ensKTddA== dependencies: "@types/node" "*" "@types/tough-cookie" "*" @@ -388,9 +388,9 @@ "@types/node" "*" "@types/node@*", "@types/node@^12.0.2": - version "12.0.7" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.7.tgz#4f2563bad652b2acb1722d7e7aae2b0ff62d192c" - integrity sha512-1YKeT4JitGgE4SOzyB9eMwO0nGVNkNEsm9qlIt1Lqm/tG2QEiSMTD4kS3aO6L+w5SClLVxALmIBESK6Mk5wX0A== + version "12.0.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.0.10.tgz#51babf9c7deadd5343620055fc8aff7995c8b031" + integrity sha512-LcsGbPomWsad6wmMNv7nBLw7YYYyfdYcz6xryKYQhx89c3XXan+8Q6AJ43G5XDIaklaVkK3mE4fCb0SBvMiPSQ== "@types/normalize-package-data@*", "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -405,14 +405,14 @@ "@types/normalize-package-data" "*" "@types/semver@^6.0.0": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-6.0.0.tgz#86ba89f02a414e39c68d02b351872e4ed31bd773" - integrity sha512-OO0srjOGH99a4LUN2its3+r6CBYcplhJ466yLqs+zvAWgphCpS8hYZEZ797tRDP/QKcqTdb/YCN6ifASoAWkrQ== + version "6.0.1" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-6.0.1.tgz#a984b405c702fa5a7ec6abc56b37f2ba35ef5af6" + integrity sha512-ffCdcrEE5h8DqVxinQjo+2d1q+FV5z7iNtPofw3JsrltSoSVlOGaW0rY8XxtO9XukdTn8TaCGWmk2VFGhI70mg== "@types/sinon@^7.0.12": - version "7.0.12" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-7.0.12.tgz#18412939ae45b225bd38715a25c1040cbad80f42" - integrity sha512-fo0MWpVPSUrnZZhp9wyu+hhI3VJ9+Jhs+PWrokBTg3d2ryNPDOAWF1csIhQuYWBTn7KdZzXpRgpX2o6cwOlPWg== + version "7.0.13" + resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-7.0.13.tgz#ca039c23a9e27ebea53e0901ef928ea2a1a6d313" + integrity sha512-d7c/C/+H/knZ3L8/cxhicHUiTDxdgap0b/aNJfsmLwFu/iOP17mdgbQsbHA3SJmrzsjD0l3UEE5SN4xxuz5ung== "@types/tough-cookie@*": version "2.3.5" @@ -452,11 +452,11 @@ ansi-align@^3.0.0: string-width "^3.0.0" ansi-escapes@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.1.0.tgz#62a9e5fa78e99c5bb588b1796855f5d729231b53" - integrity sha512-2VY/iCUZTDLD/qxptS3Zn3c6k2MeIbYqjRXqM8T5oC7N2mMjh3xIU3oYru6cHGbldFa9h5i8N0fP65UaUqrMWA== + version "4.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.2.0.tgz#c38600259cefba178ee3f7166c5ea3a5dd2e88fc" + integrity sha512-0+VX4uhi8m3aNbzoqKmkAVOEj6uQzcUHXoFPkKjhZPTpGRUBqVh930KbB6PS4zIyDZccphlLIYlu8nsjFzkXwg== dependencies: - type-fest "^0.3.0" + type-fest "^0.5.2" ansi-regex@^2.0.0: version "2.1.1" @@ -634,9 +634,9 @@ atob@^2.1.1: integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== ava@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ava/-/ava-2.0.0.tgz#265f9a094f83d0a78c05654e37302645d59ca1fa" - integrity sha512-tOfO3yQhKiSECIjST8Xi99l7Bja9EG5hgZFKc92xNZh/6pnct97vWDKENyATBvZIXpdCClSMtGgOX2UaGq+OJA== + version "2.1.0" + resolved "https://registry.yarnpkg.com/ava/-/ava-2.1.0.tgz#158c5cdf48d1556caf0a9fdf96b61af9e566c153" + integrity sha512-IaS+l1KfYtFpJlDZXrNG0M6SGr/DUvwJmTiaTaW2lMdEezCAJc5J/hNAQWIKigkmxIOURYT29atD/qyp+zq+wg== dependencies: "@ava/babel-preset-stage-4" "^3.0.0" "@ava/babel-preset-transform-test-files" "^5.0.0" @@ -654,7 +654,7 @@ ava@^2.0.0: arrify "^2.0.1" bluebird "^3.5.5" chalk "^2.4.2" - chokidar "^3.0.0" + chokidar "^3.0.1" chunkd "^1.0.0" ci-parallel-vars "^1.0.0" clean-stack "^2.1.0" @@ -668,7 +668,7 @@ ava@^2.0.0: currently-unhandled "^0.4.1" debug "^4.1.1" del "^4.1.1" - dot-prop "^5.0.0" + dot-prop "^5.0.1" emittery "^0.4.1" empower-core "^1.2.0" equal-length "^1.0.0" @@ -693,7 +693,7 @@ ava@^2.0.0: md5-hex "^3.0.0" meow "^5.0.0" micromatch "^4.0.2" - ms "^2.1.1" + ms "^2.1.2" observable-to-promise "^1.0.0" ora "^3.4.0" package-hash "^4.0.0" @@ -777,9 +777,9 @@ bcrypt-pbkdf@^1.0.0: tweetnacl "^0.14.3" big-integer@^1.6.7: - version "1.6.43" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.43.tgz#8ac15bf13e93e509500859061233e19d8d0d99d1" - integrity sha512-9dULc9jsKmXl0Aeunug8wbF+58n+hQoFjqClN7WeZwGLh0XJUWyJJ9Ee+Ep+Ql/J9fRsTVaeThp8MhiCCrY0Jg== + version "1.6.44" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.44.tgz#4ee9ae5f5839fc11ade338fea216b4513454a539" + integrity sha512-7MzElZPTyJ2fNvBkPxtFQ2fWIkVmuzw41+BZHSzpEq3ymB2MfeKp1+yXl/tS75xCx+WnyV+yb0kp+K1C3UNwmQ== binary-extensions@^2.0.0: version "2.0.0" @@ -805,6 +805,13 @@ boxen@^3.0.0: type-fest "^0.3.0" widest-line "^2.0.0" +bplist-creator@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/bplist-creator/-/bplist-creator-0.0.8.tgz#56b2a6e79e9aec3fc33bf831d09347d73794e79c" + integrity sha512-Za9JKzD6fjLC16oX2wsXfc+qBEhJBJB1YPInoAQpMLhDuj5aVOv1baGeIQSq1Fr3OCqzvsoQcSBSwGId/Ja2PA== + dependencies: + stream-buffers "~2.2.0" + bplist-parser@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.1.1.tgz#d60d5dcc20cba6dc7e1f299b35d3e1f95dafbae6" @@ -972,7 +979,7 @@ check-error@^1.0.2: resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= -chokidar@^3.0.0: +chokidar@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.0.1.tgz#98fe9aa476c55d9aea7841d6325ffdb30e95b40c" integrity sha512-2ww34sJWehnbpV0Q4k4V5Hh7juo7po6z7LUWkcIQnSGN1lHOL8GGtLtfwabKvLFQw/hbSUQ0u6V7OgGYgBzlkQ== @@ -1036,11 +1043,11 @@ cli-cursor@^2.1.0: restore-cursor "^2.0.0" cli-cursor@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.0.0.tgz#f6cc68b8ae372a18894e59fbf2ae3bd659731c15" - integrity sha512-m7avcYLWHHQVU+cFxu301q3kKZJlcZcKXQSL9kffYnIvRNtqX+a7gJKXqOKusHoKXr4oquSgiMlAo1R0dDkSZA== + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== dependencies: - restore-cursor "^2.0.0" + restore-cursor "^3.1.0" cli-spinners@^2.0.0: version "2.1.0" @@ -1449,12 +1456,12 @@ dot-prop@^4.1.0: dependencies: is-obj "^1.0.0" -dot-prop@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.0.1.tgz#e26c283bd1f10aab01e782371a751fb52cc3cb1c" - integrity sha512-5BKAm3KC6kgHOm5WqekMXd0HHRhilE0aJzBuOqtrPo2RDS2FTaOeuF5CEsHvZ8ETfjC9N3BufL6sxEMV8w/IIA== +dot-prop@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.1.0.tgz#bdd8c986a77b83e3fca524e53786df916cabbd8a" + integrity sha512-n1oC6NBF+KM9oVXtjmen4Yo7HyAVWV2UUl50dCYJdw2924K6dX9bf9TTTWaKtYlRn0FEtxG27KS80ayVLixxJA== dependencies: - is-obj "^1.0.0" + is-obj "^2.0.0" duplexer3@^0.1.4: version "0.1.4" @@ -1745,11 +1752,12 @@ find-up@^3.0.0: locate-path "^3.0.0" find-up@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.0.0.tgz#c367f8024de92efb75f2d4906536d24682065c3a" - integrity sha512-zoH7ZWPkRdgwYCDVoQTzqjG8JSPANhtvLhh4KVUHyKnaUJJrNeFmWIkTcNuJmR3GLMEmGYEf2S2bjgx26JTF+Q== + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== dependencies: locate-path "^5.0.0" + path-exists "^4.0.0" follow-redirects@1.5.10: version "1.5.10" @@ -2147,9 +2155,9 @@ inflight@^1.0.4: wrappy "1" inherits@2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== ini@^1.3.4, ini@~1.3.0: version "1.3.5" @@ -2327,6 +2335,11 @@ is-obj@^1.0.0: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" integrity sha1-PkcprB9f3gJc19g6iW2rn09n2w8= +is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== + is-observable@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-2.0.0.tgz#327af1e8cdea9cd717f95911b87c5d34301721a6" @@ -2972,7 +2985,7 @@ mimic-fn@^1.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== -mimic-fn@^2.0.0: +mimic-fn@^2.0.0, mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== @@ -3028,9 +3041,9 @@ mkdirp@^0.5.0, mkdirp@^0.5.1: minimist "0.0.8" mockdate@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/mockdate/-/mockdate-2.0.2.tgz#5ae0c0eaf8fe23e009cd01f9889b42c4f634af12" - integrity sha1-WuDA6vj+I+AJzQH5iJtCxPY0rxI= + version "2.0.3" + resolved "https://registry.yarnpkg.com/mockdate/-/mockdate-2.0.3.tgz#f4095e5eaea94c5f8b4e0e708f5d79fdff846a66" + integrity sha512-/wRyr3grWk3tyk188qjZpeiiAfkAoDPEGqyerretomeeaH0D+pN9MCcedhAwrkxX3a216gp8CwPeQMHfLvrFpA== moment@^2.17.1, moment@^2.24.0: version "2.24.0" @@ -3042,7 +3055,7 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@^2.1.1: +ms@^2.1.1, ms@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== @@ -3249,6 +3262,13 @@ onetime@^2.0.0: dependencies: mimic-fn "^1.0.0" +onetime@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.0.tgz#fff0f3c91617fe62bb50189636e99ac8a6df7be5" + integrity sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q== + dependencies: + mimic-fn "^2.1.0" + optimist@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" @@ -3379,14 +3399,14 @@ package-hash@^4.0.0: release-zalgo "^1.0.0" package-json@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.3.0.tgz#5ed793418b8322af7abfb985a19a20c2f40c2fb0" - integrity sha512-XO7WS3EEXd48vmW633Y97Mh9xuENFiOevI9G+ExfTG/k6xuY9cBd3fxkAoDMSEsNZXasaVJIJ1rD/n7GMf18bA== + version "6.4.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.4.0.tgz#4f626976604f4a9a41723ce1792b204a60b1b61e" + integrity sha512-bd1T8OBG7hcvMd9c/udgv6u5v9wISP3Oyl9Cm7Weop8EFwrtcQDnS2sb6zhwqus2WslSr5wSTIPiTTpxxmPm7Q== dependencies: got "^9.6.0" registry-auth-token "^3.4.0" registry-url "^5.0.0" - semver "^5.6.0" + semver "^6.1.1" parse-json@^2.2.0: version "2.2.0" @@ -3430,6 +3450,11 @@ path-exists@^3.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + path-is-absolute@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -3877,6 +3902,14 @@ restore-cursor@^2.0.0: onetime "^2.0.0" signal-exit "^3.0.2" +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + ret@~0.1.10: version "0.1.15" resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" @@ -3918,7 +3951,7 @@ semver-diff@^2.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== -semver@^6.0.0, semver@^6.1.0: +semver@^6.0.0, semver@^6.1.0, semver@^6.1.1: version "6.1.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.1.1.tgz#53f53da9b30b2103cd4f15eab3a18ecbcb210c9b" integrity sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ== @@ -4157,6 +4190,16 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" +stream-buffers@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4" + integrity sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ= + +strict-event-emitter-types@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz#05e15549cb4da1694478a53543e4e2f4abcf277f" + integrity sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA== + string-width@^2.0.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" @@ -4370,14 +4413,14 @@ trim-right@^1.0.1: integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= tslib@^1.8.0, tslib@^1.8.1: - version "1.9.3" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" - integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== -tslint@^5.16.0: - version "5.17.0" - resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.17.0.tgz#f9f0ce2011d8e90debaa6e9b4975f24cd16852b8" - integrity sha512-pflx87WfVoYepTet3xLfDOLDm9Jqi61UXIKePOuca0qoAZyrGWonDG9VTbji58Fy+8gciUn8Bt7y69+KEVjc/w== +tslint@^5.18.0: + version "5.18.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.18.0.tgz#f61a6ddcf372344ac5e41708095bbf043a147ac6" + integrity sha512-Q3kXkuDEijQ37nXZZLKErssQVnwCV/+23gFEMROi8IlbaBG6tXqLPQJ5Wjcyt/yHPKBC+hD5SzuGaMora+ZS6w== dependencies: "@babel/code-frame" "^7.0.0" builtin-modules "^1.1.1" @@ -4427,6 +4470,11 @@ type-fest@^0.4.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8" integrity sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw== +type-fest@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.5.2.tgz#d6ef42a0356c6cd45f49485c3b6281fc148e48a2" + integrity sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw== + typedarray-to-buffer@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" @@ -4435,9 +4483,9 @@ typedarray-to-buffer@^3.1.5: is-typedarray "^1.0.0" typescript@^3.4.5: - version "3.5.1" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.1.tgz#ba72a6a600b2158139c5dd8850f700e231464202" - integrity sha512-64HkdiRv1yYZsSe4xC1WVgamNigVYjlssIoaH2HcZF0+ijsk5YK2g0G34w9wJkze8+5ow4STd22AynfO6ZYYLw== + version "3.5.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.2.tgz#a09e1dc69bc9551cadf17dba10ee42cf55e5d56c" + integrity sha512-7KxJovlYhTX5RaRbUdkAXN1KUZ8PwWlTzQdHV6xNqvuFOs7+WBo10TQUqT19Q/Jz2hk5v9TQDIhyLhhJY4p5AA== uglify-js@^3.1.4: version "3.6.0" @@ -4519,6 +4567,11 @@ untildify@^3.0.2: resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.3.tgz#1e7b42b140bcfd922b22e70ca1265bfe3634c7c9" integrity sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA== +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + update-notifier@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-3.0.0.tgz#e9bbf8f0f5b7a2ce6666ca46334fdb29492e8fab" @@ -4697,9 +4750,9 @@ yargs-parser@^10.0.0: camelcase "^4.1.0" yargs-parser@^13.0.0, yargs-parser@^13.1.0: - version "13.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.0.tgz#7016b6dd03e28e1418a510e258be4bff5a31138f" - integrity sha512-Yq+32PrijHRri0vVKQEm+ys8mbqWjLiwQkMFNXEENutzLPP0bE4Lcd4iA3OQY5HF+GD3xXxf0MEHb8E4/SA3AA== + version "13.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" + integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== dependencies: camelcase "^5.0.0" decamelize "^1.2.0" From 17853050d01be7bfc269a8b33b46466b3097fed2 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sun, 23 Jun 2019 23:44:41 +0200 Subject: [PATCH 27/35] Fix forwardTime utility in tests --- test/helpers/mock.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/helpers/mock.ts b/test/helpers/mock.ts index 42ff560..3c919fb 100644 --- a/test/helpers/mock.ts +++ b/test/helpers/mock.ts @@ -12,7 +12,7 @@ export function date() { } export function forwardTime(amount?: DurationInputArg1, unit?: DurationInputArg2) { - mockdate.set(moment.utc().add(amount, unit)); + mockdate.set(moment.utc().add(amount, unit).toDate()); } export function npm(times: number, pkg?: any, code: number = 200, latestVersion?: string) { From 198f90ce0afa42457a5c4df0d666f86e84e8c959 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sun, 23 Jun 2019 23:46:30 +0200 Subject: [PATCH 28/35] Release beta 2.0.0 beta 1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2aada5a..f31278b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "alfred-hugo", - "version": "2.0.0-beta.0", + "version": "2.0.0-beta.1", "description": "Alfred workflow bindings for NodeJS", "author": "Maarten de Boer (https://cloudstek.nl)", "contributors": [ From 13a388a4fe2a3ea3398b04564ea428c2f98d617a Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sun, 23 Jun 2019 23:57:45 +0200 Subject: [PATCH 29/35] Update README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9cc1fc8..440c1df 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # ![Hugo](https://cdn.rawgit.com/cloudstek/alfred-hugo/master/media/logo-hugo.svg) -![CircleCI](https://img.shields.io/circleci/build/github/Cloudstek/alfred-hugo.svg) [![Coverage Status](https://coveralls.io/repos/github/Cloudstek/alfred-hugo/badge.svg?branch=master)](https://coveralls.io/github/Cloudstek/alfred-hugo?branch=master) [![Open Issues](https://img.shields.io/github/issues/Cloudstek/alfred-hugo.svg)](https://github.com/Cloudstek/alfred-hugo/issues) ![npm](https://img.shields.io/npm/dt/alfred-hugo.svg) ![GitHub](https://img.shields.io/github/license/Cloudstek/alfred-hugo.svg) ![GitHub stars](https://img.shields.io/github/stars/Cloudstek/alfred-hugo.svg) +[![CircleCI](https://img.shields.io/circleci/build/github/Cloudstek/alfred-hugo.svg)](https://circleci.com/gh/Cloudstek/alfred-hugo) [![Coverage Status](https://coveralls.io/repos/github/Cloudstek/alfred-hugo/badge.svg?branch=master)](https://coveralls.io/github/Cloudstek/alfred-hugo?branch=master) [![Open Issues](https://img.shields.io/github/issues/Cloudstek/alfred-hugo.svg)](https://github.com/Cloudstek/alfred-hugo/issues) ![npm](https://img.shields.io/npm/dt/alfred-hugo.svg) ![GitHub](https://img.shields.io/github/license/Cloudstek/alfred-hugo.svg) ![GitHub stars](https://img.shields.io/github/stars/Cloudstek/alfred-hugo.svg) Hugo is a [script filter](https://www.alfredapp.com/help/workflows/inputs/script-filter/) framework for your Alfred workflows. It can handle fetching and caching data, configuration storage, checking for updates and much much more. But I suppose you can use it for other purposes in your workflow as well :man_shrugging: @@ -18,7 +18,7 @@ Hugo is a [script filter](https://www.alfredapp.com/help/workflows/inputs/script ### Prerequisites * NodeJS 8 or higher -* Alfred 3.4.1+ with [paid powerpack addon](https://www.alfredapp.com/powerpack/buy/) +* Alfred 4 with [paid powerpack addon](https://www.alfredapp.com/powerpack/buy/) ### Installing From cc7987b0b0f9c17744a9973045ee7f4ffe8760f8 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Sun, 23 Jun 2019 23:58:05 +0200 Subject: [PATCH 30/35] Fix missing strict-event-emitter-types --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f31278b..0e5d77a 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,6 @@ "npm-run-all": "^4.1.5", "nyc": "^14.1.1", "sinon": "^7.3.2", - "strict-event-emitter-types": "^2.0.0", "tslint": "^5.18.0", "typescript": "^3.4.5" }, @@ -58,6 +57,7 @@ "node-notifier": "^5.0.2", "read-pkg": "^5.1.1", "semver": "^6.1.0", + "strict-event-emitter-types": "^2.0.0", "untildify": "^4.0.0" }, "engines": { From 9ae6953277a503ba795b2731952623e5f31570d8 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Mon, 24 Jun 2019 02:17:36 +0200 Subject: [PATCH 31/35] Add own implementation of alfred-link and alfred-unlink The alfred-link and alfred-unlink implementation does not work with Alfred 4 and has yet to be updated. This commit includes my own implementation which works with either version. --- package.json | 14 ++- src/bin/link.ts | 53 +++++++++ src/bin/unlink.ts | 47 ++++++++ src/types/plist.d.ts | 4 + yarn.lock | 266 +++++-------------------------------------- 5 files changed, 145 insertions(+), 239 deletions(-) create mode 100644 src/bin/link.ts create mode 100644 src/bin/unlink.ts create mode 100644 src/types/plist.d.ts diff --git a/package.json b/package.json index 0e5d77a..c8fc431 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,10 @@ "files": [ "/dist" ], + "bin": { + "hugo-link": "./dist/bin/link.js", + "hugo-unlink": "./dist/bin/unlink.js" + }, "keywords": [ "alfred", "workflow", @@ -26,11 +30,10 @@ "license": "BSD-2-Clause", "devDependencies": { "@types/fs-extra": "^7.0.0", - "@types/got": "^9.4.4", + "@types/glob": "^7.1.1", "@types/mockdate": "^2.0.0", "@types/nock": "^10.0.3", "@types/node": "^12.0.2", - "@types/node-notifier": "^5.4.0", "@types/read-pkg": "^4.0.0", "@types/semver": "^6.0.0", "@types/sinon": "^7.0.12", @@ -47,15 +50,18 @@ "typescript": "^3.4.5" }, "dependencies": { + "@types/node-notifier": "^5.4.0", "@cloudstek/cache": "^1.0.1", - "alfred-link": "^0.3.0", "axios": "^0.19.0", "bplist-parser": "^0.1.1", + "del": "^4.1.1", "fs-extra": "^8.0.1", "fuse.js": "^3.4.4", + "glob": "^7.1.4", "moment": "^2.17.1", "node-notifier": "^5.0.2", - "read-pkg": "^5.1.1", + "plist": "^3.0.1", + "read-pkg-up": "^6.0.0", "semver": "^6.1.0", "strict-event-emitter-types": "^2.0.0", "untildify": "^4.0.0" diff --git a/src/bin/link.ts b/src/bin/link.ts new file mode 100644 index 0000000..fed42b8 --- /dev/null +++ b/src/bin/link.ts @@ -0,0 +1,53 @@ +#!/usr/bin/env node +import path from "path"; +import fs from "fs-extra"; +import glob from "glob"; +import plist from "plist"; +import semver from "semver"; +import readPkg from "read-pkg-up"; +import del from "del"; +import * as utils from "../utils"; + +if (process.getuid && process.getuid() === 0) { + console.error("You cannot run hugo-link as root."); + process.exit(1); +} + +// Get alfred ersion +const apps = glob.sync("/Applications/Alfred?( )+([0-9]).app"); + +for (const app of apps) { + const plistPath = path.join(app, "Contents", "Info.plist"); + + if (!utils.fileExists(plistPath)) { + continue; + } + + try { + const appInfo = plist.parse(fs.readFileSync(plistPath, { encoding: "utf8" })); + const version = appInfo.CFBundleShortVersionString; + + if (!version || !semver.valid(semver.coerce(version))) { + continue; + } + + const prefsDir = utils.resolveAlfredPrefs(version); + const workflowsDir = path.join(prefsDir, "workflows"); + + // Read package.json + readPkg() + .then(({ package: pkg, path: pkgPath }) => { + const src = path.dirname(pkgPath); + const dest = path.join(workflowsDir, pkg.name.replace("/", "-")); + + del(dest, { force: true }).then(() => { + fs.ensureSymlink(src, dest); + }); + }) + .catch((err) => { + console.error(err); + }); + } catch (err) { + continue; + } +} diff --git a/src/bin/unlink.ts b/src/bin/unlink.ts new file mode 100644 index 0000000..c953f51 --- /dev/null +++ b/src/bin/unlink.ts @@ -0,0 +1,47 @@ +#!/usr/bin/env node +import path from "path"; +import fs from "fs-extra"; +import glob from "glob"; +import plist from "plist"; +import semver from "semver"; +import readPkg from "read-pkg-up"; +import del from "del"; +import * as utils from "../utils"; + +if (process.getuid && process.getuid() === 0) { + console.error("You cannot run hugo-unlink as root."); + process.exit(1); +} + +// Get alfred ersion +const apps = glob.sync("/Applications/Alfred?( )+([0-9]).app"); + +for (const app of apps) { + const plistPath = path.join(app, "Contents", "Info.plist"); + + if (!utils.fileExists(plistPath)) { + continue; + } + + try { + const appInfo = plist.parse(fs.readFileSync(plistPath, { encoding: "utf8" })); + const version = appInfo.CFBundleShortVersionString; + + if (!version || !semver.valid(semver.coerce(version))) { + continue; + } + + const prefsDir = utils.resolveAlfredPrefs(version); + const workflowsDir = path.join(prefsDir, "workflows"); + + // Read package.json + readPkg() + .then(({ package: pkg }) => { + const dest = path.join(workflowsDir, pkg.name.replace("/", "-")); + + del(dest, { force: true }); + }); + } catch (err) { + continue; + } +} diff --git a/src/types/plist.d.ts b/src/types/plist.d.ts new file mode 100644 index 0000000..16f9c7e --- /dev/null +++ b/src/types/plist.d.ts @@ -0,0 +1,4 @@ +declare module "plist" { + export function parse(string: string): any; + export function build(json: any[]): string; +} diff --git a/yarn.lock b/yarn.lock index 5ff9dd7..623e273 100644 --- a/yarn.lock +++ b/yarn.lock @@ -355,14 +355,6 @@ "@types/minimatch" "*" "@types/node" "*" -"@types/got@^9.4.4": - version "9.6.0" - resolved "https://registry.yarnpkg.com/@types/got/-/got-9.6.0.tgz#bba73ff0a46b2691ddb3d86e89f8b2f43ebb829d" - integrity sha512-t00QebxBllcawe7uMxi9jsfWfbki4+/zpJEPyoGWjUvnFOy4EkAzoYOI2UJt2+Fx0yIcDX2+us93k6ensKTddA== - dependencies: - "@types/node" "*" - "@types/tough-cookie" "*" - "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -414,11 +406,6 @@ resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-7.0.13.tgz#ca039c23a9e27ebea53e0901ef928ea2a1a6d313" integrity sha512-d7c/C/+H/knZ3L8/cxhicHUiTDxdgap0b/aNJfsmLwFu/iOP17mdgbQsbHA3SJmrzsjD0l3UEE5SN4xxuz5ung== -"@types/tough-cookie@*": - version "2.3.5" - resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-2.3.5.tgz#9da44ed75571999b65c37b60c9b2b88db54c585d" - integrity sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg== - ajv@^6.5.5: version "6.10.0" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.0.tgz#90d0d54439da587cd7e843bfb7045f50bd22bdf1" @@ -429,21 +416,6 @@ ajv@^6.5.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -alfred-link@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/alfred-link/-/alfred-link-0.3.0.tgz#d7afce495c04d85c6293c9a5abefbe7506ef8dd5" - integrity sha512-35Ezi7chQWndog9DETavKBA9Ka6PFR/PvubhgR02WXNGftGsjL58D/mhFL8cQsx+gZojEVfBarNMLpSQRKNe4Q== - dependencies: - del "^2.2.2" - make-dir "^1.3.0" - path-exists "^3.0.0" - pify "^2.3.0" - plist "^2.0.1" - read-pkg-up "^1.0.1" - resolve-alfred-prefs "^1.0.0" - sudo-block "^1.2.0" - user-home "^2.0.0" - ansi-align@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.0.tgz#b536b371cf687caaef236c18d3e21fe3797467cb" @@ -458,11 +430,6 @@ ansi-escapes@^4.1.0: dependencies: type-fest "^0.5.2" -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" @@ -473,11 +440,6 @@ ansi-regex@^4.1.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= - ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -586,7 +548,7 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -arrify@^1.0.0, arrify@^1.0.1: +arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= @@ -751,10 +713,10 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= -base64-js@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1" - integrity sha1-o5mS1yNYSBGYK+XikLtqU9hnAPE= +base64-js@^1.2.3: + version "1.3.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + integrity sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw== base@^0.11.1: version "0.11.2" @@ -954,17 +916,6 @@ chai@^4.1.2: pathval "^1.1.0" type-detect "^4.0.5" -chalk@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -1406,19 +1357,6 @@ del-cli@^2.0.0: del "^4.1.1" meow "^5.0.0" -del@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" - integrity sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag= - dependencies: - globby "^5.0.0" - is-path-cwd "^1.0.0" - is-path-in-cwd "^1.0.0" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - rimraf "^2.2.8" - del@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" @@ -1506,7 +1444,7 @@ equal-length@^1.0.0: resolved "https://registry.yarnpkg.com/equal-length/-/equal-length-1.0.1.tgz#21ca112d48ab24b4e1e7ffc0e5339d31fdfc274c" integrity sha1-IcoRLUirJLTh5//A5TOdMf38J0w= -error-ex@^1.2.0, error-ex@^1.3.1: +error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== @@ -1539,7 +1477,7 @@ es6-error@^4.0.1: resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -1729,14 +1667,6 @@ find-cache-dir@^2.1.0: make-dir "^2.0.0" pkg-dir "^3.0.0" -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - find-up@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" @@ -1897,7 +1827,7 @@ glob-to-regexp@^0.3.0: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= -glob@^7.0.3, glob@^7.1.1, glob@^7.1.3: +glob@^7.0.3, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4: version "7.1.4" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== @@ -1921,18 +1851,6 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globby@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" - integrity sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0= - dependencies: - array-union "^1.0.1" - arrify "^1.0.0" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - globby@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" @@ -2014,13 +1932,6 @@ har-validator@~5.1.0: ajv "^6.5.5" har-schema "^2.0.0" -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= - dependencies: - ansi-regex "^2.0.0" - has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -2259,11 +2170,6 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" -is-docker@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-1.1.0.tgz#f04374d4eee5310e9a8e113bf1495411e46176a1" - integrity sha1-8EN01O7lMQ6ajhE78UlUEeRhdqE= - is-error@^2.2.2: version "2.2.2" resolved "https://registry.yarnpkg.com/is-error/-/is-error-2.2.2.tgz#c10ade187b3c93510c5470a5567833ee25649843" @@ -2345,23 +2251,11 @@ is-observable@^2.0.0: resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-2.0.0.tgz#327af1e8cdea9cd717f95911b87c5d34301721a6" integrity sha512-fhBZv3eFKUbyHXZ1oHujdo2tZ+CNbdpdzzlENgCGZUC8keoGxUew2jYFLYcUB4qo7LDD03o4KK11m/QYD7kEjg== -is-path-cwd@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" - integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= - is-path-cwd@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.1.0.tgz#2e0c7e463ff5b7a0eb60852d851a6809347a124c" integrity sha512-Sc5j3/YnM8tDeyCsVeKlm/0p95075DyLmDEIkSgQ7mXkrOX+uTCtmQFm0CYzVyJwcCCmO3k8qfJt17SxQwB5Zw== -is-path-in-cwd@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" - integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ== - dependencies: - is-path-inside "^1.0.0" - is-path-in-cwd@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" @@ -2414,11 +2308,6 @@ is-regex@^1.0.4: dependencies: has "^1.0.1" -is-root@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-root/-/is-root-1.0.0.tgz#07b6c233bc394cd9d02ba15c966bd6660d6342d5" - integrity sha1-B7bCM7w5TNnQK6FclmvWZg1jQtU= - is-stream@^1.0.1, is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -2441,7 +2330,7 @@ is-url@^1.2.1: resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== -is-utf8@^0.2.0, is-utf8@^0.2.1: +is-utf8@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= @@ -2692,17 +2581,6 @@ lcov-parse@^0.0.10: resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-0.0.10.tgz#1b0b8ff9ac9c7889250582b70b71315d9da6d9a3" integrity sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM= -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - load-json-file@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" @@ -2823,7 +2701,7 @@ lru-cache@^4.0.1: pseudomap "^1.0.2" yallist "^2.1.2" -make-dir@^1.0.0, make-dir@^1.3.0: +make-dir@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== @@ -3289,7 +3167,7 @@ ora@^3.4.0: strip-ansi "^5.2.0" wcwidth "^1.0.1" -os-homedir@^1.0.0, os-homedir@^1.0.1: +os-homedir@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= @@ -3408,13 +3286,6 @@ package-json@^6.3.0: registry-url "^5.0.0" semver "^6.1.1" -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= - dependencies: - error-ex "^1.2.0" - parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" @@ -3438,13 +3309,6 @@ path-dirname@^1.0.0: resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= - dependencies: - pinkie-promise "^2.0.0" - path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -3482,15 +3346,6 @@ path-to-regexp@^1.7.0: dependencies: isarray "0.0.1" -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - path-type@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" @@ -3518,7 +3373,7 @@ pidtree@^0.3.0: resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.0.tgz#f6fada10fccc9f99bf50e90d0b23d72c9ebc2e6b" integrity sha512-9CT4NFlDcosssyg8KVFltgokyKZIFjoBxw8CTGy+5F38Y1eQWrt8tRayiUOXE+zVKQnYu5BR8JjCtvK3BcnBhg== -pify@^2.0.0, pify@^2.3.0: +pify@^2.0.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= @@ -3560,13 +3415,13 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" -plist@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/plist/-/plist-2.1.0.tgz#57ccdb7a0821df21831217a3cad54e3e146a1025" - integrity sha1-V8zbeggh3yGDEhejytVOPhRqECU= +plist@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.1.tgz#a9b931d17c304e8912ef0ba3bdd6182baf2e1f8c" + integrity sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ== dependencies: - base64-js "1.2.0" - xmlbuilder "8.2.2" + base64-js "^1.2.3" + xmlbuilder "^9.0.7" xmldom "0.1.x" plur@^3.1.1: @@ -3651,14 +3506,6 @@ rc@^1.1.6, rc@^1.2.8: minimist "^1.2.0" strip-json-comments "~2.0.1" -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - read-pkg-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" @@ -3675,14 +3522,14 @@ read-pkg-up@^4.0.0: find-up "^3.0.0" read-pkg "^3.0.0" -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= +read-pkg-up@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-6.0.0.tgz#da75ce72762f2fa1f20c5a40d4dd80c77db969e3" + integrity sha512-odtTvLl+EXo1eTsMnoUHRmg/XmXdTkwXVxy4VFE9Kp6cCq7b3l7QMdBndND3eAFzrbSAXC/WCUOQQ9rLjifKZw== dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" + find-up "^4.0.0" + read-pkg "^5.1.1" + type-fest "^0.5.0" read-pkg@^3.0.0: version "3.0.0" @@ -3835,17 +3682,6 @@ require-precompiled@^0.1.0: resolved "https://registry.yarnpkg.com/require-precompiled/-/require-precompiled-0.1.0.tgz#5a1b52eb70ebed43eb982e974c85ab59571e56fa" integrity sha1-WhtS63Dr7UPrmC6XTIWrWVceVvo= -resolve-alfred-prefs@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/resolve-alfred-prefs/-/resolve-alfred-prefs-1.0.0.tgz#aae914088578829b584a4e6b72507e8c2096ec37" - integrity sha1-qukUCIV4gptYSk5rclB+jCCW7Dc= - dependencies: - bplist-parser "^0.1.1" - path-exists "^3.0.0" - pify "^2.3.0" - untildify "^3.0.2" - user-home "^2.0.0" - resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" @@ -3915,7 +3751,7 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -rimraf@^2.2.8, rimraf@^2.6.2, rimraf@^2.6.3: +rimraf@^2.6.2, rimraf@^2.6.3: version "2.6.3" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== @@ -4226,13 +4062,6 @@ string.prototype.padend@^3.0.0: es-abstract "^1.4.3" function-bind "^1.0.2" -strip-ansi@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= - dependencies: - ansi-regex "^2.0.0" - strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -4254,13 +4083,6 @@ strip-bom-buf@^2.0.0: dependencies: is-utf8 "^0.2.1" -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= - dependencies: - is-utf8 "^0.2.0" - strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" @@ -4281,15 +4103,6 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= -sudo-block@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/sudo-block/-/sudo-block-1.2.0.tgz#cc539bf8191624d4f507d83eeb45b4cea27f3463" - integrity sha1-zFOb+BkWJNT1B9g+60W0zqJ/NGM= - dependencies: - chalk "^1.0.0" - is-docker "^1.0.0" - is-root "^1.0.0" - supertap@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/supertap/-/supertap-1.0.0.tgz#bd9751c7fafd68c68cf8222a29892206a119fa9e" @@ -4301,11 +4114,6 @@ supertap@^1.0.0: serialize-error "^2.1.0" strip-ansi "^4.0.0" -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= - supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -4470,7 +4278,7 @@ type-fest@^0.4.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8" integrity sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw== -type-fest@^0.5.2: +type-fest@^0.5.0, type-fest@^0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.5.2.tgz#d6ef42a0356c6cd45f49485c3b6281fc148e48a2" integrity sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw== @@ -4562,11 +4370,6 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" -untildify@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.3.tgz#1e7b42b140bcfd922b22e70ca1265bfe3634c7c9" - integrity sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA== - untildify@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" @@ -4614,13 +4417,6 @@ use@^3.1.0: resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== -user-home@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" - integrity sha1-nHC/2Babwdy/SGBODwS4tJzenp8= - dependencies: - os-homedir "^1.0.0" - uuid@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" @@ -4717,10 +4513,10 @@ xdg-basedir@^3.0.0: resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= -xmlbuilder@8.2.2: - version "8.2.2" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-8.2.2.tgz#69248673410b4ba42e1a6136551d2922335aa773" - integrity sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M= +xmlbuilder@^9.0.7: + version "9.0.7" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" + integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= xmldom@0.1.x: version "0.1.27" From 3f6b1d5b21a392722ead6900d2853b36c8f1243b Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Mon, 24 Jun 2019 02:17:48 +0200 Subject: [PATCH 32/35] Always use read-pkg-up --- src/updater.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/updater.ts b/src/updater.ts index 5304452..1a2643e 100644 --- a/src/updater.ts +++ b/src/updater.ts @@ -1,6 +1,6 @@ import { Cache } from "@cloudstek/cache"; import moment from "moment"; -import readPkg from "read-pkg"; +import readPkg from "read-pkg-up"; import axios from "axios"; import semver from "semver"; @@ -115,7 +115,7 @@ export class Updater { */ private async checkNpm(pkg?: any): Promise { // Get details from package.json - pkg = pkg || await readPkg({ cwd: process.cwd() }); + pkg = pkg || readPkg.sync().package; if (!pkg.name || !pkg.version) { throw new Error("Invalid package.json."); From 38c499cd4cd34b6bcc9b984243f723b2a05528ac Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Mon, 24 Jun 2019 02:33:32 +0200 Subject: [PATCH 33/35] Update docs --- docs/file-cache.md | 15 +++++++++++++++ docs/metadata.md | 4 ++-- docs/updates.md | 2 ++ media/update-action.png | Bin 66369 -> 80126 bytes 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/docs/file-cache.md b/docs/file-cache.md index e0f252f..18cd4b2 100644 --- a/docs/file-cache.md +++ b/docs/file-cache.md @@ -4,6 +4,8 @@ Processing files is often takes time and waste of resources when the file hardly The built-in file cache (for lack of a better name) does all this for you and is built upon the built-in [cache](./cache). Take a look at the examples on how to use it. +By default the TTL (cache lifetime) is set to `false`, which means the results are cached indefinitely until the file has been changed. You can force a different TTL by + ### Example ```js @@ -32,3 +34,16 @@ console.log(results.foo); // Will output processed foo data console.log(results.bar); // Will output processed bar data ``` +#### With a 1-hour TTL + +```js +import { Hugo } from "alfred-hugo"; + +const hugo = new Hugo(); + +// Create the file cache +const fc = hugo.cacheFile('/path/to/file.to.process', { ttl: 3600 }); + +// ... see example above. +``` + diff --git a/docs/metadata.md b/docs/metadata.md index 2b32f5d..76fd685 100644 --- a/docs/metadata.md +++ b/docs/metadata.md @@ -17,7 +17,7 @@ Alfred metadata can be accessed using the `alfredMeta` property of Hugo and is a themeBackground: // Theme background colour, themeSelectionBackground: // Colour of the selected result, themeSubtext: // Contains value from alfred_theme_subtext, - themeFile: // Absolute path to theme file (if found), + themeFile: // Absolute path to theme file (if found), version: // Alfred version } ``` @@ -64,7 +64,7 @@ const hugo = new Hugo(); console.log(`Alfred version ${hugo.alfredMeta.version}`); console.log(`Workflow ${hugo.workflowMeta.name} version ${hugo.workflowMeta.version}`); -// Alfred version 3.4.1 +// Alfred version 4.0.0 // Workflow alfred-foobar version 1.0.0 ``` diff --git a/docs/updates.md b/docs/updates.md index d56dc43..2840aff 100644 --- a/docs/updates.md +++ b/docs/updates.md @@ -8,6 +8,8 @@ There are two ways to notify the user of an available update, with a notificatio When the item is activated, it will set a variable named `task` (`{var:task}` in Alfred) with the value `wfUpdate`. The argument is set to the URL where the update can be found, either on Packal or NPM depending on `updateSource`. You can link the output to an [Open URL](https://www.alfredapp.com/help/workflows/actions/open-url/) action so a browser opens when the user selects the update item. +See [alfred-atom](https://github.com/Cloudstek/alfred-atom) for example which uses the Conditional element in Alfred 4. + ![Opening a browser for updates](../media/update-action.png) ### Examples diff --git a/media/update-action.png b/media/update-action.png index a21a9e9d1ac7cfb69aea5eced11e754ae268a511..a349f43561281a80ecf2bf583ec02c820b165e3d 100644 GIT binary patch literal 80126 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 literal 66369 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 From f1e4d1963da668b5fd31a29bb880fc47c8f43b38 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Mon, 24 Jun 2019 02:33:47 +0200 Subject: [PATCH 34/35] Set default TTL of file cache to false --- src/file-cache.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/file-cache.ts b/src/file-cache.ts index 488359f..7eb2a6e 100644 --- a/src/file-cache.ts +++ b/src/file-cache.ts @@ -31,6 +31,8 @@ export class FileCache extends (EventEmitter as new() => FileCacheEventEmitter) // Initialize cache store for this file options.name = Crypto.createHash("sha1").update(filePath).digest("hex") + ".json"; + options.ttl = options.ttl || false; + this.cache = new Cache(options); } From 659e7c95c63362734e3ea91283824ba03e9a74b8 Mon Sep 17 00:00:00 2001 From: Maarten de Boer Date: Mon, 24 Jun 2019 02:39:25 +0200 Subject: [PATCH 35/35] Release 2.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c8fc431..42bad0e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "alfred-hugo", - "version": "2.0.0-beta.1", + "version": "2.0.0", "description": "Alfred workflow bindings for NodeJS", "author": "Maarten de Boer (https://cloudstek.nl)", "contributors": [