Compare commits

...

12 Commits

Author SHA1 Message Date
Rich Harris
5b214c964c -> v0.2.5 2017-12-21 08:59:00 -05:00
Rich Harris
95f99fd378 Merge pull request #39 from sveltejs/windows-nested-routes
use /, not path.sep, when creating routes
2017-12-21 08:55:41 -05:00
Rich Harris
1bed4b0670 use /, not path.sep, when creating routes 2017-12-21 08:46:40 -05:00
Rich Harris
9d4890913a Merge pull request #37 from sveltejs/gh-33
error if routes clash
2017-12-20 21:00:04 -05:00
Rich Harris
f50d3c4262 error if routes clash - fixes #33 2017-12-20 20:46:28 -05:00
Rich Harris
8925e541d5 Merge pull request #36 from sveltejs/gh-19
stream responses
2017-12-20 18:50:06 -05:00
Rich Harris
a48afb77d3 stream responses - fixes #19 2017-12-20 18:39:39 -05:00
Rich Harris
45e845ee92 Merge pull request #35 from sveltejs/gh-2
add preload header for main.js and current route
2017-12-20 18:13:07 -05:00
Rich Harris
492f024d2a add preload header for main.js and current route - fixes #2 2017-12-20 18:04:11 -05:00
Rich Harris
8d40992cf1 Merge pull request #34 from sveltejs/gh-13
Rebundle when routes/templates change
2017-12-20 17:51:04 -05:00
Rich Harris
4232f75b19 rebundle when main.js changes 2017-12-20 17:36:22 -05:00
Rich Harris
fefb0d96d7 rebundle when routes and templates change 2017-12-20 17:34:23 -05:00
12 changed files with 393 additions and 94 deletions

View File

