Compare commits

...

14 Commits

35 changed files with 1274 additions and 574 deletions

3
.gitignore vendored
View File

@ -1,4 +1,5 @@
node_modules/
public/
**/*.log
**/*.log
config.json

125
README.md
View File

@ -21,7 +21,9 @@ An attempt at a viable alternative to Goodreads (currently lacking a name—idea
- [Mirror Repo on GitHub](https://github.com/Alamantus/book-tracker)
- Gets changes from GitLab pushed to it so people who prefer GitHub can contribute there as well. Pull requests and issues created here will also be addressed.
## Installation
## Development
### Installation
To develop, you'll need to know how to use a terminal or shell on your computer.
@ -37,14 +39,131 @@ Then run use [Yarn](https://yarnpkg.com) to install the dependencies:
yarn
```
Alternatively, you can use the NPM that's included with Node:
```
npm install
```
This install process will compile the sass into CSS at `public/css/index.css` and turn the svg in `images`
into PNGs in `public/images` after the dependencies are installed. (Note: This runs even if you install new packages.)
In the future, this postinstall process will also set up the database tables.
## Usage
After everything's installed, run the "start" NPM script to build and serve the front end:
```
npm run start
npm start
```
Then use your browser to navigate to http://localhost:1234 to view the website.
It's early days, so this segment will definitely change later as the project gets more complex.
When you make a change, you need to stop the server with `Ctrl+C` and re-run the script.
It's early days, so this segment will definitely change later as the project gets more complex.
---
## Production
This is totally not yet ready, but I want to use this space to block out what how I would like the installation process
to go for people installing the app.
### Requirements
- NodeJS v8.14+
- NPM v6.4.1+
- NGINX
- PostgreSQL 11+
### Recommendations
- Use a Debian 9 server for stability. Ubuntu should also work just fine.
- Use the default apt packages for the requirements
- Use Git to download the project for installation and easy upgrading
### Installation
Here's a step-by-step installation process so you can get a grasp of what you need to do from a brand new
Debian 9 installation (not included in steps). Ubuntu installation should be more or less exactly the same.
#### Step 1: Install Requirements
Install the requirements with the following commands (note: you may need to use `sudo` for each of these commands):
```
sudo apt update
sudo apt install nodejs nginx postgres-11
```
And optionally (but recommended):
```
sudo apt install git
```
Follow any instructions during each of the installations to get the programs set up correctly.
NGINX may require additional setup, so check through [this page](https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-debian-9) for different things that might be good to do.
PostgreSQL will need a database created, so do that and make a user that can access it that's not the root user.
#### Step 2: Download the Project
You can set up the project folder in any location on your server, but these instructions will set it up in
the current user's home folder using Git like so:
```
cd ~
git clone https://gitlab.com/Alamantus/book-tracker.git && cd book-tracker
```
This will download the entire project source code into a `book-tracker` folder.
#### Step 3: Configure the Project
Next, There are some configurations you need to set up. Rename the `config.example.json` to `config.json` like so:
```
mv config.example.json config.json
```
And edit its contents with the correct data for your server using your text editor of choice. Here is what
the `config.example.json` looks like with some explanations of each field:
```
{
"port": 3000 # the port that the server will serve the app from.
"dbhost": "localhost" # Where the postgres server is
"dbport": 5432 # What port the postgres server uses
"dbname": "book-tracker" # The name of the database book-tracker will use to make tables and store data in
"dbuser": "root" # The username with access to your postgres database
"dbpass": "password" # The password for the username above
... # more to come
}
```
#### Step 4: Install the Project
You will then need to install the project.
```
sudo npm install
```
This will install all of the dependencies, compile all of the Sass into usable CSS, set up the database and tables in PostgreSQL,
and do any other things that need to be done to get the project set up and usable.
#### Step 5: Run it!
Run the following to start the server:
```
sudo npm start-production
```
Then it'll be running on your server's localhost at the port you specified in the config!
#### Step 6: Set up an NGINX reverse proxy
Set up a reverse proxy to your localhost:proxy. This'll have to get filled in later.

6
config.example.json Normal file
View File

@ -0,0 +1,6 @@
{
"port": 3000,
"siteName": "book-tracker",
"jwtSecretKey": "SomethingAtLeast32CharactersLong!",
"tokenExpireDays": 7
}

148
controllers/search.js Normal file
View File

@ -0,0 +1,148 @@
const fetch = require('node-fetch');
class SearchController {
constructor(searchTerm) {
this.term = searchTerm;
}
get hasQuery() {
return typeof this.term !== 'undefined' && this.term !== '';
}
/**
* Query a MediaWiki api.php instance with the given options
*/
mediaWikiQuery(endpoint, options) {
/**
* Create a uniquely-named callback that will process the JSONP results
*/
var createCallback = function (k) {
var i = 1;
var callbackName;
do {
callbackName = 'searchCallback' + i;
i = i + 1;
} while (window[callbackName])
window[callbackName] = k;
return callbackName;
}
/**
* Flatten an object into a URL query string.
* For example: { foo: 'bar', baz: 42 } becomes 'foo=bar&baz=42'
*/
var queryStr = function (options) {
var query = [];
for (var i in options) {
if (options.hasOwnProperty(i)) {
query.push(encodeURIComponent(i) + '=' + encodeURIComponent(options[i]));
}
}
return query.join('&');
}
/**
* Build a function that can be applied to a callback. The callback processes
* the JSON results of the API call.
*/
return function (k) {
options.format = 'json';
options.callback = createCallback(k);
var script = document.createElement('script');
script.id = 'searchResults';
script.src = endpoint + '?' + queryStr(options);
var head = document.getElementsByTagName('head')[0];
head.appendChild(script);
};
}
async searchWikiBooks(term) {
if (!this.hasQuery) {
return [];
}
const query = this.mediaWikiQuery('https://en.wikibooks.org/w/api.php', {
action: 'query',
list: 'search',
srsearch: this.term,
srprop: '',
});
query(response => {
console.log(response);
const searchScript = document.getElementById('searchResults');
searchScript.parentNode.removeChild(searchScript);
for (let property in window) {
if (property.includes('searchCallback')) {
delete window[property];
}
}
const bookResults = [];
const pageids = response.query.search.map(item => item.pageid);
const propsQuery = this.mediaWikiQuery('https://en.wikibooks.org/w/api.php', {
action: 'query',
pageids: pageids.join('|'),
prop: 'categories|pageprops',
});
propsQuery(propsResponse => {
console.log(propsResponse);
for (let pageid in propsResponse.query.pages) {
if (propsResponse.query.pages[pageid].hasOwnProperty('categories')) {
}
}
});
return bookResults;
});
}
async searchOpenLibrary() {
if (!this.hasQuery) {
return [];
}
return fetch('http://openlibrary.org/search.json?q=' + encodeURIComponent(this.term))
.then(res => res.json())
.then(response => {
if (!response.hasOwnProperty('docs')) {
return [];
}
// Format the response into usable objects
const docs = response.docs.map(doc => {
return {
title: doc.title_suggest.trim(),
authors: doc.hasOwnProperty('author_name') ? doc.author_name.map(name => name.trim()) : [],
cover: doc.hasOwnProperty('cover_i') ? `//covers.openlibrary.org/b/id/${doc.cover_i}-S.jpg` : false,
};
});
// Filter out duplicate items with the same title and author
const results = docs.filter((doc, index, allDocs) => {
return typeof allDocs.find((filterResult, filterIndex) => {
return index !== filterIndex && filterResult.title === doc.title
&& JSON.stringify(filterResult.authors) === JSON.stringify(doc.authors);
}) === 'undefined';
}).map(result => {
// Find any duplicates in case they have different cover data
const duplicates = docs.filter(doc => {
return doc.title.toLowerCase() === result.title.toLowerCase() && JSON.stringify(doc.authors) === JSON.stringify(result.authors);
});
result.covers = [];
duplicates.forEach(duplicate => {
if (duplicate.cover !== false) {
result.covers.push(duplicate.cover);
}
});
return result;
});
return results;
}).catch(error => {
console.log(error);
return [];
});
}
}
module.exports = SearchController;

