From 5f4943d1d5cdd6664b9e6d14e1f1527717e9b133 Mon Sep 17 00:00:00 2001 From: Joshua Date: Fri, 14 Dec 2018 15:59:12 +0000 Subject: [PATCH] new server test with precommit hook to secure .env files, set up CI environment (#5) * new server test with precommit hook to secure .env files, set up CI environment (#3) * [TESTS] added all registered routes to api server test * [WIP] abstracting config to env where it makes sense, refactoring elsewhere, adding more tests * [WIP] fixed tests so they fail as expected * [WIP] * [DEBUG] fixed issues with the env configuration, added correct tests * [MISC] env didn't get readded on last precommit * [TESTS] added longer wait time for server as sometimtimes tests fail arbitrarily --- .env.enc | Bin 0 -> 1968 bytes .env.example | 4 + .gitignore | 2 + .travis.yml | 19 +++-- package.json | 7 ++ src/api/index.js | 35 ++++---- src/example.config.js | 4 +- src/index.js | 9 ++- src/initialize.js | 12 +-- src/lib/Controller.js | 1 + src/lib/Fetcher.js | 2 +- src/middleware/index.js | 5 +- src/sheets_config.js | 19 +++++ test/server_process.js | 103 ++++++++++++++++++++++++ yarn.lock | 173 +++++++++++++++++++++++++++++++++++++++- 15 files changed, 351 insertions(+), 44 deletions(-) create mode 100644 .env.enc create mode 100644 .env.example create mode 100644 src/sheets_config.js create mode 100644 test/server_process.js diff --git a/.env.enc b/.env.enc new file mode 100644 index 0000000000000000000000000000000000000000..dfcfe8d3382e9d6b26274d3832cbc04c8da6f4af GIT binary patch literal 1968 zcmV;h2T%B&F1_W_!JtpliEU6VgWpg2Rr9k0Z4}AUm00)4XV3v-&U4F_r@!PKGpJufWky<7Mxg4L1{z7uZ~mKP zy)e-6&yhj@6`q?t#JP(GtK`AP-mET{3;S8-d95XWK^Te|WPt%2n?RXxt6NOdo&Ds# zkXkh0v`kptc=#D&v)n!o%xmj}EN&1k%%u+eDQ|g5=Bm`;36qrvw>Aa+YQpix+rwf! zHX#Uskc{dL7aj~FK+Z27fAp0P@@Dwear~Q*R$7mK@-xzww?}tKxC3XZkzH&}BRUc6 z?8Kw-#e#Bj3qRJEPp7-T`5GK4c6Ak%8y@4vGxfO&lX_h@dIs(tC1iOUA#msfWi+0@ zaI@p<*v1CmpDLCVqRB%7sZJ{#&d(;&yy**65NC}o%wgdMkY8dWG`b~l{^lcW;<|&; znSRf`P8uXh5A?98yzX*nr@SgJvUwivj!(Q7(3K|-1^+Y;p3hx}3}tL_V6G0A<=k0x z7&dcrmf2&#BZ(Z)mu6$kZ11_Wt8W`tZw`hZ1fQLL`U-oW^v&X-9DtoXsw<+RDSu%% zW#Nm8+A2Uh**15zeT9auPJ6mX(T_W4V5Rsw@T~e3)q+QLkc7X$ zm>)b)(;!iFJ%G~Q-NV%=0#Lzg2p%&=52jIpDvZOUz`HuN+s!{*!*;}MT=m~RW$yBC zH|nqTooqOPMSz7XQ)L*@&*NKgak5&8>V!+6f$rzy`Y5YcFAj}XV4bPPfL;xNS+bhv&3B!KMdn8 z1ltp&G%Q3$p@|MrrHfv4nY71OL`i^H+6H8d-QjDx45?k;0J*fsvkUe2hD{7tIGc6ZjDJ$bvH+VhI^QD zMJoP~D)BdqJo^nyf$JxqWvfq0kU1haOUXuG{V?M;eubYKraE#|E@PuC48NqqVXAs? z_aD1hN`?QmDe+TnhRJZ7VGgeNx0bQ)THWOl`;VWsM{n8~&;t>3U!M+UP6*GqNPz~* z#xT=sE!vi>;a~d%DVeDSJxxd<81$uOfjug0_A(G1GFJ~lqFmBu_9%Qu-KZWW9f84P z0^zZT$XFTu43(WgZr`2QMS);@EL(EOJq4k-6v#17oU+pUX%oQ$4k9t&zOih34SR$p z>v4qlI4MC5o|wyuPuuc8@j9+J%b4Fw7+->L?*ZZyJN&f-Gat*oYbq!9#6r>eXeEm^ zBtyuc5C1I8j=ZtV0ywJXlPo3zqH+gBS7*W|-j>%V1!>hTf;NfGTqD?4ikGE>i+ES3 z&ySMff|DED0Iark?Wtlw1jdzhmgr>AL?SyT+qwnLO4o}=;tg07Ok8at{)WA_&*6Nc ze2avuex^ZHXPzC>3FtW(k%rAI`NQJnI6=A}`3&<4Mo`=V;^Yggw3{9totW*%+8EV( zC-6j4ob!5nmfnTp*(ntEXz>c7bTbdFh|iQh$^&y;vLtmBQrgO71*tk$rRQ|{JHCY2 zyK&cv07^JD_RTcwEQ<*H&$vMj@!w#hRZcOl&SSryc5;J%G6UcCCh>Zhz#JCU`He_C zlfOJGL$Z1y{eNIX=w@KbO#~X{GNy3comf20UIiq}ULGfD)e_s>_xIVQ{Ds_Lk9~s} zMxALU(@^Z6!pZS;QhKFIgQK8&{U;7^9+g@sSt{epV$b#&%Z*jj>>V`nCL`$~+UD&Z z-5Gc&RK<1Ty+>trd0$+bGPRO(Pe>~AVwCCJq7Oj$Cs?x6pg+K|I40M=Ue#shIbMT` zA00?wFSc^x$ewKzhCVS}O0QJBHFuhb&S2%pM*gOxod`2qCI^8cSld{wBlkv*izMg+ z-KyVSjG_u|cH2w`U>0?Ln`6bsAbV>7>a(vT-X$LYPQf;}FYM#Aw2mi0*MBj@j@mh~ zXu7j&@j1R^9Sh(C`<4f+BcaTfI0pxfk-|Fl`om?`Ma2ApgTwu}d3uQup_8r!5A1DTW!^S0WINB;Z5_mz+y*jub+s zB#@CgoTa_ZccshcK}iUHTrp-)r|K-cudD%Z04!7MQjqAck$Qrk*z<)6J_SSu6tH*& z&gc0|UtA)Uuxg3G*}>+6m=@S-@i#vlY=>0ezLbH6-Y9TiZ^_T@=HLt6X;hH0yVb6v zBbGEZ;3-ujdqAoHCCaCm)c4=+fT%`SyIf(~ { res.json(controller.blueprints()) }) + api.get('/update', (req, res) => { + controller + .update() + .then(msg => + res.json({ + success: msg + }) + ) + .catch(err => + res.status(404) + .send({ error: err.message, err }) + ) + }) + api.get('/:sheet/:tab/:resource/:frag', (req, res) => { const { sheet, tab, resource, frag } = req.params controller @@ -27,8 +41,9 @@ export default ({ config, controller }) => { }) api.get('/:sheet/:tab/:resource', (req, res) => { + const { sheet, tab, resource } = req.params controller - .retrieve(req.params.sheet, req.params.tab, req.params.resource) + .retrieve(sheet, tab, resource) .then(data => res.json(data)) .catch(err => res.status(err.status || 404) @@ -36,30 +51,16 @@ export default ({ config, controller }) => { ) }) - api.get('/update', (req, res) => { - controller - .update() - .then(msg => - res.json({ - success: msg - }) - ) - .catch(err => - res.status(404) - .send({ error: err.message }) - ) - }) - // ERROR routes. Note that it is important that these come AFTER routes // like /update, so that the regex does not greedily match these routes. api.get('/:sheet', (req, res) => { - res.status(404) + res.status(400) .send({ error: copy.errors.onlysheet }) }) api.get('/:sheet/:tab', (req, res) => { - res.status(404) + res.status(400) .send({ error: copy.errors.onlyTab }) }) diff --git a/src/example.config.js b/src/example.config.js index c4c190c..29c4a80 100644 --- a/src/example.config.js +++ b/src/example.config.js @@ -3,12 +3,10 @@ import BP from './lib/blueprinters' export default { port: 4040, googleSheets: { - email: 'SOME_SERVICE_ACCOUNT_EMAIL', - privateKey: 'SOME_SERVICE_ACCOUNT_PRIVATE_KEY', sheets: [ { name: 'example', - id: '1UC7DkCFeUXHfpUxUGruExwFbP4pqVBdJLOKfo6wDDGk', + id: '15gb_aYJw7WSVZmtS0FZvcpGx1-kwKX3VHH8YV6La4hY', tabs: { export_events: [BP.deeprows, BP.rows], export_categories: [BP.groups, BP.rows], diff --git a/src/index.js b/src/index.js index c2a483b..1e4ccd2 100755 --- a/src/index.js +++ b/src/index.js @@ -3,7 +3,10 @@ import express from 'express' import initialize from './initialize' import middleware from './middleware' import api from './api' -import config from './config' +// import config from './sheets_config' +import dotenv from 'dotenv' + +dotenv.config() let app = express() app.server = http.createServer(app) @@ -15,6 +18,8 @@ if (process.env.NODE_ENV === 'development') { app.use(cors()) } +const config = process.env + initialize(controller => { app.use( middleware({ @@ -30,7 +35,7 @@ initialize(controller => { }) ) - app.server.listen(process.env.PORT || config.port, () => { + app.server.listen(process.env.PORT || 4040, () => { console.log(`Started on port ${app.server.address().port}`) }) }) diff --git a/src/initialize.js b/src/initialize.js index d7a5e25..75c2a94 100755 --- a/src/initialize.js +++ b/src/initialize.js @@ -1,13 +1,13 @@ import StoreJson from './models/StoreJson' import Fetcher from './lib/Fetcher' import Controller from './lib/Controller' -import config from './config' +import sheetsConfig from './sheets_config' -const { googleSheets } = config -const { sheets, privateKey, email } = googleSheets +const { googleSheets } = sheetsConfig +const { sheets } = googleSheets function authenticate (_fetcher) { - return _fetcher.fetcher.authenticate(email, privateKey).then(msg => { + return _fetcher.fetcher.authenticate(process.env.SERVICE_ACCOUNT_EMAIL, process.env.SERVICE_ACCOUNT_PRIVATE_KEY).then(msg => { console.log(msg) return true }) @@ -24,7 +24,7 @@ export default callback => { Promise.all(fetchers.map(authenticate)) .then(() => { console.log(`===================`) - console.log(`grant access to: ${email}`) + console.log(`grant access to: ${process.env.SERVICE_ACCOUNT_EMAIL}`) console.log(`===================`) // NB: reformat fetchers as config for controller @@ -39,7 +39,7 @@ export default callback => { console.log(err) console.log( `ERROR: the server couldn't connect to all of the sheets you provided. Ensure you have granted access to ${ - email + process.env.SERVICE_ACCOUNT_EMAIL } on ALL listed sheets.` ) }) diff --git a/src/lib/Controller.js b/src/lib/Controller.js index b9e9351..d188fb9 100644 --- a/src/lib/Controller.js +++ b/src/lib/Controller.js @@ -36,6 +36,7 @@ class Controller { retrieve (sheet, tab, resource) { if (this._sheetExists(sheet)) { const fetcher = this.fetchers[sheet] + // console.log(fetcher); return fetcher.retrieve(tab, resource) } else { return Promise.reject(new Error(copy.errors.noResource(sheet))) diff --git a/src/lib/Fetcher.js b/src/lib/Fetcher.js index f62c79f..164eff5 100644 --- a/src/lib/Fetcher.js +++ b/src/lib/Fetcher.js @@ -189,7 +189,7 @@ class Fetcher { retrieveFrag (tab, resource, frag) { const title = fmtName(tab) - const url = `${this.id}/${tab}/${resource}/${frag}` + const url = `${this.sheetName}/${tab}/${resource}/${frag || ''}` return this.db.load(url, this.blueprints[title]) } } diff --git a/src/middleware/index.js b/src/middleware/index.js index 6876175..0399649 100755 --- a/src/middleware/index.js +++ b/src/middleware/index.js @@ -1,5 +1,4 @@ import { Router } from 'express' -import { mapboxAccessToken } from '../config' import morgan from 'morgan' import mapbox from './mapbox' @@ -10,8 +9,8 @@ export default ({ config, db }) => { /* logging middleware */ routes.use(morgan('dev')) - if (mapboxAccessToken) { - routes.get('/mapbox/:z/:y/:x', mapbox(mapboxAccessToken)) + if (process.env.MAPBOX_TOKEN) { + routes.get('/mapbox/:z/:y/:x', mapbox(process.env.MAPBOX_TOKEN)) } return routes diff --git a/src/sheets_config.js b/src/sheets_config.js new file mode 100644 index 0000000..96996c3 --- /dev/null +++ b/src/sheets_config.js @@ -0,0 +1,19 @@ +import BP from './lib/blueprinters' + +export default { + googleSheets: { + sheets: [ + { + name: 'example', + id: '1UC7DkCFeUXHfpUxUGruExwFbP4pqVBdJLOKfo6wDDGk', + tabs: { + export_events: [BP.deeprows, BP.rows], + export_categories: [BP.groups, BP.rows], + export_sources: BP.ids, + export_sites: BP.rows, + export_tags: BP.tree + } + } + ] + } +} diff --git a/test/server_process.js b/test/server_process.js new file mode 100644 index 0000000..02d7341 --- /dev/null +++ b/test/server_process.js @@ -0,0 +1,103 @@ +var assert = require('assert'); +var child_process = require('child_process') +var http = require('http'); +import test from 'ava' + +const SERVER_LAUNCH_WAIT_TIME = 10 * 1000; + +var server_proc = null; +var server_exited = false; + +test.before.cb(t => { + console.log("launching server...") + server_proc = child_process.spawn('yarn', ['dev'], { + cwd: '.', + stdio: 'ignore' + }); + + server_proc.on('exit', function(code, signal) { + server_exited = true; + }); + + setTimeout(t.end, SERVER_LAUNCH_WAIT_TIME); +}); + +test.after(function() { + console.log("killing server...") + server_proc.kill('SIGKILL'); +}); + +test('should launch', t => { + t.false(server_exited); +}); + +var passUrls = [ + // Express API registered routes: + // / + '/api/', + // /blueprints + '/api/blueprints', + // /update + '/api/update', + // /:sheet/:tab/:resource + '/api/example/export_events/rows', + // /:sheet/:tab/:resource/:frag + '/api/example/export_events/rows/1' +]; + +var failUrls = [ + // /:sheet + '/api/example', + // /:sheet/:tab + '/api/example/events' +] + +passUrls.forEach(function(url) { + test.cb('should respond successfully to request for "' + url + '"', t => { + http.get({ + hostname: 'localhost', + port: 4040, + path: url, + agent: false + }, function(res) { + var result_data = ''; + + if(res.statusCode != 200) { + t.fail('Server response was not 200.'); + } else { + res.on('data', function(data) { result_data += data }); + + res.on('end', function() { + if (result_data.length > 0) { + t.pass(); + } else { + t.fail("Server returned no data."); + } + }); + } + + t.end(); + }) + }); +}); + +failUrls.forEach(function(url) { + test.cb('should fail to respond to request for "' + url + '"', t => { + http.get({ + hostname: 'localhost', + port: 4040, + path: url, + agent: false + }, function(res) { + var result_data = ''; + + if(res.statusCode < 400) { + t.fail('Server response was not erroneous.'); + } else { + t.pass(); + } + + t.end(); + }) + }); +}); \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 715154a..e7a78cb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -996,16 +996,35 @@ call-signature@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/call-signature/-/call-signature-0.0.2.tgz#a84abc825a55ef4cb2b028bd74e205a65b9a4996" +caller-callsite@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-callsite/-/caller-callsite-2.0.0.tgz#847e0fce0a223750a9a027c54b33731ad3154134" + integrity sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ= + dependencies: + callsites "^2.0.0" + caller-path@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" dependencies: callsites "^0.2.0" +caller-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-2.0.0.tgz#468f83044e369ab2010fac5f06ceee15bb2cb1f4" + integrity sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ= + dependencies: + caller-callsite "^2.0.0" + callsites@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + integrity sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA= + camelcase-keys@^4.0.0: version "4.2.0" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-4.2.0.tgz#a2aa5fb1af688758259c32c141426d78923b9b77" @@ -1274,6 +1293,16 @@ cors@^2.8.5: object-assign "^4" vary "^1" +cosmiconfig@^5.0.6: + version "5.0.7" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.0.7.tgz#39826b292ee0d78eda137dfa3173bd1c21a43b04" + integrity sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA== + dependencies: + import-fresh "^2.0.0" + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + create-error-class@^3.0.0: version "3.0.2" resolved "https://registry.yarnpkg.com/create-error-class/-/create-error-class-3.0.2.tgz#06be7abef947a3f14a30fd610671d401bca8b7b6" @@ -1288,7 +1317,7 @@ cross-spawn@^5.0.1: shebang-command "^1.2.0" which "^1.2.9" -cross-spawn@^6.0.5: +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" dependencies: @@ -1470,6 +1499,11 @@ dot-prop@^4.1.0, dot-prop@^4.2.0: dependencies: is-obj "^1.0.0" +dotenv@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-6.1.0.tgz#9853b6ca98292acb7dec67a95018fa40bccff42c" + integrity sha512-/veDn2ztgRlB7gKmE3i9f6CmDIyXAy6d5nBq+whO9SLX+Zs1sXEgFLPi+aSuWqUuusMfbi84fT8j34fs1HaYUw== + duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" @@ -1503,6 +1537,13 @@ encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" +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" @@ -1741,6 +1782,19 @@ execa@^0.7.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" @@ -1910,6 +1964,13 @@ find-up@^2.0.0, find-up@^2.1.0: 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" + flat-cache@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.3.0.tgz#d3030b32b38154f4e3b7e9c709f490f7ef97c481" @@ -2009,6 +2070,13 @@ get-stream@^3.0.0: version "3.0.0" resolved "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" +get-stream@^4.0.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" @@ -2226,6 +2294,22 @@ http-errors@^1.3.0: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" +husky@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/husky/-/husky-1.2.0.tgz#d631dda1e4a9ee8ba69a10b0c51a0e2c66e711e5" + integrity sha512-/ib3+iycykXC0tYIxsyqierikVa9DA2DrT32UEirqNEFVqOj1bFMTgP3jAz8HM7FgC/C8pc/BTUa9MV2GEkZaA== + dependencies: + cosmiconfig "^5.0.6" + execa "^1.0.0" + find-up "^3.0.0" + get-stdin "^6.0.0" + is-ci "^1.2.1" + pkg-dir "^3.0.0" + please-upgrade-node "^3.1.1" + read-pkg "^4.0.1" + run-node "^1.0.0" + slash "^2.0.0" + iconv-lite@0.4.23: version "0.4.23" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" @@ -2256,6 +2340,14 @@ ignore@^4.0.2: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" +import-fresh@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" + integrity sha1-2BNVwVYS04bGH53dOSLUMEgipUY= + dependencies: + caller-path "^2.0.0" + resolve-from "^3.0.0" + import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" @@ -2358,7 +2450,7 @@ is-callable@^1.1.3, is-callable@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" -is-ci@^1.0.10, is-ci@^1.2.0: +is-ci@^1.0.10, is-ci@^1.2.0, is-ci@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.2.1.tgz#e3779c8ee17fccf428488f6e281187f2e632841c" dependencies: @@ -2396,6 +2488,11 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + integrity sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE= + is-error@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/is-error/-/is-error-2.2.1.tgz#684a96d84076577c98f4cdb40c6d26a5123bf19c" @@ -2577,7 +2674,7 @@ js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" -js-yaml@^3.10.0, js-yaml@^3.11.0: +js-yaml@^3.10.0, js-yaml@^3.11.0, js-yaml@^3.9.0: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" dependencies: @@ -2687,6 +2784,14 @@ locate-path@^2.0.0: 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" + lodash.clone@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6" @@ -3145,7 +3250,7 @@ on-headers@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" -once@^1.3.0: +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" dependencies: @@ -3212,12 +3317,26 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" +p-limit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" + integrity sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A== + 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" 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-map@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" @@ -3226,6 +3345,11 @@ p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" +p-try@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" + integrity sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ== + package-hash@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-2.0.0.tgz#78ae326c89e05a4d813b68601977af05c00d2a0d" @@ -3370,6 +3494,20 @@ pkg-dir@^2.0.0: dependencies: find-up "^2.1.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" + +please-upgrade-node@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz#ed320051dfcc5024fae696712c8288993595e8ac" + integrity sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ== + dependencies: + semver-compare "^1.0.0" + plur@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/plur/-/plur-3.0.1.tgz#268652d605f816699b42b86248de73c9acd06a7c" @@ -3433,6 +3571,14 @@ pstree.remy@^1.1.2: resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.2.tgz#4448bbeb4b2af1fed242afc8dc7416a6f504951a" integrity sha512-vL6NLxNHzkNTjGJUpMm5PLC+94/0tTlC1vkP9bdU0pOHih+EujMjgMTwfZopZvHWRFbqJ5Y73OMoau50PewDDA== +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" + punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" @@ -3501,6 +3647,15 @@ read-pkg@^3.0.0: normalize-package-data "^2.3.2" path-type "^3.0.0" +read-pkg@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-4.0.1.tgz#963625378f3e1c4d48c85872b5a6ec7d5d093237" + integrity sha1-ljYlN48+HE1IyFhytabsfV0JMjc= + dependencies: + normalize-package-data "^2.3.2" + parse-json "^4.0.0" + pify "^3.0.0" + readable-stream@^2.0.2, readable-stream@^2.0.6: version "2.3.6" resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" @@ -3677,6 +3832,11 @@ run-async@^2.2.0: dependencies: is-promise "^2.1.0" +run-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/run-node/-/run-node-1.0.0.tgz#46b50b946a2aa2d4947ae1d886e9856fd9cabe5e" + integrity sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A== + run-parallel@^1.1.2: version "1.1.9" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" @@ -3705,6 +3865,11 @@ sax@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" +semver-compare@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" + integrity sha1-De4hahyUGrN+nvsXiPavxf9VN/w= + semver-diff@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-2.1.0.tgz#4bbb8437c8d37e4b0cf1a68fd726ec6d645d6d36"