@@ -1,5 +1,13 @@
# sapper changelog
## 0.2.5
* Fix nested routes on Windows ([#39](https://github.com/sveltejs/sapper/pull/39))
* Rebundle when routes and main.js change ([#34](https://github.com/sveltejs/sapper/pull/34))
* Add `Link...preload` headers for JavaScript assets ([#2](https://github.com/sveltejs/sapper/issues/2))
* Stream document up to first dynamic content ([#19](https://github.com/sveltejs/sapper/issues/19))
* Error if routes clash ([#33](https://github.com/sveltejs/sapper/issues/33))
## 0.2.4
* Posixify path to HMR client

View File

@@ -14,8 +14,6 @@ const escape_html = require('escape-html');
const { src, dest, dev } = require('./config.js');
function connect_dev() {
// create main.js and server-routes.js
// TODO update on changes
create_app();
const watcher = create_watcher();
@@ -59,7 +57,7 @@ function connect_dev() {
get_route_handler(() => asset_cache),
not_found
get_not_found_handler(() => asset_cache)
]);
}
@@ -95,7 +93,7 @@ function connect_prod() {
get_route_handler(() => asset_cache),
not_found
get_not_found_handler(() => asset_cache)
]);
}
@@ -137,20 +135,36 @@ function get_route_handler(fn) {
const mod = require(server.entry)[route.id];
if (route.type === 'page') {
// preload main.js and current route
// TODO detect other stuff we can preload? images, CSS, fonts?
res.set('Link', `<${client.main_file}>;rel="preload";as="script", <${client.routes[route.id]}>;rel="preload";as="script"`);
let data = { params: req.params, query: req.query };
if (mod.preload) data = Object.assign(data, await mod.preload(data));
const { html, head, css } = mod.render(data);
if (mod.preload) {
const promise = Promise.resolve(mod.preload(data)).then(preloaded => {
Object.assign(data, preloaded);
return mod.render(data);
});
const page = templates.render(200, {
main: client.main_file,
html,
head: `<noscript id='sapper-head-start'></noscript>${head}<noscript id='sapper-head-end'></noscript>`,
styles: (css && css.code ? `<style>${css.code}</style>` : '')
});
templates.stream(res, 200, {
main: client.main_file,
html: promise.then(rendered => rendered.html),
head: promise.then(({ head }) => `<noscript id='sapper-head-start'></noscript>${head}<noscript id='sapper-head-end'></noscript>`),
styles: promise.then(({ css }) => (css && css.code ? `<style>${css.code}</style>` : ''))
});
} else {
const { html, head, css } = mod.render(data);
res.status(200);
res.end(page);
const page = templates.render(200, {
main: client.main_file,
html,
head: `<noscript id='sapper-head-start'></noscript>${head}<noscript id='sapper-head-end'></noscript>`,
styles: (css && css.code ? `<style>${css.code}</style>` : '')
});
res.end(page);
}
}
else {
@@ -174,13 +188,18 @@ function get_route_handler(fn) {
}
}
function not_found(req, res) {
res.status(404).end(templates.render(404, {
title: 'Not found',
status: 404,
method: req.method,
url: req.url
}));
function get_not_found_handler(fn) {
return function handle_not_found(req, res) {
const asset_cache = fn();
res.status(404).end(templates.render(404, {
title: 'Not found',
status: 404,
method: req.method,
main: asset_cache.client.main_file,
url: req.url
}));
}
}
function compose_handlers(handlers) {

View File

@@ -1,16 +1,30 @@
const glob = require('glob');
const chokidar = require('chokidar');
const create_routes = require('./utils/create_routes.js');
const { src } = require('./config.js');
const { src, dev } = require('./config.js');
const route_manager = {
routes: create_routes(
glob.sync('**/*.+(html|js|mjs)', { cwd: src })
),
const callbacks = [];
onchange(fn) {
// TODO in dev mode, keep this updated, and allow
// webpack compiler etc to hook into it
}
exports.onchange = fn => {
callbacks.push(fn);
};
module.exports = route_manager;
function update() {
exports.routes = create_routes(
glob.sync('**/*.+(html|js|mjs)', { cwd: src })
);
callbacks.forEach(fn => fn());
}
update();
if (dev) {
const watcher = chokidar.watch(`${src}/**/*.+(html|js|mjs)`, {
ignoreInitial: true
});
watcher.on('add', update);
watcher.on('change', update);
watcher.on('unlink', update);
}

View File

@@ -1,34 +1,78 @@
const fs = require('fs');
const glob = require('glob');
const chokidar = require('chokidar');
const { dev } = require('./config.js');
const templates = glob.sync('*.html', { cwd: 'templates' })
.map(file => {
const template = fs.readFileSync(`templates/${file}`, 'utf-8');
const status = file.replace('.html', '').toLowerCase();
let templates;
if (!/^[0-9x]{3}$/.test(status)) {
throw new Error(`Bad template — should be a valid status code like 404.html, or a wildcard like 2xx.html`);
}
function create_templates() {
templates = glob.sync('*.html', { cwd: 'templates' })
.map(file => {
const template = fs.readFileSync(`templates/${file}`, 'utf-8');
const status = file.replace('.html', '').toLowerCase();
const specificity = (
(status[0] === 'x' ? 0 : 4) +
(status[1] === 'x' ? 0 : 2) +
(status[2] === 'x' ? 0 : 1)
);
const pattern = new RegExp(`^${status.split('').map(d => d === 'x' ? '\\d' : d).join('')}$`);
return {
test: status => pattern.test(status),
specificity,
render(data) {
return template.replace(/%sapper\.(\w+)%/g, (match, key) => {
return key in data ? data[key] : '';
});
if (!/^[0-9x]{3}$/.test(status)) {
throw new Error(`Bad template — should be a valid status code like 404.html, or a wildcard like 2xx.html`);
}
}
})
.sort((a, b) => b.specificity - a.specificity);
const specificity = (
(status[0] === 'x' ? 0 : 4) +
(status[1] === 'x' ? 0 : 2) +
(status[2] === 'x' ? 0 : 1)
);
const pattern = new RegExp(`^${status.split('').map(d => d === 'x' ? '\\d' : d).join('')}$`);
return {
test: status => pattern.test(status),
specificity,
render: data => {
return template.replace(/%sapper\.(\w+)%/g, (match, key) => {
return key in data ? data[key] : '';
});
},
stream: async (res, data) => {
let i = 0;
do {
const start = template.indexOf('%sapper', i);
if (start === -1) {
res.end(template.slice(start));
return;
}
res.write(template.slice(i, start));
const end = template.indexOf('%', start + 1);
if (end === -1) {
throw new Error(`Bad template`); // TODO validate ahead of time
}
const tag = template.slice(start + 1, end);
const match = /sapper\.(\w+)/.exec(tag);
if (!match || !(match[1] in data)) throw new Error(`Bad template`); // TODO ditto
res.write(await data[match[1]]);
i = end + 1;
} while (i < template.length);
}
}
})
.sort((a, b) => b.specificity - a.specificity);
}
create_templates();
if (dev) {
const watcher = chokidar.watch('templates/**.html', {
ignoreInitial: true
});
watcher.on('add', create_templates);
watcher.on('change', create_templates);
watcher.on('unlink', create_templates);
}
exports.render = (status, data) => {
const template = templates.find(template => template.test(status));
@@ -37,7 +81,9 @@ exports.render = (status, data) => {
return `Missing template for status code ${status}`;
};
exports.onchange = fn => {
// TODO in dev mode, keep this updated, and allow
// webpack compiler etc to hook into it
exports.stream = (res, status, data) => {
const template = templates.find(template => template.test(status));
if (template) return template.stream(res, data);
return `Missing template for status code ${status}`;
};

View File

@@ -1,5 +1,6 @@
const fs = require('fs');
const path = require('path');
const chokidar = require('chokidar');
const route_manager = require('../route_manager.js');
const { src, dest, server_routes, dev } = require('../config.js');
@@ -7,7 +8,7 @@ function posixify(file) {
return file.replace(/[\/\\]/g, '/');
}
module.exports = function create_app() {
function create_app() {
const { routes } = route_manager;
function create_client_main() {
@@ -64,7 +65,20 @@ module.exports = function create_app() {
fs.utimesSync(server_routes, new Date(atime.getTime() - 999999), new Date(mtime.getTime() - 999999));
}
// TODO in dev mode, watch files
create_client_main();
create_server_routes();
};
}
if (dev) {
route_manager.onchange(create_app);
const watcher = chokidar.watch(`templates/main.js`, {
ignoreInitial: true
});
watcher.on('add', create_app);
watcher.on('change', create_app);
watcher.on('unlink', create_app);
}
module.exports = create_app;

View File

@@ -1,11 +1,11 @@
const path = require('path');
module.exports = function create_matchers(files) {
return files
const routes = files
.map(file => {
if (/(^|\/|\\)_/.test(file)) return;
const parts = file.replace(/\.(html|js|mjs)$/, '').split(path.sep);
const parts = file.replace(/\.(html|js|mjs)$/, '').split('/'); // glob output is always posix-style
if (parts[parts.length - 1] === 'index') parts.pop();
const id = (
@@ -47,9 +47,31 @@ module.exports = function create_matchers(files) {
})
.filter(Boolean)
.sort((a, b) => {
return (
(a.dynamic.length - b.dynamic.length) || // match static paths first
(b.parts.length - a.parts.length) // match longer paths first
);
let same = true;
for (let i = 0; true; i += 1) {
const a_part = a.parts[i];
const b_part = b.parts[i];
if (!a_part && !b_part) {
if (same) throw new Error(`The ${a.file} and ${b.file} routes clash`);
return 0;
}
if (!a_part) return 1;
if (!b_part) return -1;
const a_is_dynamic = a_part[0] === '[';
const b_is_dynamic = b_part[0] === '[';
if (a_is_dynamic === b_is_dynamic) {
if (!a_is_dynamic) same = false;
continue;
}
return a_is_dynamic ? 1 : -1;
}
});
return routes;
}

View File

@@ -1,7 +1,9 @@
const fs = require('fs');
const path = require('path');
const chalk = require('chalk');
const compilers = require('./compilers.js');
const generate_asset_cache = require('./generate_asset_cache.js');
const { dest } = require('../config.js');
function deferred() {
const d = {};
@@ -24,6 +26,12 @@ module.exports = function create_watcher() {
deferreds.client.promise,
deferreds.server.promise
]).then(([client_stats, server_stats]) => {
const client_info = client_stats.toJson();
fs.writeFileSync(path.join(dest, 'stats.client.json'), JSON.stringify(client_info, null, ' '));
const server_info = server_stats.toJson();
fs.writeFileSync(path.join(dest, 'stats.server.json'), JSON.stringify(server_info, null, ' '));
return generate_asset_cache(
client_stats.toJson(),
server_stats.toJson()

View File

@@ -5,8 +5,13 @@ const templates = require('../templates.js');
const route_manager = require('../route_manager.js');
const { dest } = require('../config.js');
function ensure_array(thing) {
return Array.isArray(thing) ? thing : [thing]; // omg webpack what the HELL are you doing
}
module.exports = function generate_asset_cache(clientInfo, serverInfo) {
const main_file = `/client/${clientInfo.assetsByChunkName.main}`;
const main_file = `/client/${ensure_array(clientInfo.assetsByChunkName.main)[0]}`;
const chunk_files = clientInfo.assets.map(chunk => `/client/${chunk.name}`);
const service_worker = generate_service_worker(chunk_files);
@@ -26,6 +31,11 @@ module.exports = function generate_asset_cache(clientInfo, serverInfo) {
return lookup;
}, {}),
routes: route_manager.routes.reduce((lookup, route) => {
lookup[route.id] = `/client/${ensure_array(clientInfo.assetsByChunkName[route.id])[0]}`;
return lookup;
}, {}),
index,
service_worker
},

View File

@@ -1,6 +1,6 @@
{
"name": "sapper",
"version": "0.2.4",
"version": "0.2.5",
"description": "Military-grade apps, engineered by Svelte",
"main": "lib/index.js",
"bin": {
@@ -11,6 +11,7 @@
},
"dependencies": {
"chalk": "^2.3.0",
"chokidar": "^1.7.0",
"escape-html": "^1.0.3",
"mkdirp": "^0.5.1",
"relative": "^3.0.2",

View File

@@ -5,15 +5,17 @@ const create_routes = require('../../lib/utils/create_routes.js');
describe('create_routes', () => {
it('sorts routes correctly', () => {
const routes = create_routes(['index.html', 'about.html', '[wildcard].html', 'post/[id].html']);
const routes = create_routes(['index.html', 'about.html', '[wildcard].html', 'post/foo.html', 'post/[id].html', 'post/bar.html']);
assert.deepEqual(
routes.map(r => r.file),
[
'about.html',
'index.html',
'post/foo.html',
'post/bar.html',
'post/[id].html',
'[wildcard].html'
'about.html',
'[wildcard].html',
'index.html'
]
);
});
@@ -48,4 +50,25 @@ describe('create_routes', () => {
]
);
});
it('matches /foo/:bar before /:baz/qux', () => {
const a = create_routes(['foo/[bar].html', '[baz]/qux.html']);
const b = create_routes(['[baz]/qux.html', 'foo/[bar].html']);
assert.deepEqual(
a.map(r => r.file),
['foo/[bar].html', '[baz]/qux.html']
);
assert.deepEqual(
b.map(r => r.file),
['foo/[bar].html', '[baz]/qux.html']
);
});
it('fails if routes are indistinguishable', () => {
assert.throws(() => {
create_routes(['[foo].html', '[bar]/index.html']);
}, /The \[foo\].html and \[bar\]\/index.html routes clash/);
});
});

View File

@@ -1,5 +1,4 @@
const path = require('path');
const route_manager = require('../lib/route_manager.js');
const { src, dest, dev, server_routes } = require('../lib/config.js');
module.exports = {

173
yarn.lock
View File

@@ -112,7 +112,7 @@ ajv@^4.9.1:
co "^4.6.0"
json-stable-stringify "^1.0.1"
ajv@^5.1.5, ajv@^5.2.3, ajv@^5.3.0:
ajv@^5.1.0, ajv@^5.1.5, ajv@^5.2.3, ajv@^5.3.0:
version "5.5.2"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
dependencies:
@@ -273,7 +273,11 @@ aws-sign2@~0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f"
aws4@^1.2.1:
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
aws4@^1.2.1, aws4@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
@@ -334,6 +338,18 @@ boom@2.x.x:
dependencies:
hoek "2.x.x"
boom@4.x.x:
version "4.3.1"
resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31"
dependencies:
hoek "4.x.x"
boom@5.x.x:
version "5.2.0"
resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02"
dependencies:
hoek "4.x.x"
brace-expansion@^1.1.7:
version "1.1.8"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
@@ -439,10 +455,6 @@ caller-path@^0.1.0:
dependencies:
callsites "^0.2.0"
caller@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/caller/-/caller-1.0.1.tgz#b851860f70e195db3d277395aa1a7e23ea30ecf5"
callsites@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca"
@@ -633,7 +645,7 @@ constants-browserify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75"
core-js@^2.4.0:
core-js@^2.4.0, core-js@^2.4.1:
version "2.5.3"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e"
@@ -682,6 +694,12 @@ cryptiles@2.x.x:
dependencies:
boom "2.x.x"
cryptiles@3.x.x:
version "3.1.2"
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe"
dependencies:
boom "5.x.x"
crypto-browserify@^3.11.0:
version "3.12.0"
resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec"
@@ -1136,7 +1154,7 @@ expand-range@^1.8.1:
dependencies:
fill-range "^2.1.0"
extend@~3.0.0:
extend@~3.0.0, extend@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
@@ -1264,6 +1282,14 @@ form-data@~2.1.1:
combined-stream "^1.0.5"
mime-types "^2.1.12"
form-data@~2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf"
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.5"
mime-types "^2.1.12"
from@~0:
version "0.1.7"
resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe"
@@ -1402,6 +1428,10 @@ har-schema@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e"
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
har-validator@~4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a"
@@ -1409,6 +1439,13 @@ har-validator@~4.2.1:
ajv "^4.9.1"
har-schema "^1.0.5"
har-validator@~5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd"
dependencies:
ajv "^5.1.0"
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"
@@ -1458,6 +1495,15 @@ hawk@3.1.3, hawk@~3.1.3:
hoek "2.x.x"
sntp "1.x.x"
hawk@~6.0.2:
version "6.0.2"
resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038"
dependencies:
boom "4.x.x"
cryptiles "3.x.x"
hoek "4.x.x"
sntp "2.x.x"
he@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
@@ -1474,6 +1520,10 @@ hoek@2.x.x:
version "2.16.3"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
hoek@4.x.x:
version "4.2.0"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
hosted-git-info@^2.1.4:
version "2.5.0"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c"
@@ -1490,6 +1540,14 @@ http-signature@~1.1.0:
jsprim "^1.2.2"
sshpk "^1.7.0"
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
dependencies:
assert-plus "^1.0.0"
jsprim "^1.2.2"
sshpk "^1.7.0"
https-browserify@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
@@ -1717,6 +1775,10 @@ isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
isemail@2.x.x:
version "2.2.1"
resolved "https://registry.yarnpkg.com/isemail/-/isemail-2.2.1.tgz#0353d3d9a62951080c262c2aa0a42b8ea8e9e2a6"
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@@ -1731,6 +1793,20 @@ isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
items@2.x.x:
version "2.1.1"
resolved "https://registry.yarnpkg.com/items/-/items-2.1.1.tgz#8bd16d9c83b19529de5aea321acaada78364a198"
joi@^9.2.0:
version "9.2.0"
resolved "https://registry.yarnpkg.com/joi/-/joi-9.2.0.tgz#3385ac790192130cbe230e802ec02c9215bbfeda"
dependencies:
hoek "4.x.x"
isemail "2.x.x"
items "2.x.x"
moment "2.x.x"
topo "2.x.x"
js-tokens@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b"
@@ -2001,7 +2077,7 @@ mime-db@~1.30.0:
version "1.30.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01"
mime-types@^2.1.12, mime-types@~2.1.7:
mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.7:
version "2.1.17"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a"
dependencies:
@@ -2060,6 +2136,10 @@ mocha@^4.0.1:
mkdirp "0.5.1"
supports-color "4.4.0"
moment@2.x.x:
version "2.20.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.20.1.tgz#d6eb1a46cbcc14a2b2f9434112c1ff8907f313fd"
ms@0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098"
@@ -2179,7 +2259,7 @@ number-is-nan@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
oauth-sign@~0.8.1:
oauth-sign@~0.8.1, oauth-sign@~0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
@@ -2371,6 +2451,10 @@ performance-now@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5"
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
pify@^2.0.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
@@ -2453,6 +2537,10 @@ qs@~6.4.0:
version "6.4.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233"
qs@~6.5.1:
version "6.5.1"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
querystring-es3@^0.2.0:
version "0.2.1"
resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73"
@@ -2605,16 +2693,37 @@ request@2.81.0:
tunnel-agent "^0.6.0"
uuid "^3.0.0"
request@^2.78.0:
version "2.83.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356"
dependencies:
aws-sign2 "~0.7.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.3.1"
har-validator "~5.0.3"
hawk "~6.0.2"
http-signature "~1.2.0"
is-typedarray "~1.0.0"
isstream "~0.1.2"
json-stringify-safe "~5.0.1"
mime-types "~2.1.17"
oauth-sign "~0.8.2"
performance-now "^2.1.0"
qs "~6.5.1"
safe-buffer "^5.1.1"
stringstream "~0.0.5"
tough-cookie "~2.3.3"
tunnel-agent "^0.6.0"
uuid "^3.1.0"
require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
require-inject@^1.4.2:
version "1.4.2"
resolved "https://registry.yarnpkg.com/require-inject/-/require-inject-1.4.2.tgz#e7abe7fb0a9a8699bc6b729fc74a4e6eb63db580"
dependencies:
caller "^1.0.1"
require-main-filename@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1"
@@ -2683,6 +2792,10 @@ rx-lite@*, rx-lite@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444"
rx@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782"
rxjs@^5.0.0-beta.11:
version "5.5.5"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.5.tgz#e164f11d38eaf29f56f08c3447f74ff02dd84e97"
@@ -2755,6 +2868,12 @@ sntp@1.x.x:
dependencies:
hoek "2.x.x"
sntp@2.x.x:
version "2.1.0"
resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8"
dependencies:
hoek "4.x.x"
source-list-map@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085"
@@ -2861,7 +2980,7 @@ string_decoder@^1.0.0, string_decoder@~1.0.3:
dependencies:
safe-buffer "~5.1.0"
stringstream@~0.0.4:
stringstream@~0.0.4, stringstream@~0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
@@ -2979,7 +3098,13 @@ to-arraybuffer@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
tough-cookie@~2.3.0:
topo@2.x.x:
version "2.0.2"
resolved "https://registry.yarnpkg.com/topo/-/topo-2.0.2.tgz#cd5615752539057c0dc0491a621c3bc6fbe1d182"
dependencies:
hoek "4.x.x"
tough-cookie@~2.3.0, tough-cookie@~2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
dependencies:
@@ -3055,7 +3180,7 @@ util@0.10.3, util@^0.10.3:
dependencies:
inherits "2.0.1"
uuid@^3.0.0:
uuid@^3.0.0, uuid@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.1.0.tgz#3dd3d3e790abc24d7b0d3a034ffababe28ebbc04"
@@ -3080,6 +3205,16 @@ vm-browserify@0.0.4:
dependencies:
indexof "0.0.1"
wait-on@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/wait-on/-/wait-on-2.0.2.tgz#0a84fd07024c6fc268cb0eabe585be217aaf2baa"
dependencies:
core-js "^2.4.1"
joi "^9.2.0"
minimist "^1.2.0"
request "^2.78.0"
rx "^4.1.0"
watchpack@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.4.0.tgz#4a1472bcbb952bd0a9bb4036801f954dfb39faac"