1
images/book-pile.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" style="height: 512px; width: 512px;"><path d="M0 0h512v512H0z" fill="#000" fill-opacity="1"></path><g class="" transform="translate(0,0)" style="touch-action: none;"><path d="M341.79 95.5L65.54 166.379l127.84 58.11 276.025-72.64L341.789 95.5zm-1.577 18.984l74.858 33.059-72.551 19.09-77.258-32.916 74.951-19.233zm142.813 52.395L194.864 242.71l-3.057.805h-.002l-.041.01-2.857-1.3L44.73 178.15l-.184-.092c-5.585-2.793-8.012-1.992-10.77.11-2.757 2.1-5.515 6.88-6.275 12.956-1.519 12.153 3.616 27.58 23.916 34.346l.412.139L193.338 288.5l173.235-45.588V212.45l76-18.345v28.806l42.173-11.097c-4.36-14.037-5.33-29.146-1.72-44.934zm-58.453 50.086l-40 9.656v103.186l21.947-21.948 18.053 12.498V216.965zm58.453 13.914l-40.453 10.646v45.385l42.173-11.098c-4.36-14.036-5.33-29.145-1.72-44.933zM38.42 240.268c-1.803.036-3.177.782-4.642 1.898-2.758 2.101-5.516 6.88-6.276 12.957-1.519 12.153 3.616 27.579 23.916 34.346l.412.138L193.338 352.5l173.235-45.588v-45.387l-174.766 45.99-146.62-65.161a61.602 61.602 0 0 1-4.802-1.874 8.317 8.317 0 0 0-1.965-.212zm6.768 2.086l.021.008-.279-.125.258.117zm437.838 52.525l-40.453 10.646v45.385l42.173-11.097c-4.36-14.037-5.33-29.146-1.72-44.934zM38.42 304.268c-1.803.036-3.177.782-4.642 1.898-2.758 2.101-5.516 6.88-6.276 12.957-1.519 12.153 3.616 27.579 23.916 34.346l.412.138L193.338 416.5l173.235-45.588v-45.387l-174.766 45.99-146.62-65.161a61.602 61.602 0 0 1-4.802-1.874 8.317 8.317 0 0 0-1.965-.212zm6.768 2.086l.021.008-.279-.125.258.117zm363.437 24.855l-38.863 38.863 68.834-18.115-29.97-20.748z" fill="#1c4aff" fill-opacity="1"></path></g></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -7,25 +7,32 @@
"author": "Robbie Antenesse <dev@alamantus.com>",
"license": "MIT",
"scripts": {
"start": "npm run compile-sass && npm run start-server",
"start-server": "node server.js",
"compile-sass": "node process-styles.js"
"postinstall": "npm run process-images && npm run compile-sass",
"start": "node server.js",
"start-production": "cross-env NODE_ENV=production npm start",
"compile-sass": "node process-styles.js",
"process-images": "node process-images.js"
},
"devDependencies": {
"autoprefixer": "^9.6.1",
"cssnano": "^4.1.10",
"sass": "^1.23.0-module.beta.1"
"sass": "^1.23.0-module.beta.1",
"sharp": "^0.23.0"
},
"dependencies": {
"cross-env": "^5.2.1",
"fastify": "^2.8.0",
"fastify-caching": "^5.0.0",
"fastify-compress": "^0.11.0",
"fastify-cookie": "^3.1.0",
"fastify-formbody": "^3.1.0",
"fastify-helmet": "^3.0.1",
"fastify-jwt": "^1.0.0",
"fastify-static": "^2.5.0",
"handlebars": "^4.2.0",
"html-minifier": "^4.0.0",
"make-promises-safe": "^5.0.0",
"node-fetch": "^2.6.0",
"picnic": "^6.5.1",
"point-of-view": "^3.5.0"
}

53
process-images.js Normal file
View File

@ -0,0 +1,53 @@
const fs = require('fs');
const sharp = require('sharp');
const folder = './public/images/';
if (!fs.existsSync('./public')) {
fs.mkdirSync('./public');
}
if (!fs.existsSync('./public/images')) {
fs.mkdirSync('./public/images');
}
const favicon = sharp('./images/book-pile.svg');
// sharp('./src/images/social.jpg').toFile(folder + 'social.jpg', (err, info) => {
// if (err) return console.error(err);
// console.log(info);
// });
favicon.clone().resize(32, 32).toFile(folder + 'favicon.png', (err, info) => {
if (err) return console.error(err);
console.log(info);
});
favicon.clone().resize(128, 128).toFile(folder + 'icon-128.png', (err, info) => {
if (err) return console.error(err);
console.log(info);
});
favicon.clone().resize(144, 144).toFile(folder + 'icon-144.png', (err, info) => {
if (err) return console.error(err);
console.log(info);
});
favicon.clone().resize(152, 152).toFile(folder + 'icon-152.png', (err, info) => {
if (err) return console.error(err);
console.log(info);
});
favicon.clone().resize(192, 192).toFile(folder + 'icon-192.png', (err, info) => {
if (err) return console.error(err);
console.log(info);
});
favicon.clone().resize(256, 256).toFile(folder + 'icon-256.png', (err, info) => {
if (err) return console.error(err);
console.log(info);
});
favicon.clone().resize(512, 512).toFile(folder + 'icon-512.png', (err, info) => {
if (err) return console.error(err);
console.log(info);
});

View File

@ -21,6 +21,12 @@ sass.render({ file: 'index.scss' }, function (sassErr, css) {
console.warn(warn.toString());
});
if (!fs.existsSync('public')) {
fs.mkdirSync('public');
}
if (!fs.existsSync('public/css')) {
fs.mkdirSync('public/css');
}
fs.writeFile('public/css/index.css', result.css, (fileErr) => {
if (fileErr) {
throw fileErr;

29
routes/account.js Normal file
View File

@ -0,0 +1,29 @@
async function routes(fastify, options) {
fastify.get('/login', async (request, reply) => {
reply.view('login.hbs', { text: request.isLoggedInUser ? JSON.stringify(fastify.jwt.decode(request.cookies.token)) : 'you are NOT logged in' });
});
fastify.post('/login-validate', async (request, reply) => {
if (typeof request.body.email === "undefined" || typeof request.body.password === "undefined") {
reply.redirect('/login', 400);
}
const token = fastify.jwt.sign({ email: request.body.email, password: request.body.password });
const expireTime = fastify.siteConfig.tokenExpireDays * (24 * 60 * 60e3); // The section in parentheses is milliseconds in a day
reply
.setCookie('token', token, {
path: '/',
expires: new Date(Date.now() + expireTime),
maxAge: new Date(Date.now() + expireTime), // Both are set as a "just in case"
httpOnly: true, // Prevents JavaScript on the front end from grabbing it
sameSite: true, // Prevents the cookie from being used outside of this site
})
.redirect('/', 200);
});
fastify.get('/logout', async (request, reply) => {
reply.clearCookie('token', { path: '/' }).redirect('/?loggedout');
});
}
module.exports = routes

View File

@ -1,16 +1,17 @@
async function routes(fastify, options) {
fastify.get('/', async (request, reply) => {
// return { hello: 'world' }
reply.view('home.hbs', { text: 'test' });
const viewData = {};
if (typeof request.query.loggedOut !== 'undefined') {
viewData.message = 'You have been logged out';
} else {
viewData.message = request.isLoggedInUser ? JSON.stringify(fastify.jwt.decode(request.cookies.token)) : 'you are NOT logged in';
}
if (request.isLoggedInUser) {
viewData.loggedIn = true;
viewData.statuses = [{ title: 'books' }, { title: 'fun' }];
}
reply.view('home.hbs', viewData);
});
// fastify.get('/search/:id', async function (request, reply) {
// const result = await collection.findOne({ id: request.params.id })
// if (result.value === null) {
// throw new Error('Invalid value')
// }
// return result.value
// })
}
module.exports = routes

View File

@ -3,13 +3,55 @@ async function routes(fastify, options) {
reply.sendFile('css/' + request.params.css);
});
// fastify.get('/search/:id', async function (request, reply) {
// const result = await collection.findOne({ id: request.params.id })
// if (result.value === null) {
// throw new Error('Invalid value')
// }
// return result.value
// })
fastify.get('/images/:image', async (request, reply) => {
reply.sendFile('images/' + request.params.image);
});
fastify.get('/manifest.webmanifest', async (request, reply) => {
const manifest = {
name: typeof fastify.siteConfig !== 'undefined' ? fastify.siteConfig.siteName : 'name not configured',
short_name: typeof fastify.siteConfig !== 'undefined' ? fastify.siteConfig.siteName : 'name not configured',
icons: [
{
src: '/images/icon-128.png',
sizes: '128x128',
type: 'image/png',
},
{
src: '/images/icon-144.png',
sizes: '144x144',
type: 'image/png',
},
{
src: '/images/icon-152.png',
sizes: '152x152',
type: 'image/png',
},
{
src: '/images/icon-192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: '/images/icon-256.png',
sizes: '256x256',
type: 'image/png',
},
{
src: '/images/icon-512.png',
sizes: '512x512',
type: 'image/png',
}
],
start_url: '/',
display: 'standalone',
orientation: 'portrait',
background_color: '#000000',
theme_color: '#1C4AFF',
};
return JSON.stringify(manifest);
});
}
module.exports = routes

13
routes/search.js Normal file
View File

@ -0,0 +1,13 @@
const SearchController = require('../controllers/search');
async function routes(fastify, options) {
fastify.get('/search', async (request, reply) => {
const searchTerm = typeof request.query.for !== 'undefined' ? request.query.for.trim() : '';
const search = new SearchController(searchTerm);
const results = await search.searchOpenLibrary();
reply.view('search.hbs', { results, searchTerm, arbitraryContent: request.isLoggedInUser ? JSON.stringify(fastify.jwt.decode(request.cookies.token)) : 'you are NOT logged in' });
});
}
module.exports = routes

View File

@ -3,45 +3,45 @@
require('make-promises-safe'); // installs an 'unhandledRejection' handler
const path = require('path');
let siteConfig;
try {
siteConfig = require('./config.json');
} catch (ex) {
console.error('Please copy `config.example.json` to `config.json` and fill it with your server\'s data.');
process.exit(1);
}
const fastify = require('fastify')({
logger: true,
logger: process.env.NODE_ENV !== 'production',
});
fastify.register(require('fastify-helmet'));
fastify.register(require('fastify-compress'));
fastify.register(require('fastify-formbody'));
fastify.register(require('fastify-static'), {
root: path.join(__dirname, 'public'),
fastify.decorate('siteConfig', siteConfig); // Insert siteConfig into global fastify instance
fastify.register(require('fastify-helmet')); // Add security stuff
fastify.register(require('fastify-compress')); // Compress output data for smaller packet delivery
fastify.register(require('fastify-formbody')); // Enable fastify to parse data sent by POST from forms
fastify.register(require('fastify-static'), { // Enable delivering static content efficiently
root: path.join(__dirname, 'public'), // all static content will be delivered from the public/ folder
});
fastify.register(require('point-of-view'), {
engine: {
handlebars: require('handlebars'),
},
templates: 'views',
options: {
useHtmlMinifier: require('html-minifier'),
htmlMinifierOptions: {
removeComments: true,
removeCommentsFromCDATA: true,
collapseWhitespace: true,
collapseBooleanAttributes: true,
removeAttributeQuotes: true,
removeEmptyAttributes: true
},
partials: {
head: 'partials/head.hbs',
header: 'partials/header.hbs',
foot: 'partials/foot.hbs',
footer: 'partials/footer.hbs',
}
},
fastify.register(require('point-of-view'), require('./views/viewSetup')); // Adds the `view()` function to fastify's `reply` objects
fastify.register(require('fastify-cookie')); // Enable reading and setting http-level cookies for the sole purpose of storing login tokens
fastify.register(require('fastify-jwt'), { // Enable creating, parsing, and verifying JSON Web Tokens from the global fastify object
secret: fastify.siteConfig.jwtSecretKey, // The secret key used to generate JWTs. Make it big and random!
});
// Every request, check to see if a valid token exists
fastify.addHook('onRequest', (request, reply, done) => {
request.isLoggedInUser = typeof request.cookies.token !== 'undefined' && fastify.jwt.verify(request.cookies.token);
done();
});
// Routes
fastify.register(require('./routes/resources'));
fastify.register(require('./routes/home'));
fastify.register(require('./routes/account'));
fastify.register(require('./routes/search'));
// Start the server
fastify.listen(3000, function (err, address) {
fastify.listen(fastify.siteConfig.port, function (err, address) {
if (err) {
fastify.log.error(err);
process.exit(1);

View File

@ -1,19 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>book-tracker</title>
<meta name="description" content="An attempt at a viable alternative to Goodreads">
<meta name="keywords" content="books, tracking, lists, bookshelves, bookshelf, rating, reviews, reading">
<link rel="stylesheet" href="index.scss">
<script src="index.js"></script>
</head>
<!-- Choo replaces the body tag with the app. -->
<body></body>
</html>

View File

@ -1,45 +0,0 @@
import choo from 'choo';
import { viewManager } from './views/manager';
const app = choo();
if (process.env.NODE_ENV !== 'production') {
// Only runs in development and will be stripped from production build.
app.use(require('choo-devtools')()); // Exposes `choo` to the console for debugging!
}
// App state and emitters
app.use((state, emitter) => {
// Default state variables
state.currentView = 'home';
state.viewStates = {};
// Listeners
emitter.on('DOMContentLoaded', () => {
// Emitter listeners
emitter.on('render', callback => {
// This is a dirty hack to get the callback to call *after* re-rendering.
if (callback && typeof callback === "function") {
setTimeout(() => {
callback();
}, 50);
}
});
emitter.on('changeView', newView => {
// Change the view and call render. Makes it easier to call within views.
state.currentView = newView;
emitter.emit('render', () => {});
});
});
});
// For the main screen, pass the viewManager function in viewManager.js,
// which is given the app's state from above and the emitter.emit method that
// triggers the app's emitter listeners.
app.route('/', viewManager);
app.route('/:page', viewManager);
app.route('/404', viewManager);
app.mount('body'); // Overwrite the `<body>` tag with the content of the Choo app

View File

@ -1,12 +0,0 @@
export class ViewController {
constructor(state, viewName, defaultState = {}) {
// Store the global app state so it's accessible but out of the way.
this.appState = state;
// Give this view its own state within the appState.
if (!this.appState.viewStates.hasOwnProperty(viewName)) {
this.appState.viewStates[viewName] = defaultState;
}
this.state = this.appState.viewStates[viewName];
}
}

View File

@ -1,23 +0,0 @@
import { ViewController } from '../controller';
export class HomeController extends ViewController {
constructor(state) {
// Super passes state, view name, and default state to ViewController,
// which stores state in this.appState and the view controller's state to this.state
super(state, 'home', {
messages: [
'hello',
'test',
'yay',
],
});
// If using controller methods in an input's onchange or onclick instance,
// either bind the class's 'this' instance to the method first...
// or use `onclick=${() => controller.submit()}` to maintain the 'this' of the class instead.
}
get messages() {
return [...this.state.messages];
}
}

View File

@ -1,41 +0,0 @@
import html from 'choo/html';
import './styles.scss'; // Creates a separate CSS file, but allows better code splitting.
// We'll see if code splitting is worth it in the end or if we should combine everything into `src/index.scss`
import { HomeController } from './controller'; // The controller for this view, where processing should happen.
// This is the view function that is exported and used in the view manager.
export const homeView = (state, emit) => {
const controller = new HomeController(state);
// Returning an array in a view allows non-shared parent HTML elements.
// This one doesn't have the problem right now, but it's good to remember.
return [
html`<section>
<h2 class="subtitle">An attempt at a viable alternative to Goodreads</h2>
<article class="flex two">
<div class="half">
<div class="card">
<header>
<p>Still gotta figure out a design.</p>
</header>
</div>
</div>
<div class="half">
<div class="card">
<header>
<p>It's early days, my friends!</p>
</header>
</div>
</div>
</article>
<article class="test">
${controller.messages.map(message => {
return html`<p>${message}</p>`;
})}
</article>
</section>`,
];
}

View File

@ -1,8 +0,0 @@
.test {
background-color: #dddddd;
padding: 10px;
p {
border: 1px solid #444444;
}
}

View File

@ -1,55 +0,0 @@
import html from 'choo/html';
import { homeView } from './home';
import { searchView } from './search';
export const viewManager = (state, emit) => {
// In viewManager all we are doing is checking the app's state
// and passing the state and emit to the relevant view.
let htmlContent = html`<div>loading</div>`;
switch (state.params.page) {
case 'home':
default: {
htmlContent = homeView(state, emit);
break;
}
case 'search': {
htmlContent = searchView(state, emit);
break;
}
}
// Create a wrapper for view content that includes global header/footer
let view = html`<body>
<header>
<nav>
<div class="brand">
<a href="./">
<h1>Unnamed Book Tracker</h1>
</a>
</div>
<!-- responsive-->
<input id="navMenu" type="checkbox" class="show">
<label for="navMenu" class="burger pseudo button">&#8801;</label>
<div class="menu">
<label style="display: inline-block;">
<input type="text" name="search" placeholder="Search" onchange=${e => {
console.log(encodeURIComponent(e.target.value.trim()));
emit('pushState', '/search?for=' + encodeURIComponent(e.target.value.trim()));
}}>
</label>
<a href="https://gitlab.com/Alamantus/book-tracker" class="pseudo button">Repo</a>
<a href="https://gitter.im/book-tracker/general" class="pseudo button">Chat</a>
</div>
</nav>
</header>
<main class="container">
${htmlContent}
</main>
</body>`;
return view;
}

View File

@ -1,206 +0,0 @@
import { ViewController } from '../controller';
export class SearchController extends ViewController {
constructor(state) {
// Super passes state, view name, and default state to ViewController,
// which stores state in this.appState and the view controller's state to this.state
super(state, 'search', {
done: false,
results: [],
});
// If using controller methods in an input's onchange or onclick instance,
// either bind the class's 'this' instance to the method first...
// or use `onclick=${() => controller.submit()}` to maintain the 'this' of the class instead.
}
get results() {
return [...this.state.results];
}
get hasQuery() {
return this.appState.query.hasOwnProperty('for') && this.appState.query.for.trim() !== '';
}
/**
* Query a MediaWiki api.php instance with the given options
*/
mediaWikiQuery(endpoint, options) {
/**
* Create a uniquely-named callback that will process the JSONP results
*/
var createCallback = function (k) {
var i = 1;
var callbackName;
do {
callbackName = 'searchCallback' + i;
i = i + 1;
} while (window[callbackName])
window[callbackName] = k;
return callbackName;
}
/**
* Flatten an object into a URL query string.
* For example: { foo: 'bar', baz: 42 } becomes 'foo=bar&baz=42'
*/
var queryStr = function (options) {
var query = [];
for (var i in options) {
if (options.hasOwnProperty(i)) {
query.push(encodeURIComponent(i) + '=' + encodeURIComponent(options[i]));
}
}
return query.join('&');
}
/**
* Build a function that can be applied to a callback. The callback processes
* the JSON results of the API call.
*/
return function (k) {
options.format = 'json';
options.callback = createCallback(k);
var script = document.createElement('script');
script.id = 'searchResults';
script.src = endpoint + '?' + queryStr(options);
var head = document.getElementsByTagName('head')[0];
head.appendChild(script);
};
}
search(term) {
const query = this.mediaWikiQuery('https://en.wikibooks.org/w/api.php', {
action: 'query',
list: 'search',
// list: 'categorymembers',
// cmtitle: 'Category:Subject:Books by subject/all books',
srsearch: term,
srprop: '',
// pageids: 20308,
// prop: 'categories|pageprops',
});
query(response => {
console.log(response);
const searchScript = document.getElementById('searchResults');
searchScript.parentNode.removeChild(searchScript);
for (let property in window) {
if (property.includes('searchCallback')) {
delete window[property];
}
}
const bookResults = [];
const pageids = response.query.search.map(item => item.pageid);
const propsQuery = this.mediaWikiQuery('https://en.wikibooks.org/w/api.php', {
action: 'query',
pageids: pageids.join('|'),
prop: 'categories|pageprops',
});
propsQuery(propsResponse => {
console.log(propsResponse);
for (let pageid in propsResponse.query.pages) {
if (propsResponse.query.pages[pageid].hasOwnProperty('categories')) {
}
}
});
// this.state.results = results;
this.state.done = true;
});
// return fetch(`https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch=${term}&format=json&callback=searchCallback`, {
// method: 'GET',
// mode: 'no-cors',
// headers: new Headers(
// {
// "Accept": "text/plain"
// }
// ),
// // body: JSON.stringify({
// // action: 'opensearch',
// // search: term,
// // format: 'json',
// // }),
// })
// .then(res => res.text())
// .then(response => {
// console.log(response);
// // if (response.hasOwnProperty('docs')) {
// // // Format the response into usable objects
// // const docs = response.docs.map(doc => {
// // return {
// // title: doc.title_suggest.trim(),
// // authors: doc.hasOwnProperty('author_name') ? doc.author_name.map(name => name.trim()) : [],
// // cover: doc.hasOwnProperty('cover_i') ? `//covers.openlibrary.org/b/id/${doc.cover_i}-S.jpg` : false,
// // };
// // });
// // // Filter out duplicate items with the same title and author
// // const results = docs.filter((doc, index, allDocs) => {
// // return typeof allDocs.find((filterResult, filterIndex) => {
// // return index !== filterIndex && filterResult.title === doc.title
// // && JSON.stringify(filterResult.authors) === JSON.stringify(doc.authors);
// // }) === 'undefined';
// // }).map(result => {
// // // Find any duplicates in case they have different cover data
// // const duplicates = docs.filter(doc => {
// // return doc.title.toLowerCase() === result.title.toLowerCase() && JSON.stringify(doc.authors) === JSON.stringify(result.authors);
// // });
// // result.covers = [];
// // duplicates.forEach(duplicate => {
// // if (duplicate.cover !== false) {
// // result.covers.push(duplicate.cover);
// // }
// // });
// // return result;
// // });
// // this.state.results = results;
// this.state.done = true;
// // }
// });
}
searchOpenLibrary(term) {
this.state.done = false;
return fetch('http://openlibrary.org/search.json?q=' + encodeURIComponent(term))
.then(res => res.json())
.then(response => {
if (response.hasOwnProperty('docs')) {
// Format the response into usable objects
const docs = response.docs.map(doc => {
return {
title: doc.title_suggest.trim(),
authors: doc.hasOwnProperty('author_name') ? doc.author_name.map(name => name.trim()) : [],
cover: doc.hasOwnProperty('cover_i') ? `//covers.openlibrary.org/b/id/${doc.cover_i}-S.jpg` : false,
};
});
// Filter out duplicate items with the same title and author
const results = docs.filter((doc, index, allDocs) => {
return typeof allDocs.find((filterResult, filterIndex) => {
return index !== filterIndex && filterResult.title === doc.title
&& JSON.stringify(filterResult.authors) === JSON.stringify(doc.authors);
}) === 'undefined';
}).map(result => {
// Find any duplicates in case they have different cover data
const duplicates = docs.filter(doc => {
return doc.title.toLowerCase() === result.title.toLowerCase() && JSON.stringify(doc.authors) === JSON.stringify(result.authors);
});
result.covers = [];
duplicates.forEach(duplicate => {
if (duplicate.cover !== false) {
result.covers.push(duplicate.cover);
}
});
return result;
});
this.state.results = results;
this.state.done = true;
}
});
}
}

View File

@ -1,39 +0,0 @@
import html from 'choo/html';
// We'll see if code splitting is worth it in the end or if we should combine everything into `src/index.scss`
import { SearchController } from './controller'; // The controller for this view, where processing should happen.
// This is the view function that is exported and used in the view manager.
export const searchView = (state, emit) => {
const controller = new SearchController(state);
if (!controller.state.done && controller.hasQuery) {
controller.searchOpenLibrary(state.query.for).then(() => {
emit('render');
});
}
// Returning an array in a view allows non-shared parent HTML elements.
// This one doesn't have the problem right now, but it's good to remember.
return [
html`<section>
<h2 class="subtitle">An attempt at a viable alternative to Goodreads</h2>
<article>
${controller.results.map(result => {
return html`<div class="card">
<header>
${result.covers.map(cover => {
return html`<img src=${cover} />`;
})}
<h1 class="title">${result.title}</h1>
${result.authors.map(author => {
return html`<h2 class="subtitle">${author}</h2>`;
})}
</header>
</div>`;
})}
</article>
</section>`,
];
}

View File

@ -18,6 +18,13 @@ nav {
position: relative;
}
footer nav {
.links {
@extend .brand;
font-weight: unset;
}
}
// External links
// a[href^="http://"]:not([href*="localhost"]):not([href*="guts.plus"]):after,
// a[href^="https://"]:not([href*="localhost"]):not([href*="guts.plus"]):after{

View File

@ -1,28 +1,20 @@
{{> header }}
{{#> layout }}
{{#*inline "page-content-block" }}
<section>
<h2 class="subtitle">An attempt at a viable alternative to Goodreads</h2>
<article class="flex two">
<div class="half">
<div class="card">
<header>
<p>Still gotta figure out a design.</p>
</header>
</div>
</div>
<div class="half">
<div class="card">
<header>
<p>It's early days, my friends!</p>
</header>
</div>
</div>
{{#if message }}
<article class="card" style="background-color:cornflowerblue;color:white;width:100%;">
{{ message }}
</article>
{{/if}}
<article class="test">
{{ text }}
</article>
{{#if loggedIn }}
{{> home-logged-in }}
{{ else }}
{{> home-logged-out }}
{{/if}}
</section>
{{/inline}}
{{> footer }}
{{/layout}}

42
views/layout.hbs Normal file
View File

@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ pageTitle }}</title>
<meta name="description" content="An attempt at a viable alternative to Goodreads">
<meta name="keywords" content="books, tracking, lists, bookshelves, bookshelf, rating, reviews, reading">
<link rel="manifest" href="manifest.webmanifest">
<meta name="theme-color" content="#000000">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="{{ pageTitle }}">
<link rel="apple-touch-icon" href="/images/icon-152.png">
<link rel="shortcut icon" type="image/png" href="/images/favicon.png" />
<link rel="stylesheet" href="/styles/index.css">{{!-- This is controlled by the resources router. --}}
</head>
<body>
{{#> header-block }}
{{> header }}
{{/header-block}}
<main class="container">
{{#> page-content-block }}
{{!-- Wrap the actual page content in {{#*inline "page-content-block"}} to insert it here --}}
{{/page-content-block}}
</main>
{{#> footer-block }}
{{> footer }}
{{/footer-block}}
{{#> scripts-block }}
{{/scripts-block}}
</body>
</html>

23
views/login.hbs Normal file
View File

@ -0,0 +1,23 @@
{{#> layout }}
{{#*inline "page-content-block" }}
<section>
<article class="card">
<form action="/login-validate" method="POST">
<label>
<span>Email</span>
<input type="email" name="email">
</label>
<label>
<span>Password</span>
<input type="password" name="password">
</label>
<input type="submit" value="Log In!">
</form>
</article>
</section>
{{/inline}}
{{/layout}}

View File

@ -1,7 +0,0 @@
<script>
(function() {
alert('test');
})();
</script>
</body>
</html>

View File

@ -1,7 +1,8 @@
</main>
<footer>
<p>test footer</p>
<nav>
<div class="links">
<a href="https://gitlab.com/Alamantus/book-tracker" class="pseudo button">Repo</a>
<a href="https://gitter.im/book-tracker/general" class="pseudo button">Chat</a>
</div>
</nav>
</footer>
{{> foot }}

View File

@ -1,15 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ pageTitle }}</title>
<meta name="description" content="An attempt at a viable alternative to Goodreads">
<meta name="keywords" content="books, tracking, lists, bookshelves, bookshelf, rating, reviews, reading">
<link rel="stylesheet" href="/styles/index.css">{{!-- This is controlled by the resources router. --}}
<script src="index.js"></script>
</head>
<body>

View File

@ -1,10 +1,8 @@
{{> head }}
<header>
<nav>
<div class="brand">
<a href="./">
<h1>Unnamed Book Tracker</h1>
<span class="title">Unnamed Book Tracker</span>
</a>
</div>
@ -13,13 +11,13 @@
<label for="navMenu" class="burger pseudo button">&#8801;</label>
<div class="menu">
<label style="display: inline-block;">
<input type="text" id="headerSearchBar" placeholder="Search">
</label>
<a href="https://gitlab.com/Alamantus/book-tracker" class="pseudo button">Repo</a>
<a href="https://gitter.im/book-tracker/general" class="pseudo button">Chat</a>
<form action="/search" style="display: inline-block;">
<label>
<input type="text" id="headerSearchBar" name="for" placeholder="Search" value="{{searchTerm}}">
</label>
</form>
<a href="/login" class="pseudo button">Log In</a>
<a href="/logout" class="pseudo button">Log Out</a>
</div>
</nav>
</header>
<main class="container">

View File

@ -0,0 +1,16 @@
<section>
<h2 class="subtitle">You are logged in!</h2>
{{#each statuses }}
<article class="card">
<header>
<p>A status about {{title}}</p>
</header>
<footer>
<button>Like!</button>
<button class="small dangerous">Dislike!</button>
</footer>
</article>
{{/each}}
</section>

View File

@ -0,0 +1,18 @@
<h2 class="subtitle">An attempt at a viable alternative to Goodreads</h2>
<article class="flex two">
<div class="half">
<div class="card">
<header>
<p>Still gotta figure out a design.</p>
</header>
</div>
</div>
<div class="half">
<div class="card">
<header>
<p>It's early days, my friends!</p>
</header>
</div>
</div>
</article>

37
views/search.hbs Normal file
View File

@ -0,0 +1,37 @@
{{#> layout }}
{{#*inline "page-content-block"}}
<section>
<h2 class="subtitle">An attempt at a viable alternative to Goodreads</h2>
<article>
{{#each results }}
<div class="card">
<header>
{{#each covers }}
<img src="{{this}}" />
{{/each}}
<h1 class="title">{{title}}</h1>
{{#each authors }}
<h2 class="subtitle">{{this}}</h2>
{{/each}}
</header>
</div>
{{/each}}
</article>
</section>
{{/inline}}
{{#*inline "footer-block"}}
{{#if arbitraryContent}}
{{arbitraryContent}}
{{/if}}
{{/inline}}
{{/layout}}

31
views/viewSetup.js Normal file
View File

@ -0,0 +1,31 @@
const fs = require('fs');
const path = require('path');
const partialFiles = fs.readdirSync(path.resolve(__dirname, 'partials')); // This is resolved from *this file's* dirname
const partials = {
layout: 'layout.hbs',
};
partialFiles.forEach(file => {
if (file.includes('.hbs')) {
const name = file.replace('.hbs', '');
partials[name] = `partials/${file}`;
}
});
module.exports = { // Adds the `view()` function to fastify's `reply` objects
engine: {
handlebars: require('handlebars'), // Use handlebar as the render engine for `reply.view()`
},
templates: 'views', // Search for all files referenced in `reply.view()` within the `views/` folder
options: {
useHtmlMinifier: require('html-minifier'), // Add a minifier to the rendered HTML output
htmlMinifierOptions: {
removeComments: true,
removeCommentsFromCDATA: true,
collapseWhitespace: true,
collapseBooleanAttributes: true,
removeEmptyAttributes: true
},
partials, // Specifies the Handlebars Partials so `point-of-view` knows where they are within the `views` folder and what they're called when referenced in a `.hbs` file
},
}

605
yarn.lock
View File

@ -2,6 +2,18 @@
# yarn lockfile v1
"@types/jsonwebtoken@^8.3.2":
version "8.3.3"
resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-8.3.3.tgz#eafeea8239c74b02263d204c0e1175d5cd0bb85f"
integrity sha512-mofwpvFbm2AUxD5mg4iQPc2o/+ubM200R/L86kR17SeC99jM3gEnB9hy16ln3kZkxM5LnGpDJclxeUNEHhehng==
dependencies:
"@types/node" "*"
"@types/node@*":
version "12.7.4"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.4.tgz#64db61e0359eb5a8d99b55e05c729f130a678b04"
integrity sha512-W0+n1Y+gK/8G2P/piTkBBN38Qc5Q1ZSO6B5H3QmPCUewaiXOo2GCAWZ4ElZCcNhjJuBSUSLGFUJnmlCn5+nxOQ==
"@types/q@^1.5.1":
version "1.5.2"
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8"
@ -36,6 +48,16 @@ alphanum-sort@^1.0.0:
resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3"
integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=
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-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
@ -51,11 +73,24 @@ anymatch@^3.0.1:
normalize-path "^3.0.0"
picomatch "^2.0.4"
aproba@^1.0.3:
version "1.2.0"
resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a"
integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==
archy@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40"
integrity sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=
are-we-there-yet@~1.1.2:
version "1.1.5"
resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21"
integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==
dependencies:
delegates "^1.0.0"
readable-stream "^2.0.6"
argparse@^1.0.7:
version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
@ -108,6 +143,13 @@ binary@~0.3.0:
buffers "~0.1.1"
chainsaw "~0.1.0"
bl@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/bl/-/bl-3.0.0.tgz#3611ec00579fd18561754360b21e9f784500ff88"
integrity sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==
dependencies:
readable-stream "^3.0.1"
bluebird@~3.4.1:
version "3.4.7"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.7.tgz#f72d760be09b7f76d08ed8fae98b289a8d05fab3"
@ -147,6 +189,11 @@ browserslist@^4.0.0, browserslist@^4.6.3:
electron-to-chromium "^1.3.247"
node-releases "^1.1.29"
buffer-equal-constant-time@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=
buffer-from@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
@ -240,6 +287,11 @@ chalk@^2.4.1, chalk@^2.4.2:
optionalDependencies:
fsevents "^2.0.6"
chownr@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.2.tgz#a18f1e0b269c8a6a5d3c86eb298beb14c3dd7bf6"
integrity sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==
clean-css@^4.2.1:
version "4.2.1"
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.1.tgz#2d411ef76b8569b6d0c84068dabe85b0aa5e5c17"
@ -261,6 +313,11 @@ coa@^2.0.2:
chalk "^2.4.1"
q "^1.1.2"
code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
color-convert@^1.9.0, color-convert@^1.9.1:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
@ -286,7 +343,7 @@ color-string@^1.5.2:
color-name "^1.0.0"
simple-swizzle "^0.2.2"
color@^3.0.0:
color@^3.0.0, color@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/color/-/color-3.1.2.tgz#68148e7f85d41ad7649c5fa8c8106f098d229e10"
integrity sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==
@ -304,11 +361,21 @@ concat-map@0.0.1:
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
console-control-strings@^1.0.0, console-control-strings@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e"
integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=
content-security-policy-builder@2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/content-security-policy-builder/-/content-security-policy-builder-2.1.0.tgz#0a2364d769a3d7014eec79ff7699804deb8cfcbb"
integrity sha512-/MtLWhJVvJNkA9dVLAp6fg9LxD2gfI6R2Fi1hPmfjYXSahJJzcfvoeDOxSyp4NvxMuwWv3WMssE9o31DoULHrQ==
cookie@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb"
integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=
core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@ -324,6 +391,24 @@ cosmiconfig@^5.0.0:
js-yaml "^3.13.1"
parse-json "^4.0.0"
cross-env@^5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.1.tgz#b2c76c1ca7add66dc874d11798466094f551b34d"
integrity sha512-1yHhtcfAd1r4nwQgknowuUNfIT9E8dOMMspC36g45dN+iD1blloi7xp8X/xAIDnjHWyt1uQ8PHk2fkNaym7soQ==
dependencies:
cross-spawn "^6.0.5"
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"
css-color-names@0.0.4, css-color-names@^0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0"
@ -477,6 +562,18 @@ debug@^4.0.0:
dependencies:
ms "^2.1.1"
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-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==
deepmerge@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.0.0.tgz#3e3110ca29205f120d7cb064960a39c3d2087c09"
@ -489,6 +586,11 @@ define-properties@^1.1.2, define-properties@^1.1.3:
dependencies:
object-keys "^1.0.12"
delegates@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=
depd@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
@ -504,6 +606,11 @@ destroy@~1.0.4:
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=
detect-libc@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
dns-prefetch-control@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/dns-prefetch-control/-/dns-prefetch-control-0.2.0.tgz#73988161841f3dcc81f47686d539a2c702c88624"
@ -574,6 +681,13 @@ duplexify@^4.1.1:
readable-stream "^3.1.1"
stream-shift "^1.0.0"
ecdsa-sig-formatter@1.0.11:
version "1.0.11"
resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf"
integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==
dependencies:
safe-buffer "^5.0.1"
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@ -658,6 +772,11 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
expand-template@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c"
integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==
expect-ct@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/expect-ct/-/expect-ct-0.2.0.tgz#3a54741b6ed34cc7a93305c605f63cd268a54a62"
@ -696,6 +815,13 @@ fast-safe-stringify@^2.0.6:
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz#04b26106cc56681f51a044cfc0d76cf0008ac2c2"
integrity sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==
fastfall@^1.5.0:
version "1.5.1"
resolved "https://registry.yarnpkg.com/fastfall/-/fastfall-1.5.1.tgz#3fee03331a49d1d39b3cdf7a5e9cd66f475e7b94"
integrity sha1-P+4DMxpJ0dObPN96XpzWb0dee5Q=
dependencies:
reusify "^1.0.0"
fastify-caching@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/fastify-caching/-/fastify-caching-5.0.0.tgz#28a3b5d2eaa242cd7f89429f025a339100f02b96"
@ -725,6 +851,14 @@ fastify-compress@^0.11.0:
string-to-stream "^2.0.0"
unzipper "^0.10.1"
fastify-cookie@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/fastify-cookie/-/fastify-cookie-3.1.0.tgz#01c3df5e44ef9feed7b7d25574c8348b8ea10b1d"
integrity sha512-xCy7UJcJcwNBbDPKiczyAvFFTGX9iUgz/7l91N/et97SdbweqYrI3IS8zQLGScWXLm638cvgXPLP7P9w6RYmIg==
dependencies:
cookie "^0.3.1"
fastify-plugin "^1.4.0"
fastify-formbody@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/fastify-formbody/-/fastify-formbody-3.1.0.tgz#604cdafdb9e3af6068e6d9940985baf692d6e922"
@ -754,7 +888,18 @@ fastify-helmet@^3.0.1:
referrer-policy "^1.1.0"
x-xss-protection "^1.1.0"
fastify-plugin@^1.0.0, fastify-plugin@^1.2.1, fastify-plugin@^1.5.0, fastify-plugin@^1.6.0:
fastify-jwt@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fastify-jwt/-/fastify-jwt-1.0.0.tgz#a732abda7ca89e2d7153bea13703177567eb77dd"
integrity sha512-nyRF43KfabpqiB0pke5WfyHH2lIKtytSWf64B3GcJBbIY2nUxJhJKyfm2bZByCu5H26QJrHvH+j9lfn6EfsdcA==
dependencies:
"@types/jsonwebtoken" "^8.3.2"
fastify-plugin "^1.2.0"
http-errors "^1.7.1"
jsonwebtoken "^8.3.0"
steed "^1.1.3"
fastify-plugin@^1.0.0, fastify-plugin@^1.2.0, fastify-plugin@^1.2.1, fastify-plugin@^1.4.0, fastify-plugin@^1.5.0, fastify-plugin@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/fastify-plugin/-/fastify-plugin-1.6.0.tgz#c8198b08608f20c502b5dad26b36e9ae27206d7c"
integrity sha512-lFa9txg8LZx4tljj33oG53nUXhVg0baZxtP9Pxi0dJmI0NQxzkDk5DS9kr3D7iMalUAp3mvIq16OQumc7eIvLA==
@ -791,13 +936,29 @@ fastify@^2.8.0:
secure-json-parse "^1.0.0"
tiny-lru "^6.0.1"
fastq@^1.6.0:
fastparallel@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/fastparallel/-/fastparallel-2.3.0.tgz#1e709bfb6a03993f3857e3ce7f01311ce7602613"
integrity sha1-HnCb+2oDmT84V+POfwExHOdgJhM=
dependencies:
reusify "^1.0.0"
xtend "^4.0.1"
fastq@^1.3.0, fastq@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.6.0.tgz#4ec8a38f4ac25f21492673adb7eae9cfef47d1c2"
integrity sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==
dependencies:
reusify "^1.0.0"
fastseries@^1.7.0:
version "1.7.2"
resolved "https://registry.yarnpkg.com/fastseries/-/fastseries-1.7.2.tgz#d22ce13b9433dff3388d91dbd6b8bda9b21a0f4b"
integrity sha1-0izhO5Qz3/M4jZHb1ri9qbIaD0s=
dependencies:
reusify "^1.0.0"
xtend "^4.0.0"
feature-policy@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/feature-policy/-/feature-policy-0.3.0.tgz#7430e8e54a40da01156ca30aaec1a381ce536069"
@ -847,6 +1008,18 @@ from2@^2.1.1:
inherits "^2.0.1"
readable-stream "^2.0.0"
fs-constants@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
fs-minipass@^1.2.5:
version "1.2.6"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.6.tgz#2c5cc30ded81282bfe8a0d7c7c1853ddeb102c07"
integrity sha512-crhvyXcMejjv3Z5d2Fa9sf5xLYVCF5O1c71QxbVnbLsmYMBEvDAftewesN/HhY03YRoA7zOMxjNGrF5svGaaeQ==
dependencies:
minipass "^2.2.1"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
@ -872,6 +1045,25 @@ function-bind@^1.0.2, function-bind@^1.1.1:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
gauge@~2.7.3:
version "2.7.4"
resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7"
integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=
dependencies:
aproba "^1.0.3"
console-control-strings "^1.0.0"
has-unicode "^2.0.0"
object-assign "^4.1.0"
signal-exit "^3.0.0"
string-width "^1.0.1"
strip-ansi "^3.0.1"
wide-align "^1.1.0"
github-from-package@0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce"
integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=
glob-parent@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.0.0.tgz#1dc99f0f39b006d3e92c2c284068382f0c20e954"
@ -917,6 +1109,11 @@ has-symbols@^1.0.0:
resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44"
integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=
has@^1.0.0, has@^1.0.1, has@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
@ -999,6 +1196,17 @@ html-minifier@^4.0.0:
relateurl "^0.2.7"
uglify-js "^3.5.1"
http-errors@^1.7.1:
version "1.7.3"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06"
integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw==
dependencies:
depd "~1.1.2"
inherits "2.0.4"
setprototypeof "1.1.1"
statuses ">= 1.5.0 < 2"
toidentifier "1.0.0"
http-errors@~1.6.2:
version "1.6.3"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
@ -1035,7 +1243,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3:
inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.0, inherits@~2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@ -1045,6 +1253,11 @@ inherits@2.0.3:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
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==
into-stream@4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-4.0.0.tgz#ef10ee2ffb6f78af34c93194bbdc36c35f7d8a9d"
@ -1117,6 +1330,18 @@ is-extglob@^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@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs=
dependencies:
number-is-nan "^1.0.0"
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@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
@ -1185,6 +1410,11 @@ isarray@~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=
js-yaml@^3.13.1:
version "3.13.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
@ -1203,6 +1433,39 @@ json-schema-traverse@^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==
jsonwebtoken@^8.3.0:
version "8.5.1"
resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d"
integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==
dependencies:
jws "^3.2.2"
lodash.includes "^4.3.0"
lodash.isboolean "^3.0.3"
lodash.isinteger "^4.0.4"
lodash.isnumber "^3.0.3"
lodash.isplainobject "^4.0.6"
lodash.isstring "^4.0.1"
lodash.once "^4.0.0"
ms "^2.1.1"
semver "^5.6.0"
jwa@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a"
integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==
dependencies:
buffer-equal-constant-time "1.0.1"
ecdsa-sig-formatter "1.0.11"
safe-buffer "^5.0.1"
jws@^3.2.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304"
integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==
dependencies:
jwa "^1.4.1"
safe-buffer "^5.0.1"
light-my-request@^3.4.1:
version "3.4.1"
resolved "https://registry.yarnpkg.com/light-my-request/-/light-my-request-3.4.1.tgz#c30087005f6ae64ce5ef92c2484b1ab93c71ad3e"
@ -1216,11 +1479,46 @@ listenercount@~1.0.1:
resolved "https://registry.yarnpkg.com/listenercount/-/listenercount-1.0.1.tgz#84c8a72ab59c4725321480c975e6508342e70937"
integrity sha1-hMinKrWcRyUyFIDJdeZQg0LnCTc=
lodash.includes@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=
lodash.isboolean@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=
lodash.isinteger@^4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343"
integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=
lodash.isnumber@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=
lodash.isplainobject@^4.0.6:
version "4.0.6"
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"
integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=
lodash.isstring@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451"
integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=
lodash.memoize@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
lodash.once@^4.0.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac"
integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=
lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
@ -1276,6 +1574,11 @@ mime@1.4.1:
resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"
integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==
mimic-response@^1.0.0:
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"
@ -1288,6 +1591,11 @@ minimist@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"
@ -1301,7 +1609,22 @@ minipass@2.3.5:
safe-buffer "^5.1.2"
yallist "^3.0.0"
"mkdirp@>=0.5 0", mkdirp@~0.5.1:
minipass@^2.2.1, minipass@^2.3.5:
version "2.5.0"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.5.0.tgz#dddb1d001976978158a05badfcbef4a771612857"
integrity sha512-9FwMVYhn6ERvMR8XFdOavRz4QK/VJV8elU1x50vYexf9lslDcWe/f4HBRxCPd185ekRSjU6CfYyJCECa/CQy7Q==
dependencies:
safe-buffer "^5.1.2"
yallist "^3.0.0"
minizlib@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614"
integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==
dependencies:
minipass "^2.2.1"
"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
@ -1318,11 +1641,26 @@ ms@^2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
nan@^2.14.0:
version "2.14.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c"
integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==
napi-build-utils@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.1.tgz#1381a0f92c39d66bf19852e7873432fc2123e508"
integrity sha512-boQj1WFgQH3v4clhu3mTNfP+vOBxorDlE8EKiMjUlLG3C4qAESnn9AxIOkFgTR2c9LtzNjPrjS60cT27ZKBhaA==
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==
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==
no-case@^2.2.0:
version "2.3.2"
resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac"
@ -1335,6 +1673,18 @@ nocache@^2.0.0:
resolved "https://registry.yarnpkg.com/nocache/-/nocache-2.1.0.tgz#120c9ffec43b5729b1d5de88cd71aa75a0ba491f"
integrity sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==
node-abi@^2.7.0:
version "2.11.0"
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.11.0.tgz#b7dce18815057544a049be5ae75cd1fdc2e9ea59"
integrity sha512-kuy/aEg75u40v378WRllQ4ZexaXJiCvB68D2scDXclp/I4cRq6togpbOoKhmN07tns9Zldu51NNERo0wehfX9g==
dependencies:
semver "^5.4.1"
node-fetch@^2.6.0:
version "2.6.0"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
node-releases@^1.1.29:
version "1.1.29"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.29.tgz#86a57c6587a30ecd6726449e5d293466b0a0bb86"
@ -1342,6 +1692,11 @@ node-releases@^1.1.29:
dependencies:
semver "^5.3.0"
noop-logger@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2"
integrity sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=
normalize-path@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
@ -1357,6 +1712,16 @@ normalize-url@^3.0.0:
resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559"
integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==
npmlog@^4.0.1, npmlog@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
dependencies:
are-we-there-yet "~1.1.2"
console-control-strings "~1.1.0"
gauge "~2.7.3"
set-blocking "~2.0.0"
nth-check@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c"
@ -1369,6 +1734,16 @@ num2fraction@^1.2.2:
resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede"
integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=
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"
integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
object-assign@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
object-inspect@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b"
@ -1444,6 +1819,11 @@ path-is-absolute@^1.0.0:
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
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-to-regexp@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-3.1.0.tgz#f45a9cc4dc6331ae8f131e0ce4fde8607f802367"
@ -1778,6 +2158,27 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.17, postcss@^7.0.5:
source-map "^0.6.1"
supports-color "^6.1.0"
prebuild-install@^5.3.0:
version "5.3.1"
resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.3.1.tgz#7d220b978e03b0e067e0d8cffd13e84b3515131d"
integrity sha512-lRLBU0JPXBbpC/ER9PtVYYk1y9Rme1WiMA3WKEQ4v78A5kTsqQtrEyYlbghvXCA6Uhr/769SkhibQznjDBRZpg==
dependencies:
detect-libc "^1.0.3"
expand-template "^2.0.3"
github-from-package "0.0.0"
minimist "^1.2.0"
mkdirp "^0.5.1"
napi-build-utils "^1.0.1"
node-abi "^2.7.0"
noop-logger "^0.1.1"
npmlog "^4.0.1"
pump "^3.0.0"
rc "^1.2.7"
simple-get "^3.0.3"
tar-fs "^2.0.0"
tunnel-agent "^0.6.0"
which-pm-runs "^1.0.0"
process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
@ -1838,7 +2239,17 @@ range-parser@~1.2.0:
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@~2.3.6:
rc@^1.2.7:
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"
readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@~2.3.6:
version "2.3.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==
@ -1851,7 +2262,7 @@ readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@~2.3.6:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
readable-stream@^3.1.1, readable-stream@^3.4.0:
readable-stream@^3.0.1, readable-stream@^3.1.1, readable-stream@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.4.0.tgz#a51c26754658e0a3c21dbf59163bd45ba6f447fc"
integrity sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==
@ -1914,7 +2325,7 @@ rimraf@2:
dependencies:
glob "^7.1.3"
safe-buffer@^5.1.2, safe-buffer@~5.2.0:
safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
@ -1953,12 +2364,12 @@ semver-store@^0.3.0:
resolved "https://registry.yarnpkg.com/semver-store/-/semver-store-0.3.0.tgz#ce602ff07df37080ec9f4fb40b29576547befbe9"
integrity sha512-TcZvGMMy9vodEFSse30lWinkj+JgOBvPn8wRItpQRSayhc+4ssDs335uklkfvQQJgL/WvmHLVj4Ycv2s7QCQMg==
semver@^5.3.0:
semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
semver@^6.0.0:
semver@^6.0.0, semver@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
@ -1982,6 +2393,11 @@ send@^0.16.0:
range-parser "~1.2.0"
statuses "~1.4.0"
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=
setimmediate@~1.0.4:
version "1.0.5"
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
@ -1992,6 +2408,57 @@ setprototypeof@1.1.0:
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==
setprototypeof@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683"
integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==
sharp@^0.23.0:
version "0.23.0"
resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.23.0.tgz#e34c7c44af219f8fd6b780adaa2b44aa6a22cbd9"
integrity sha512-3+QlktTYDPO9CLmB3DUaBSj729ic3R9TO5Bz318F8WubUW10HR4os0Tm+GdYNcVg0layhMhP4Hf2SILwXVG2ig==
dependencies:
color "^3.1.2"
detect-libc "^1.0.3"
nan "^2.14.0"
npmlog "^4.1.2"
prebuild-install "^5.3.0"
semver "^6.3.0"
simple-get "^3.0.3"
tar "^4.4.10"
tunnel-agent "^0.6.0"
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=
signal-exit@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
simple-concat@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6"
integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=
simple-get@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.0.3.tgz#924528ac3f9d7718ce5e9ec1b1a69c0be4d62efa"
integrity sha512-Wvre/Jq5vgoz31Z9stYWPLn0PqRqmBDpFSdypAnHu5AvRVCYPRYGnvryNLiXu8GOBNDH82J2FRHUGMjjHUpXFw==
dependencies:
decompress-response "^3.3.0"
once "^1.3.1"
simple-concat "^1.0.0"
simple-swizzle@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a"
@ -2026,7 +2493,7 @@ stable@^0.1.8:
resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
"statuses@>= 1.4.0 < 2":
"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2":
version "1.5.0"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=
@ -2036,6 +2503,17 @@ statuses@~1.4.0:
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087"
integrity sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==
steed@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/steed/-/steed-1.1.3.tgz#f1525dd5adb12eb21bf74749537668d625b9abc5"
integrity sha1-8VJd1a2xLrIb90dJU3Zo1iW5q8U=
dependencies:
fastfall "^1.5.0"
fastparallel "^2.2.0"
fastq "^1.3.0"
fastseries "^1.7.0"
reusify "^1.0.0"
stream-shift@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952"
@ -2049,6 +2527,23 @@ string-to-stream@^2.0.0:
inherits "^2.0.1"
readable-stream "^3.4.0"
string-width@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=
dependencies:
code-point-at "^1.0.0"
is-fullwidth-code-point "^1.0.0"
strip-ansi "^3.0.0"
"string-width@^1.0.2 || 2":
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.prototype.trimleft@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.0.0.tgz#68b6aa8e162c6a80e76e3a8a0c2e747186e271ff"
@ -2079,6 +2574,25 @@ string_decoder@~1.1.1:
dependencies:
safe-buffer "~5.1.0"
strip-ansi@^3.0.0, strip-ansi@^3.0.1:
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-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=
stylehacks@^4.0.0:
version "4.0.3"
resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-4.0.3.tgz#6718fcaf4d1e07d8a1318690881e8d96726a71d5"
@ -2121,6 +2635,40 @@ svgo@^1.0.0:
unquote "~1.1.1"
util.promisify "~1.0.0"
tar-fs@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.0.0.tgz#677700fc0c8b337a78bee3623fdc235f21d7afad"
integrity sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==
dependencies:
chownr "^1.1.1"
mkdirp "^0.5.1"
pump "^3.0.0"
tar-stream "^2.0.0"
tar-stream@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.0.tgz#d1aaa3661f05b38b5acc9b7020efdca5179a2cc3"
integrity sha512-+DAn4Nb4+gz6WZigRzKEZl1QuJVOLtAwwF+WUxy1fJ6X63CaGaUAxJRD2KEn1OMfcbCjySTYpNC6WmfQoIEOdw==
dependencies:
bl "^3.0.0"
end-of-stream "^1.4.1"
fs-constants "^1.0.0"
inherits "^2.0.3"
readable-stream "^3.1.1"
tar@^4.4.10:
version "4.4.10"
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.10.tgz#946b2810b9a5e0b26140cf78bea6b0b0d689eba1"
integrity sha512-g2SVs5QIxvo6OLp0GudTqEf05maawKUxXru104iaayWA09551tFCTI8f1Asb4lPfkBr91k07iL4c11XO3/b0tA==
dependencies:
chownr "^1.1.1"
fs-minipass "^1.2.5"
minipass "^2.3.5"
minizlib "^1.2.1"
mkdirp "^0.5.0"
safe-buffer "^5.1.2"
yallist "^3.0.3"
through2@^2.0.3:
version "2.0.5"
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
@ -2146,11 +2694,23 @@ to-regex-range@^5.0.1:
dependencies:
is-number "^7.0.0"
toidentifier@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
"traverse@>=0.3.0 <0.4":
version "0.3.9"
resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9"
integrity sha1-cXuPIgzAu3tE5AUUwisui7xw2Lk=
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"
uglify-js@^3.1.4, uglify-js@^3.5.1:
version "3.6.0"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.0.tgz#704681345c53a8b2079fb6cec294b05ead242ff5"
@ -2226,6 +2786,25 @@ vendors@^1.0.0:
resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.3.tgz#a6467781abd366217c050f8202e7e50cc9eef8c0"
integrity sha512-fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw==
which-pm-runs@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb"
integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=
which@^1.2.9:
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"
wide-align@^1.1.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457"
integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==
dependencies:
string-width "^1.0.2 || 2"
wordwrap@~0.0.2:
version "0.0.3"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107"
@ -2241,12 +2820,12 @@ x-xss-protection@^1.1.0:
resolved "https://registry.yarnpkg.com/x-xss-protection/-/x-xss-protection-1.3.0.tgz#3e3a8dd638da80421b0e9fff11a2dbe168f6d52c"
integrity sha512-kpyBI9TlVipZO4diReZMAHWtS0MMa/7Kgx8hwG/EuZLiA6sg4Ah/4TRdASHhRRN3boobzcYgFRUFSgHRge6Qhg==
xtend@~4.0.1:
xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
yallist@^3.0.0:
yallist@^3.0.0, yallist@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9"
integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==