From 29b8334b060dc0c05a509d523ead4b3a30229fef Mon Sep 17 00:00:00 2001 From: vantezzen Date: Thu, 5 Sep 2019 11:22:49 +0200 Subject: Add eslint --- .eslintrc.js | 22 + app/Controllers/Http/DashboardController.js | 61 +- app/Controllers/Http/RecipeController.js | 159 ++- app/Controllers/Http/ServiceController.js | 200 ++- app/Controllers/Http/StaticController.js | 347 +++--- app/Controllers/Http/UserController.js | 213 ++-- app/Controllers/Http/WorkspaceController.js | 104 +- app/Exceptions/Handler.js | 16 +- app/Middleware/ConvertEmptyStringsToNull.js | 15 +- app/Models/Recipe.js | 5 +- app/Models/Service.js | 11 +- app/Models/Token.js | 5 +- app/Models/Traits/NoTimestamp.js | 9 +- app/Models/User.js | 28 +- app/Models/Workspace.js | 11 +- config/app.js | 23 +- config/auth.js | 17 +- config/bodyParser.js | 21 +- config/cors.js | 5 +- config/database.js | 21 +- config/drive.js | 17 +- config/hash.js | 11 +- config/session.js | 13 +- config/shield.js | 13 +- database/factory.js | 1 - database/migrations/1503250034279_user.js | 23 +- database/migrations/1503250034280_token.js | 25 +- .../migrations/1566385379883_service_schema.js | 27 +- database/migrations/1566554231482_recipe_schema.js | 23 +- .../migrations/1566554359294_workspace_schema.js | 29 +- package-lock.json | 1295 +++++++++++++++++++- package.json | 13 +- public/js/new.js | 9 +- server.js | 8 +- start/app.js | 15 +- start/kernel.js | 13 +- start/routes.js | 116 +- 37 files changed, 2104 insertions(+), 840 deletions(-) create mode 100644 .eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..d02f489 --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,22 @@ +module.exports = { + env: { + commonjs: true, + es6: true, + node: true, + }, + extends: [ + 'airbnb-base', + ], + globals: { + Atomics: 'readonly', + SharedArrayBuffer: 'readonly', + use: 'readonly' + }, + parserOptions: { + ecmaVersion: 2018, + }, + rules: { + "class-methods-use-this": 'off', + "no-restricted-syntax": 'off', + }, +}; diff --git a/app/Controllers/Http/DashboardController.js b/app/Controllers/Http/DashboardController.js index aa8127f..49f6cc0 100644 --- a/app/Controllers/Http/DashboardController.js +++ b/app/Controllers/Http/DashboardController.js @@ -1,7 +1,6 @@ -'use strict' const { - validateAll + validateAll, } = use('Validator'); const crypto = require('crypto'); @@ -11,7 +10,7 @@ class DashboardController { request, response, auth, - session + session, }) { const validation = await validateAll(request.all(), { mail: 'required|email', @@ -20,25 +19,25 @@ class DashboardController { if (validation.fails()) { session.withErrors({ type: 'danger', - message: 'Invalid mail or password' + message: 'Invalid mail or password', }).flashExcept(['password']); return response.redirect('back'); } - let { + const { mail, - password - } = request.all() + password, + } = request.all(); const hashedPassword = crypto.createHash('sha256').update(password).digest('base64'); try { - await auth.authenticator('session').attempt(mail, hashedPassword) + await auth.authenticator('session').attempt(mail, hashedPassword); } catch (error) { session.flash({ type: 'danger', - message: 'Invalid mail or password' - }) + message: 'Invalid mail or password', + }); return response.redirect('back'); } return response.redirect('/user/account'); @@ -46,17 +45,18 @@ class DashboardController { async account({ auth, - view + view, + response, }) { try { - await auth.check() + await auth.check(); } catch (error) { return response.redirect('/user/login'); } return view.render('dashboard.account', { username: auth.user.username, - email: auth.user.email + email: auth.user.email, }); } @@ -65,11 +65,11 @@ class DashboardController { request, session, view, - response + response, }) { let validation = await validateAll(request.all(), { username: 'required', - email: 'required' + email: 'required', }); if (validation.fails()) { session.withErrors(validation.messages()).flashExcept(['password']); @@ -80,19 +80,19 @@ class DashboardController { if (request.input('username') !== auth.user.username) { validation = await validateAll(request.all(), { username: 'required|unique:users,username', - email: 'required' + email: 'required', }); if (validation.fails()) { session.withErrors(validation.messages()).flashExcept(['password']); return response.redirect('back'); } - } + } // Check new email if (request.input('email') !== auth.user.email) { validation = await validateAll(request.all(), { username: 'required', - email: 'required|email|unique:users,email' + email: 'required|email|unique:users,email', }); if (validation.fails()) { session.withErrors(validation.messages()).flashExcept(['password']); @@ -101,24 +101,25 @@ class DashboardController { } // Update user account - auth.user.username = request.input('username'); - auth.user.email = request.input('email'); - if (!!request.input('password')) { + const { user } = auth; + user.username = request.input('username'); + user.email = request.input('email'); + if (request.input('password')) { const hashedPassword = crypto.createHash('sha256').update(request.input('password')).digest('base64'); - auth.user.password = hashedPassword; + user.password = hashedPassword; } - auth.user.save(); + user.save(); return view.render('dashboard.account', { - username: auth.user.username, - email: auth.user.email, - success: true + username: user.username, + email: user.email, + success: true, }); } async data({ auth, - view + view, }) { const general = auth.user; const services = (await auth.user.services().fetch()).toJSON(); @@ -136,7 +137,7 @@ class DashboardController { logout({ auth, - response + response, }) { auth.authenticator('session').logout(); return response.redirect('/user/login'); @@ -144,7 +145,7 @@ class DashboardController { delete({ auth, - response + response, }) { auth.user.delete(); auth.authenticator('session').logout(); @@ -152,4 +153,4 @@ class DashboardController { } } -module.exports = DashboardController +module.exports = DashboardController; diff --git a/app/Controllers/Http/RecipeController.js b/app/Controllers/Http/RecipeController.js index fd9ed83..217b05b 100644 --- a/app/Controllers/Http/RecipeController.js +++ b/app/Controllers/Http/RecipeController.js @@ -1,61 +1,58 @@ -'use strict' const Recipe = use('App/Models/Recipe'); -const Helpers = use('Helpers') -const Drive = use('Drive') +const Helpers = use('Helpers'); +const Drive = use('Drive'); const { - validateAll + validateAll, } = use('Validator'); -const Env = use('Env') +const Env = use('Env'); const fetch = require('node-fetch'); const targz = require('targz'); const path = require('path'); const fs = require('fs-extra'); -const compress = (src, dest) => { - return new Promise((resolve, reject) => { - targz.compress({ - src, - dest - }, function (err) { - if (err) { - reject(err); - } else { - resolve(dest); - } - }); - }) -} +const compress = (src, dest) => new Promise((resolve, reject) => { + targz.compress({ + src, + dest, + }, (err) => { + if (err) { + reject(err); + } else { + resolve(dest); + } + }); +}); class RecipeController { // List official and custom recipes async list({ - response + response, }) { const officialRecipes = JSON.parse(await (await fetch('https://api.franzinfra.com/v1/recipes')).text()); const customRecipesArray = (await Recipe.all()).rows; - const customRecipes = customRecipesArray.map(recipe => ({ - "id": recipe.recipeId, - "name": recipe.name, - ...JSON.parse(recipe.data) - })) + const customRecipes = customRecipesArray.map((recipe) => ({ + id: recipe.recipeId, + name: recipe.name, + ...JSON.parse(recipe.data), + })); const recipes = [ ...officialRecipes, ...customRecipes, - ] + ]; - return response.send(recipes) + return response.send(recipes); } // Create a new recipe using the new.html page async create({ request, - response + response, }) { // Check if recipe creation is enabled - if (Env.get('IS_CREATION_ENABLED') == 'false') { + if (Env.get('IS_CREATION_ENABLED') == 'false') { // eslint-disable-line eqeqeq return response.send('This server doesn\'t allow the creation of new recipes.'); } @@ -69,10 +66,10 @@ class RecipeController { }); if (validation.fails()) { return response.status(401).send({ - "message": "Invalid POST arguments", - "messages": validation.messages(), - "status": 401 - }) + message: 'Invalid POST arguments', + messages: validation.messages(), + status: 401, + }); } const data = request.all(); @@ -90,16 +87,16 @@ class RecipeController { await fs.emptyDir(Helpers.tmpPath('recipe')); // Move uploaded files to temporary path - const files = request.file('files') - await files.moveAll(Helpers.tmpPath('recipe')) + const files = request.file('files'); + await files.moveAll(Helpers.tmpPath('recipe')); // Compress files to .tar.gz file const source = Helpers.tmpPath('recipe'); - const destination = path.join(Helpers.appRoot(), '/recipes/' + data.id + '.tar.gz'); - + const destination = path.join(Helpers.appRoot(), `/recipes/${data.id}.tar.gz`); + compress( source, - destination + destination, ); // Create recipe in db @@ -107,74 +104,73 @@ class RecipeController { name: data.name, recipeId: data.id, data: JSON.stringify({ - "author": data.author, - "featured": false, - "version": "1.0.0", - "icons": { - "png": data.png, - "svg": data.svg - } - }) - }) - - return response.send('Created new recipe') + author: data.author, + featured: false, + version: '1.0.0', + icons: { + png: data.png, + svg: data.svg, + }, + }), + }); + + return response.send('Created new recipe'); } // Search official and custom recipes async search({ request, - response + response, }) { // Validate user input const validation = await validateAll(request.all(), { - needle: 'required' + needle: 'required', }); if (validation.fails()) { return response.status(401).send({ - "message": "Please provide a needle", - "messages": validation.messages(), - "status": 401 - }) + message: 'Please provide a needle', + messages: validation.messages(), + status: 401, + }); } - const needle = request.input('needle') + const needle = request.input('needle'); // Get results let remoteResults = []; - if (Env.get('CONNECT_WITH_FRANZ') == 'true') { - remoteResults = JSON.parse(await (await fetch('https://api.franzinfra.com/v1/recipes/search?needle=' + encodeURIComponent(needle))).text()); + if (Env.get('CONNECT_WITH_FRANZ') == 'true') { // eslint-disable-line eqeqeq + remoteResults = JSON.parse(await (await fetch(`https://api.franzinfra.com/v1/recipes/search?needle=${encodeURIComponent(needle)}`)).text()); } - const localResultsArray = (await Recipe.query().where('name', 'LIKE', '%' + needle + '%').fetch()).toJSON(); - const localResults = localResultsArray.map(recipe => ({ - "id": recipe.recipeId, - "name": recipe.name, - ...JSON.parse(recipe.data) - })) + const localResultsArray = (await Recipe.query().where('name', 'LIKE', `%${needle}%`).fetch()).toJSON(); + const localResults = localResultsArray.map((recipe) => ({ + id: recipe.recipeId, + name: recipe.name, + ...JSON.parse(recipe.data), + })); const results = [ ...localResults, ...remoteResults, - ] + ]; return response.send(results); } // Download a recipe async download({ - request, response, - params + params, }) { // Validate user input const validation = await validateAll(params, { - recipe: 'required|accepted' + recipe: 'required|accepted', }); if (validation.fails()) { return response.status(401).send({ - "message": "Please provide a recipe ID", - "messages": validation.messages(), - "status": 401 - }) + message: 'Please provide a recipe ID', + messages: validation.messages(), + status: 401, + }); } const service = params.recipe; @@ -185,17 +181,16 @@ class RecipeController { } // Check if recipe exists in recipes folder - if (await Drive.exists(service + '.tar.gz')) { - response.send(await Drive.get(service + '.tar.gz')) - } else if(Env.get('CONNECT_WITH_FRANZ') == 'true') { - response.redirect('https://api.franzinfra.com/v1/recipes/download/' + service) - } else { - return response.status(400).send({ - "message": "Recipe not found", - "code": "recipe-not-found" - }) + if (await Drive.exists(`${service}.tar.gz`)) { + response.send(await Drive.get(`${service}.tar.gz`)); + } else if (Env.get('CONNECT_WITH_FRANZ') == 'true') { // eslint-disable-line eqeqeq + response.redirect(`https://api.franzinfra.com/v1/recipes/download/${service}`); } + return response.status(400).send({ + message: 'Recipe not found', + code: 'recipe-not-found', + }); } } -module.exports = RecipeController +module.exports = RecipeController; diff --git a/app/Controllers/Http/ServiceController.js b/app/Controllers/Http/ServiceController.js index e887e3a..309ae09 100644 --- a/app/Controllers/Http/ServiceController.js +++ b/app/Controllers/Http/ServiceController.js @@ -1,9 +1,6 @@ -'use strict' - -const User = use('App/Models/User'); const Service = use('App/Models/Service'); const { - validateAll + validateAll, } = use('Validator'); const uuid = require('uuid/v4'); @@ -13,12 +10,12 @@ class ServiceController { async create({ request, response, - auth + auth, }) { try { - await auth.getUser() + await auth.getUser(); } catch (error) { - return response.send('Missing or invalid api token') + return response.send('Missing or invalid api token'); } // Validate user input @@ -28,10 +25,10 @@ class ServiceController { }); if (validation.fails()) { return response.status(401).send({ - "message": "Invalid POST arguments", - "messages": validation.messages(), - "status": 401 - }) + message: 'Invalid POST arguments', + messages: validation.messages(), + status: 401, + }); } const data = request.all(); @@ -40,83 +37,82 @@ class ServiceController { let serviceId; do { serviceId = uuid(); - } while ((await Service.query().where('serviceId', serviceId).fetch()).rows.length > 0) + } while ((await Service.query().where('serviceId', serviceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop - const service = await Service.create({ + await Service.create({ userId: auth.user.id, serviceId, name: data.name, recipeId: data.recipeId, - settings: JSON.stringify(data) + settings: JSON.stringify(data), }); return response.send({ - "data": { + data: { userId: auth.user.id, id: serviceId, - "isEnabled": true, - "isNotificationEnabled": true, - "isBadgeEnabled": true, - "isMuted": false, - "isDarkModeEnabled": "", - "spellcheckerLanguage": "", - "order": 1, - "customRecipe": false, - "hasCustomIcon": false, - "workspaces": [], - "iconUrl": null, + isEnabled: true, + isNotificationEnabled: true, + isBadgeEnabled: true, + isMuted: false, + isDarkModeEnabled: '', + spellcheckerLanguage: '', + order: 1, + customRecipe: false, + hasCustomIcon: false, + workspaces: [], + iconUrl: null, ...data, }, - "status": ["created"] - }) + status: ['created'], + }); } // List all services a user has created async list({ - request, response, - auth + auth, }) { try { - await auth.getUser() + await auth.getUser(); } catch (error) { - return response.send('Missing or invalid api token') + return response.send('Missing or invalid api token'); } const services = (await auth.user.services().fetch()).rows; // Convert to array with all data Franz wants - const servicesArray = services.map(service => ({ - "customRecipe": false, - "hasCustomIcon": false, - "isBadgeEnabled": true, - "isDarkModeEnabled": "", - "isEnabled": true, - "isMuted": false, - "isNotificationEnabled": true, - "order": 1, - "spellcheckerLanguage": "", - "workspaces": [], - "iconUrl": null, + const servicesArray = services.map((service) => ({ + customRecipe: false, + hasCustomIcon: false, + isBadgeEnabled: true, + isDarkModeEnabled: '', + isEnabled: true, + isMuted: false, + isNotificationEnabled: true, + order: 1, + spellcheckerLanguage: '', + workspaces: [], + iconUrl: null, ...JSON.parse(service.settings), - "id": service.serviceId, - "name": service.name, - "recipeId": service.recipeId, - "userId": auth.user.id, - })) + id: service.serviceId, + name: service.name, + recipeId: service.recipeId, + userId: auth.user.id, + })); - return response.send(servicesArray) + return response.send(servicesArray); } async edit({ request, response, auth, - params + params, }) { try { - await auth.getUser() + await auth.getUser(); } catch (error) { - return response.send('Missing or invalid api token') + return response.send('Missing or invalid api token'); } // Validate user input @@ -125,15 +121,15 @@ class ServiceController { }); if (validation.fails()) { return response.status(401).send({ - "message": "Invalid POST arguments", - "messages": validation.messages(), - "status": 401 - }) + message: 'Invalid POST arguments', + messages: validation.messages(), + status: 401, + }); } const data = request.all(); const { - id + id, } = params; // Get current settings from db @@ -141,7 +137,7 @@ class ServiceController { .where('serviceId', id) .where('userId', auth.user.id).fetch()).rows[0]; - let settings = { + const settings = { ...JSON.parse(serviceData.settings), ...data, }; @@ -150,9 +146,9 @@ class ServiceController { await (Service.query() .where('serviceId', id) .where('userId', auth.user.id)).update({ - name: data.name, - settings: JSON.stringify(settings) - }); + name: data.name, + settings: JSON.stringify(settings), + }); // Get updated row const service = (await Service.query() @@ -160,88 +156,86 @@ class ServiceController { .where('userId', auth.user.id).fetch()).rows[0]; return response.send({ - "id": service.serviceId, - "name": data.name, + id: service.serviceId, + name: data.name, ...settings, - "userId": auth.user.id - }) + userId: auth.user.id, + }); } async reorder({ request, response, - auth + auth, }) { const data = request.all(); - for (const service in data) { + for (const service of Object.keys(data)) { // Get current settings from db - const serviceData = (await Service.query() + const serviceData = (await Service.query() // eslint-disable-line no-await-in-loop .where('serviceId', service) .where('userId', auth.user.id).fetch()).rows[0]; - let settings = { + const settings = { ...JSON.parse(serviceData.settings), - order: data[service] + order: data[service], }; // Update data in database - await (Service.query() + await (Service.query() // eslint-disable-line no-await-in-loop .where('serviceId', service) .where('userId', auth.user.id)) - .update({ - settings: JSON.stringify(settings) - }); + .update({ + settings: JSON.stringify(settings), + }); } // Get new services const services = (await auth.user.services().fetch()).rows; // Convert to array with all data Franz wants - const servicesArray = services.map(service => ({ - "customRecipe": false, - "hasCustomIcon": false, - "isBadgeEnabled": true, - "isDarkModeEnabled": "", - "isEnabled": true, - "isMuted": false, - "isNotificationEnabled": true, - "order": 1, - "spellcheckerLanguage": "", - "workspaces": [], - "iconUrl": null, + const servicesArray = services.map((service) => ({ + customRecipe: false, + hasCustomIcon: false, + isBadgeEnabled: true, + isDarkModeEnabled: '', + isEnabled: true, + isMuted: false, + isNotificationEnabled: true, + order: 1, + spellcheckerLanguage: '', + workspaces: [], + iconUrl: null, ...JSON.parse(service.settings), - "id": service.serviceId, - "name": service.name, - "recipeId": service.recipeId, - "userId": auth.user.id, - })) + id: service.serviceId, + name: service.name, + recipeId: service.recipeId, + userId: auth.user.id, + })); - return response.send(servicesArray) + return response.send(servicesArray); } update({ - request, - response + response, }) { - return response.send([]) + return response.send([]); } async delete({ - request, params, auth, - response + response, }) { // Update data in database await (Service.query() .where('serviceId', params.id) - .where('userId', auth.user.id)).delete() + .where('userId', auth.user.id)).delete(); return response.send({ - "message": "Sucessfully deleted service", - "status": 200 - }) + message: 'Sucessfully deleted service', + status: 200, + }); } } -module.exports = ServiceController +module.exports = ServiceController; diff --git a/app/Controllers/Http/StaticController.js b/app/Controllers/Http/StaticController.js index 17b641f..b16e6cb 100644 --- a/app/Controllers/Http/StaticController.js +++ b/app/Controllers/Http/StaticController.js @@ -1,4 +1,4 @@ -'use strict' + /** * Controller for routes with static responses */ @@ -6,220 +6,219 @@ class StaticController { // Enable all features features({ - response + response, }) { return response.send({ - "needToWaitToProceed": false, - "isSpellcheckerPremiumFeature": true, - "isServiceProxyEnabled": true, - "isServiceProxyPremiumFeature": true, - "isWorkspacePremiumFeature": true, - "isWorkspaceEnabled": true, - "isAnnouncementsEnabled": true, - "isSettingsWSEnabled": false, - "isServiceLimitEnabled": false, - "serviceLimitCount": 0, - "isCommunityRecipesPremiumFeature": false - }) + needToWaitToProceed: false, + isSpellcheckerPremiumFeature: true, + isServiceProxyEnabled: true, + isServiceProxyPremiumFeature: true, + isWorkspacePremiumFeature: true, + isWorkspaceEnabled: true, + isAnnouncementsEnabled: true, + isSettingsWSEnabled: false, + isServiceLimitEnabled: false, + serviceLimitCount: 0, + isCommunityRecipesPremiumFeature: false, + }); } // Return an empty array emptyArray({ - response + response, }) { - return response.send([]) + return response.send([]); } // Payment plans availible plans({ - response + response, }) { return response.send({ - "month": { - "id": "franz-supporter-license", - "price": 99 - }, - "year": { - "id": "franz-supporter-license-year-2019", - "price": 99 - } - }) + month: { + id: 'franz-supporter-license', + price: 99, + }, + year: { + id: 'franz-supporter-license-year-2019', + price: 99, + }, + }); } // Return list of popular recipes (copy of the response Franz's API is returning) popularRecipes({ - response + response, }) { return response.send([{ - "author": "Stefan Malzner ", - "featured": false, - "id": "slack", - "name": "Slack", - "version": "1.0.4", - "icons": { - "png": "https://cdn.franzinfra.com/recipes/dist/slack/src/icon.png", - "svg": "https://cdn.franzinfra.com/recipes/dist/slack/src/icon.svg" - } + author: 'Stefan Malzner ', + featured: false, + id: 'slack', + name: 'Slack', + version: '1.0.4', + icons: { + png: 'https://cdn.franzinfra.com/recipes/dist/slack/src/icon.png', + svg: 'https://cdn.franzinfra.com/recipes/dist/slack/src/icon.svg', + }, }, { - "author": "Stefan Malzner ", - "featured": false, - "id": "whatsapp", - "name": "WhatsApp", - "version": "1.0.1", - "icons": { - "png": "https://cdn.franzinfra.com/recipes/dist/whatsapp/src/icon.png", - "svg": "https://cdn.franzinfra.com/recipes/dist/whatsapp/src/icon.svg" - } + author: 'Stefan Malzner ', + featured: false, + id: 'whatsapp', + name: 'WhatsApp', + version: '1.0.1', + icons: { + png: 'https://cdn.franzinfra.com/recipes/dist/whatsapp/src/icon.png', + svg: 'https://cdn.franzinfra.com/recipes/dist/whatsapp/src/icon.svg', + }, }, { - "author": "Stefan Malzner ", - "featured": false, - "id": "messenger", - "name": "Messenger", - "version": "1.0.6", - "icons": { - "png": "https://cdn.franzinfra.com/recipes/dist/messenger/src/icon.png", - "svg": "https://cdn.franzinfra.com/recipes/dist/messenger/src/icon.svg" - } + author: 'Stefan Malzner ', + featured: false, + id: 'messenger', + name: 'Messenger', + version: '1.0.6', + icons: { + png: 'https://cdn.franzinfra.com/recipes/dist/messenger/src/icon.png', + svg: 'https://cdn.franzinfra.com/recipes/dist/messenger/src/icon.svg', + }, }, { - "author": "Stefan Malzner ", - "featured": false, - "id": "telegram", - "name": "Telegram", - "version": "1.0.0", - "icons": { - "png": "https://cdn.franzinfra.com/recipes/dist/telegram/src/icon.png", - "svg": "https://cdn.franzinfra.com/recipes/dist/telegram/src/icon.svg" - } + author: 'Stefan Malzner ', + featured: false, + id: 'telegram', + name: 'Telegram', + version: '1.0.0', + icons: { + png: 'https://cdn.franzinfra.com/recipes/dist/telegram/src/icon.png', + svg: 'https://cdn.franzinfra.com/recipes/dist/telegram/src/icon.svg', + }, }, { - "author": "Stefan Malzner ", - "featured": false, - "id": "gmail", - "name": "Gmail", - "version": "1.0.0", - "icons": { - "png": "https://cdn.franzinfra.com/recipes/dist/gmail/src/icon.png", - "svg": "https://cdn.franzinfra.com/recipes/dist/gmail/src/icon.svg" - } + author: 'Stefan Malzner ', + featured: false, + id: 'gmail', + name: 'Gmail', + version: '1.0.0', + icons: { + png: 'https://cdn.franzinfra.com/recipes/dist/gmail/src/icon.png', + svg: 'https://cdn.franzinfra.com/recipes/dist/gmail/src/icon.svg', + }, }, { - "author": "Stefan Malzner ", - "featured": false, - "id": "skype", - "name": "Skype", - "version": "1.0.0", - "icons": { - "png": "https://cdn.franzinfra.com/recipes/dist/skype/src/icon.png", - "svg": "https://cdn.franzinfra.com/recipes/dist/skype/src/icon.svg" - } + author: 'Stefan Malzner ', + featured: false, + id: 'skype', + name: 'Skype', + version: '1.0.0', + icons: { + png: 'https://cdn.franzinfra.com/recipes/dist/skype/src/icon.png', + svg: 'https://cdn.franzinfra.com/recipes/dist/skype/src/icon.svg', + }, }, { - "author": "Stefan Malzner ", - "featured": false, - "id": "hangouts", - "name": "Hangouts", - "version": "1.0.0", - "icons": { - "png": "https://cdn.franzinfra.com/recipes/dist/hangouts/src/icon.png", - "svg": "https://cdn.franzinfra.com/recipes/dist/hangouts/src/icon.svg" - } + author: 'Stefan Malzner ', + featured: false, + id: 'hangouts', + name: 'Hangouts', + version: '1.0.0', + icons: { + png: 'https://cdn.franzinfra.com/recipes/dist/hangouts/src/icon.png', + svg: 'https://cdn.franzinfra.com/recipes/dist/hangouts/src/icon.svg', + }, }, { - "author": "Stefan Malzner ", - "featured": false, - "id": "discord", - "name": "Discord", - "version": "1.0.0", - "icons": { - "png": "https://cdn.franzinfra.com/recipes/dist/discord/src/icon.png", - "svg": "https://cdn.franzinfra.com/recipes/dist/discord/src/icon.svg" - } + author: 'Stefan Malzner ', + featured: false, + id: 'discord', + name: 'Discord', + version: '1.0.0', + icons: { + png: 'https://cdn.franzinfra.com/recipes/dist/discord/src/icon.png', + svg: 'https://cdn.franzinfra.com/recipes/dist/discord/src/icon.svg', + }, }, { - "author": "Stefan Malzner ", - "featured": false, - "id": "tweetdeck", - "name": "Tweetdeck", - "version": "1.0.1", - "icons": { - "png": "https://cdn.franzinfra.com/recipes/dist/tweetdeck/src/icon.png", - "svg": "https://cdn.franzinfra.com/recipes/dist/tweetdeck/src/icon.svg" - } + author: 'Stefan Malzner ', + featured: false, + id: 'tweetdeck', + name: 'Tweetdeck', + version: '1.0.1', + icons: { + png: 'https://cdn.franzinfra.com/recipes/dist/tweetdeck/src/icon.png', + svg: 'https://cdn.franzinfra.com/recipes/dist/tweetdeck/src/icon.svg', + }, }, { - "author": "Stefan Malzner ", - "featured": false, - "id": "hipchat", - "name": "HipChat", - "version": "1.0.1", - "icons": { - "png": "https://cdn.franzinfra.com/recipes/dist/hipchat/src/icon.png", - "svg": "https://cdn.franzinfra.com/recipes/dist/hipchat/src/icon.svg" - } + author: 'Stefan Malzner ', + featured: false, + id: 'hipchat', + name: 'HipChat', + version: '1.0.1', + icons: { + png: 'https://cdn.franzinfra.com/recipes/dist/hipchat/src/icon.png', + svg: 'https://cdn.franzinfra.com/recipes/dist/hipchat/src/icon.svg', + }, }, { - "author": "Stefan Malzner ", - "featured": false, - "id": "gmailinbox", - "name": "Inbox by Gmail", - "version": "1.0.0", - "icons": { - "png": "https://cdn.franzinfra.com/recipes/dist/gmailinbox/src/icon.png", - "svg": "https://cdn.franzinfra.com/recipes/dist/gmailinbox/src/icon.svg" - } + author: 'Stefan Malzner ', + featured: false, + id: 'gmailinbox', + name: 'Inbox by Gmail', + version: '1.0.0', + icons: { + png: 'https://cdn.franzinfra.com/recipes/dist/gmailinbox/src/icon.png', + svg: 'https://cdn.franzinfra.com/recipes/dist/gmailinbox/src/icon.svg', + }, }, { - "author": "Stefan Malzner ", - "featured": false, - "id": "rocketchat", - "name": "Rocket.Chat", - "version": "1.0.1", - "icons": { - "png": "https://cdn.franzinfra.com/recipes/dist/rocketchat/src/icon.png", - "svg": "https://cdn.franzinfra.com/recipes/dist/rocketchat/src/icon.svg" - } + author: 'Stefan Malzner ', + featured: false, + id: 'rocketchat', + name: 'Rocket.Chat', + version: '1.0.1', + icons: { + png: 'https://cdn.franzinfra.com/recipes/dist/rocketchat/src/icon.png', + svg: 'https://cdn.franzinfra.com/recipes/dist/rocketchat/src/icon.svg', + }, }, { - "author": "Brian Gilbert ", - "featured": false, - "id": "gitter", - "name": "Gitter", - "version": "1.0.0", - "icons": { - "png": "https://cdn.franzinfra.com/recipes/dist/gitter/src/icon.png", - "svg": "https://cdn.franzinfra.com/recipes/dist/gitter/src/icon.svg" - } + author: 'Brian Gilbert ', + featured: false, + id: 'gitter', + name: 'Gitter', + version: '1.0.0', + icons: { + png: 'https://cdn.franzinfra.com/recipes/dist/gitter/src/icon.png', + svg: 'https://cdn.franzinfra.com/recipes/dist/gitter/src/icon.svg', + }, }, { - "author": "Stefan Malzner ", - "featured": false, - "id": "mattermost", - "name": "Mattermost", - "version": "1.0.0", - "icons": { - "png": "https://cdn.franzinfra.com/recipes/dist/mattermost/src/icon.png", - "svg": "https://cdn.franzinfra.com/recipes/dist/mattermost/src/icon.svg" - } + author: 'Stefan Malzner ', + featured: false, + id: 'mattermost', + name: 'Mattermost', + version: '1.0.0', + icons: { + png: 'https://cdn.franzinfra.com/recipes/dist/mattermost/src/icon.png', + svg: 'https://cdn.franzinfra.com/recipes/dist/mattermost/src/icon.svg', + }, }, { - "author": "Franz ", - "featured": false, - "id": "toggl", - "name": "toggl", - "version": "1.0.0", - "icons": { - "png": "https://cdn.franzinfra.com/recipes/dist/toggl/src/icon.png", - "svg": "https://cdn.franzinfra.com/recipes/dist/toggl/src/icon.svg" - } + author: 'Franz ', + featured: false, + id: 'toggl', + name: 'toggl', + version: '1.0.0', + icons: { + png: 'https://cdn.franzinfra.com/recipes/dist/toggl/src/icon.png', + svg: 'https://cdn.franzinfra.com/recipes/dist/toggl/src/icon.svg', + }, }, { - "author": "Stuart Clark ", - "featured": false, - "id": "twist", - "name": "twist", - "version": "1.0.0", - "icons": { - "png": "https://cdn.franzinfra.com/recipes/dist/twist/src/icon.png", - "svg": "https://cdn.franzinfra.com/recipes/dist/twist/src/icon.svg" - } - }]) + author: 'Stuart Clark ', + featured: false, + id: 'twist', + name: 'twist', + version: '1.0.0', + icons: { + png: 'https://cdn.franzinfra.com/recipes/dist/twist/src/icon.png', + svg: 'https://cdn.franzinfra.com/recipes/dist/twist/src/icon.svg', + }, + }]); } // Show announcements announcement({ response, - params }) { return response.send('No announcement found.'); } } -module.exports = StaticController +module.exports = StaticController; diff --git a/app/Controllers/Http/UserController.js b/app/Controllers/Http/UserController.js index ced27bb..1e67092 100644 --- a/app/Controllers/Http/UserController.js +++ b/app/Controllers/Http/UserController.js @@ -1,12 +1,10 @@ -'use strict' - const User = use('App/Models/User'); const Service = use('App/Models/Service'); const Workspace = use('App/Models/Workspace'); const { - validateAll + validateAll, } = use('Validator'); -const Env = use('Env') +const Env = use('Env'); const atob = require('atob'); const btoa = require('btoa'); @@ -14,49 +12,44 @@ const fetch = require('node-fetch'); const uuid = require('uuid/v4'); const crypto = require('crypto'); -const franzRequest = async (route, method, auth) => { - return new Promise(async (resolve, reject) => { - const base = 'https://api.franzinfra.com/v1/'; - const user = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Ferdi/5.3.0-beta.1 Chrome/69.0.3497.128 Electron/4.2.4 Safari/537.36'; - - try { - const rawResponse = await fetch(base + route, { - method, - headers: { - 'Authorization': 'Bearer ' + auth, - 'User-Agent': user - }, - }); - const content = await rawResponse.json(); - - resolve(content); - } catch (e) { - reject(); - } - }) -} +const franzRequest = (route, method, auth) => new Promise((resolve, reject) => { + const base = 'https://api.franzinfra.com/v1/'; + const user = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Ferdi/5.3.0-beta.1 Chrome/69.0.3497.128 Electron/4.2.4 Safari/537.36'; + + try { + fetch(base + route, { + method, + headers: { + Authorization: `Bearer ${auth}`, + 'User-Agent': user, + }, + }) + .then((data) => data.json()) + .then((json) => resolve(json)); + } catch (e) { + reject(); + } +}); class UserController { - // Register a new user async signup({ request, response, auth, - session }) { // Validate user input const validation = await validateAll(request.all(), { firstname: 'required', email: 'required|email|unique:users,email', - password: 'required' + password: 'required', }); if (validation.fails()) { return response.status(401).send({ - "message": "Invalid POST arguments", - "messages": validation.messages(), - "status": 401 - }) + message: 'Invalid POST arguments', + messages: validation.messages(), + status: 401, + }); } const data = request.only(['firstname', 'email', 'password']); @@ -67,21 +60,21 @@ class UserController { user = await User.create({ email: data.email, password: data.password, - username: data.firstname + username: data.firstname, }); } catch (e) { return response.status(401).send({ - "message": "E-Mail Address already in use", - "status": 401 - }) + message: 'E-Mail Address already in use', + status: 401, + }); } // Generate new auth token - const token = await auth.generate(user) + const token = await auth.generate(user); return response.send({ - "message": "Successfully created account", - "token": token.token + message: 'Successfully created account', + token: token.token, }); } @@ -89,115 +82,112 @@ class UserController { async login({ request, response, - auth + auth, }) { if (!request.header('Authorization')) { return response.status(401).send({ - "message": "Please provide authorization", - "status": 401 - }) + message: 'Please provide authorization', + status: 401, + }); } // Get auth data from auth token const authHeader = atob(request.header('Authorization').replace('Basic ', '')).split(':'); // Check if user with email exists - let user = (await User.query().where('email', authHeader[0]).first()); + const user = (await User.query().where('email', authHeader[0]).first()); if (!user || !user.email) { return response.status(401).send({ - "message": "User credentials not valid (Invalid mail)", - "code": "invalid-credentials", - "status": 401 + message: 'User credentials not valid (Invalid mail)', + code: 'invalid-credentials', + status: 401, }); } // Try to login let token; try { - token = await auth.attempt(user.email, authHeader[1]) + token = await auth.attempt(user.email, authHeader[1]); } catch (e) { return response.status(401).send({ - "message": "User credentials not valid", - "code": "invalid-credentials", - "status": 401 + message: 'User credentials not valid', + code: 'invalid-credentials', + status: 401, }); } return response.send({ - "message": "Successfully logged in", - "token": token.token + message: 'Successfully logged in', + token: token.token, }); } // Return information about the current user async me({ - request, response, auth, - session }) { try { - await auth.getUser() + await auth.getUser(); } catch (error) { - response.send('Missing or invalid api token') + response.send('Missing or invalid api token'); } return response.send({ - accountType: "individual", + accountType: 'individual', beta: false, donor: {}, email: auth.user.email, emailValidated: true, features: {}, - firstname: "Franz", - id: "82c1cf9d-ab58-4da2-b55e-aaa41d2142d8", + firstname: 'Franz', + id: '82c1cf9d-ab58-4da2-b55e-aaa41d2142d8', isPremium: true, isSubscriptionOwner: true, - lastname: "Franz", - locale: "en-US" + lastname: 'Franz', + locale: 'en-US', }); } - async import({ request, - response + response, }) { // Validate user input const validation = await validateAll(request.all(), { email: 'required|email|unique:users,email', - password: 'required' + password: 'required', }); if (validation.fails()) { - let errorMessage = "There was an error while trying to import your account:\n"; + let errorMessage = 'There was an error while trying to import your account:\n'; for (const message of validation.messages()) { - if (message.validation == 'required') { - errorMessage += '- Please make sure to supply your ' + message.field + '\n' - } else if (message.validation == 'unique') { - errorMessage += '- There is already a user with this email.\n' + if (message.validation === 'required') { + errorMessage += `- Please make sure to supply your ${message.field}\n`; + } else if (message.validation === 'unique') { + errorMessage += '- There is already a user with this email.\n'; } else { - errorMessage += message.message + '\n'; + errorMessage += `${message.message}\n`; } } - return response.status(401).send(errorMessage) + return response.status(401).send(errorMessage); } const { email, - password - } = request.all() + password, + } = request.all(); const hashedPassword = crypto.createHash('sha256').update(password).digest('base64'); - - if(Env.get('CONNECT_WITH_FRANZ') == 'false') { + + if (Env.get('CONNECT_WITH_FRANZ') == 'false') { // eslint-disable-line eqeqeq await User.create({ email, password: hashedPassword, - username: 'Franz' + username: 'Franz', }); - return response.send('Your account has been created but due to this server\'s configuration, we could not import your Franz account data.\n\nIf you are the server owner, please set CONNECT_WITH_FRANZ to true to enable account imports.') + return response.send('Your account has been created but due to this server\'s configuration, we could not import your Franz account data.\n\nIf you are the server owner, please set CONNECT_WITH_FRANZ to true to enable account imports.'); } const base = 'https://api.franzinfra.com/v1/'; @@ -206,42 +196,41 @@ class UserController { // Try to get an authentication token let token; try { - const basicToken = btoa(email + ':' + hashedPassword) + const basicToken = btoa(`${email}:${hashedPassword}`); - const rawResponse = await fetch(base + 'auth/login', { + const rawResponse = await fetch(`${base}auth/login`, { method: 'POST', headers: { - 'Authorization': 'Basic ' + basicToken, - 'User-Agent': userAgent + Authorization: `Basic ${basicToken}`, + 'User-Agent': userAgent, }, }); const content = await rawResponse.json(); if (!content.message || content.message !== 'Successfully logged in') { const errorMessage = 'Could not login into Franz with your supplied credentials. Please check and try again'; - return response.status(401).send(errorMessage) + return response.status(401).send(errorMessage); } token = content.token; } catch (e) { return response.status(401).send({ - "message": "Cannot login to Franz", - "error": e - }) + message: 'Cannot login to Franz', + error: e, + }); } // Get user information let userInf = false; try { - userInf = await franzRequest('me', 'GET', token) - console.log('A', userInf) + userInf = await franzRequest('me', 'GET', token); } catch (e) { - const errorMessage = 'Could not get your user info from Franz. Please check your credentials or try again later.\nError: ' + e; - return response.status(401).send(errorMessage) + const errorMessage = `Could not get your user info from Franz. Please check your credentials or try again later.\nError: ${e}`; + return response.status(401).send(errorMessage); } if (!userInf) { - const errorMessage = 'Could not get your user info from Franz. Please check your credentials or try again later.\nError: ' + e; - return response.status(401).send(errorMessage) + const errorMessage = 'Could not get your user info from Franz. Please check your credentials or try again later'; + return response.status(401).send(errorMessage); } // Create user in DB @@ -250,69 +239,69 @@ class UserController { user = await User.create({ email: userInf.email, password: hashedPassword, - username: userInf.firstname + username: userInf.firstname, }); } catch (e) { - const errorMessage = 'Could not create your user in our system.\nError: ' + e; - return response.status(401).send(errorMessage) + const errorMessage = `Could not create your user in our system.\nError: ${e}`; + return response.status(401).send(errorMessage); } - let serviceIdTranslation = {}; + const serviceIdTranslation = {}; // Import services try { - const services = await franzRequest('me/services', 'GET', token) + const services = await franzRequest('me/services', 'GET', token); for (const service of services) { // Get new, unused uuid let serviceId; do { serviceId = uuid(); - } while ((await Service.query().where('serviceId', serviceId).fetch()).rows.length > 0) + } while ((await Service.query().where('serviceId', serviceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop - await Service.create({ + await Service.create({ // eslint-disable-line no-await-in-loop userId: user.id, serviceId, name: service.name, recipeId: service.recipeId, - settings: JSON.stringify(service) + settings: JSON.stringify(service), }); serviceIdTranslation[service.id] = serviceId; } } catch (e) { - const errorMessage = 'Could not import your services into our system.\nError: ' + e; - return response.status(401).send(errorMessage) + const errorMessage = `Could not import your services into our system.\nError: ${e}`; + return response.status(401).send(errorMessage); } // Import workspaces try { - const workspaces = await franzRequest('workspace', 'GET', token) + const workspaces = await franzRequest('workspace', 'GET', token); for (const workspace of workspaces) { let workspaceId; do { workspaceId = uuid(); - } while ((await Workspace.query().where('workspaceId', workspaceId).fetch()).rows.length > 0) + } while ((await Workspace.query().where('workspaceId', workspaceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop - const services = workspace.services.map(service => serviceIdTranslation[service]) + const services = workspace.services.map((service) => serviceIdTranslation[service]); - await Workspace.create({ - userId: auth.user.id, + await Workspace.create({ // eslint-disable-line no-await-in-loop + userId: user.id, workspaceId, name: workspace.name, order: workspace.order, services: JSON.stringify(services), - data: JSON.stringify({}) + data: JSON.stringify({}), }); } } catch (e) { - const errorMessage = 'Could not import your workspaces into our system.\nError: ' + e; - return response.status(401).send(errorMessage) + const errorMessage = `Could not import your workspaces into our system.\nError: ${e}`; + return response.status(401).send(errorMessage); } - return response.send('Your account has been imported. You can now use your Franz account in Ferdi.') + return response.send('Your account has been imported. You can now use your Franz account in Ferdi.'); } } -module.exports = UserController +module.exports = UserController; diff --git a/app/Controllers/Http/WorkspaceController.js b/app/Controllers/Http/WorkspaceController.js index b64d858..ecf79af 100644 --- a/app/Controllers/Http/WorkspaceController.js +++ b/app/Controllers/Http/WorkspaceController.js @@ -1,8 +1,7 @@ -'use strict' const Workspace = use('App/Models/Workspace'); const { - validateAll + validateAll, } = use('Validator'); const uuid = require('uuid/v4'); @@ -12,12 +11,12 @@ class WorkspaceController { async create({ request, response, - auth + auth, }) { try { - await auth.getUser() + await auth.getUser(); } catch (error) { - return response.send('Missing or invalid api token') + return response.send('Missing or invalid api token'); } // Validate user input @@ -26,10 +25,10 @@ class WorkspaceController { }); if (validation.fails()) { return response.status(401).send({ - "message": "Invalid POST arguments", - "messages": validation.messages(), - "status": 401 - }) + message: 'Invalid POST arguments', + messages: validation.messages(), + status: 401, + }); } const data = request.all(); @@ -38,7 +37,7 @@ class WorkspaceController { let workspaceId; do { workspaceId = uuid(); - } while ((await Workspace.query().where('workspaceId', workspaceId).fetch()).rows.length > 0) + } while ((await Workspace.query().where('workspaceId', workspaceId).fetch()).rows.length > 0); // eslint-disable-line no-await-in-loop const order = (await auth.user.workspaces().fetch()).rows.length; @@ -48,7 +47,7 @@ class WorkspaceController { name: data.name, order, services: JSON.stringify([]), - data: JSON.stringify(data) + data: JSON.stringify(data), }); return response.send({ @@ -57,37 +56,37 @@ class WorkspaceController { id: workspaceId, order, workspaces: [], - }) + }); } async edit({ request, response, auth, - params + params, }) { try { - await auth.getUser() + await auth.getUser(); } catch (error) { - return response.send('Missing or invalid api token') + return response.send('Missing or invalid api token'); } // Validate user input const validation = await validateAll(request.all(), { name: 'required|alpha', - services: 'required|array' + services: 'required|array', }); if (validation.fails()) { return response.status(401).send({ - "message": "Invalid POST arguments", - "messages": validation.messages(), - "status": 401 - }) + message: 'Invalid POST arguments', + messages: validation.messages(), + status: 401, + }); } const data = request.all(); const { - id + id, } = params; // Update data in database @@ -95,7 +94,7 @@ class WorkspaceController { .where('workspaceId', id) .where('userId', auth.user.id)).update({ name: data.name, - services: JSON.stringify(data.services) + services: JSON.stringify(data.services), }); // Get updated row @@ -104,24 +103,24 @@ class WorkspaceController { .where('userId', auth.user.id).fetch()).rows[0]; return response.send({ - "id": workspace.workspaceId, - "name": data.name, - "order": workspace.order, - "services": data.services, - "userId": auth.user.id - }) + id: workspace.workspaceId, + name: data.name, + order: workspace.order, + services: data.services, + userId: auth.user.id, + }); } async delete({ request, response, auth, - params + params, }) { try { - await auth.getUser() + await auth.getUser(); } catch (error) { - return response.send('Missing or invalid api token') + return response.send('Missing or invalid api token'); } // Validate user input @@ -130,14 +129,14 @@ class WorkspaceController { }); if (validation.fails()) { return response.status(401).send({ - "message": "Invalid POST arguments", - "messages": validation.messages(), - "status": 401 - }) + message: 'Invalid POST arguments', + messages: validation.messages(), + status: 401, + }); } const { - id + id, } = params; // Update data in database @@ -146,38 +145,37 @@ class WorkspaceController { .where('userId', auth.user.id)).delete(); return response.send({ - "message": "Successfully deleted workspace", - }) + message: 'Successfully deleted workspace', + }); } // List all workspaces a user has created async list({ - request, response, - auth + auth, }) { try { - await auth.getUser() + await auth.getUser(); } catch (error) { - return response.send('Missing or invalid api token') + return response.send('Missing or invalid api token'); } const workspaces = (await auth.user.workspaces().fetch()).rows; // Convert to array with all data Franz wants let workspacesArray = []; - if(workspaces) { - workspacesArray = workspaces.map(workspace => ({ - "id": workspace.workspaceId, - "name": workspace.name, - "order": workspace.order, - "services": JSON.parse(workspace.services), - "userId": auth.user.id - })) + if (workspaces) { + workspacesArray = workspaces.map((workspace) => ({ + id: workspace.workspaceId, + name: workspace.name, + order: workspace.order, + services: JSON.parse(workspace.services), + userId: auth.user.id, + })); } - - return response.send(workspacesArray) + + return response.send(workspacesArray); } } -module.exports = WorkspaceController +module.exports = WorkspaceController; diff --git a/app/Exceptions/Handler.js b/app/Exceptions/Handler.js index efa2e0b..cb9e10b 100644 --- a/app/Exceptions/Handler.js +++ b/app/Exceptions/Handler.js @@ -1,6 +1,5 @@ -'use strict' -const BaseExceptionHandler = use('BaseExceptionHandler') +const BaseExceptionHandler = use('BaseExceptionHandler'); /** * This class handles all exceptions thrown during @@ -20,14 +19,14 @@ class ExceptionHandler extends BaseExceptionHandler { * * @return {void} */ - async handle (error, { request, response }) { + async handle(error, { response }) { if (error.name === 'ValidationException') { - return response.status(400).send('Invalid arguments') - } else if (error.name === 'InvalidSessionException') { + return response.status(400).send('Invalid arguments'); + } if (error.name === 'InvalidSessionException') { return response.status(401).redirect('/user/login'); } - response.status(error.status).send(error.message) + return response.status(error.status).send(error.message); } /** @@ -40,8 +39,9 @@ class ExceptionHandler extends BaseExceptionHandler { * * @return {void} */ - async report (error, { request }) { + async report() { + return true; } } -module.exports = ExceptionHandler +module.exports = ExceptionHandler; diff --git a/app/Middleware/ConvertEmptyStringsToNull.js b/app/Middleware/ConvertEmptyStringsToNull.js index a5750cc..556f223 100644 --- a/app/Middleware/ConvertEmptyStringsToNull.js +++ b/app/Middleware/ConvertEmptyStringsToNull.js @@ -1,17 +1,16 @@ -'use strict' class ConvertEmptyStringsToNull { - async handle ({ request }, next) { + async handle({ request }, next) { if (Object.keys(request.body).length) { request.body = Object.assign( - ...Object.keys(request.body).map(key => ({ - [key]: request.body[key] !== '' ? request.body[key] : null - })) - ) + ...Object.keys(request.body).map((key) => ({ + [key]: request.body[key] !== '' ? request.body[key] : null, + })), + ); } - await next() + await next(); } } -module.exports = ConvertEmptyStringsToNull +module.exports = ConvertEmptyStringsToNull; diff --git a/app/Models/Recipe.js b/app/Models/Recipe.js index 9e3619c..da3618b 100644 --- a/app/Models/Recipe.js +++ b/app/Models/Recipe.js @@ -1,9 +1,8 @@ -'use strict' /** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */ -const Model = use('Model') +const Model = use('Model'); class Recipe extends Model { } -module.exports = Recipe +module.exports = Recipe; diff --git a/app/Models/Service.js b/app/Models/Service.js index 0ca72fd..0a13ec1 100644 --- a/app/Models/Service.js +++ b/app/Models/Service.js @@ -1,12 +1,11 @@ -'use strict' /** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */ -const Model = use('Model') +const Model = use('Model'); class Service extends Model { - user() { - return this.belongsTo('App/Models/User', 'userId', 'id') - } + user() { + return this.belongsTo('App/Models/User', 'userId', 'id'); + } } -module.exports = Service +module.exports = Service; diff --git a/app/Models/Token.js b/app/Models/Token.js index e089e87..f6bec08 100644 --- a/app/Models/Token.js +++ b/app/Models/Token.js @@ -1,9 +1,8 @@ -'use strict' /** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */ -const Model = use('Model') +const Model = use('Model'); class Token extends Model { } -module.exports = Token +module.exports = Token; diff --git a/app/Models/Traits/NoTimestamp.js b/app/Models/Traits/NoTimestamp.js index edd07f0..c647428 100644 --- a/app/Models/Traits/NoTimestamp.js +++ b/app/Models/Traits/NoTimestamp.js @@ -1,16 +1,15 @@ -'use strict' class NoTimestamp { - register (Model) { + register(Model) { Object.defineProperties(Model, { createdAtColumn: { get: () => null, }, updatedAtColumn: { get: () => null, - } - }) + }, + }); } } -module.exports = NoTimestamp +module.exports = NoTimestamp; diff --git a/app/Models/User.js b/app/Models/User.js index c9a680a..3a40347 100644 --- a/app/Models/User.js +++ b/app/Models/User.js @@ -1,14 +1,13 @@ -'use strict' /** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */ -const Model = use('Model') +const Model = use('Model'); /** @type {import('@adonisjs/framework/src/Hash')} */ -const Hash = use('Hash') +const Hash = use('Hash'); class User extends Model { - static boot () { - super.boot() + static boot() { + super.boot(); /** * A hook to hash the user password before saving @@ -16,9 +15,10 @@ class User extends Model { */ this.addHook('beforeSave', async (userInstance) => { if (userInstance.dirty.password) { - userInstance.password = await Hash.make(userInstance.password) + // eslint-disable-next-line no-param-reassign + userInstance.password = await Hash.make(userInstance.password); } - }) + }); } /** @@ -31,17 +31,17 @@ class User extends Model { * * @return {Object} */ - tokens () { - return this.hasMany('App/Models/Token') + tokens() { + return this.hasMany('App/Models/Token'); } - services () { - return this.hasMany('App/Models/Service', 'id', 'userId') + services() { + return this.hasMany('App/Models/Service', 'id', 'userId'); } - workspaces () { - return this.hasMany('App/Models/Workspace', 'id', 'userId') + workspaces() { + return this.hasMany('App/Models/Workspace', 'id', 'userId'); } } -module.exports = User +module.exports = User; diff --git a/app/Models/Workspace.js b/app/Models/Workspace.js index f78a3f9..b155e09 100644 --- a/app/Models/Workspace.js +++ b/app/Models/Workspace.js @@ -1,12 +1,11 @@ -'use strict' /** @type {typeof import('@adonisjs/lucid/src/Lucid/Model')} */ -const Model = use('Model') +const Model = use('Model'); class Workspace extends Model { - user() { - return this.belongsTo('App/Models/User', 'userId', 'id') - } + user() { + return this.belongsTo('App/Models/User', 'userId', 'id'); + } } -module.exports = Workspace +module.exports = Workspace; diff --git a/config/app.js b/config/app.js index 4b4f7a5..4d36c7b 100644 --- a/config/app.js +++ b/config/app.js @@ -1,7 +1,6 @@ -'use strict' /** @type {import('@adonisjs/framework/src/Env')} */ -const Env = use('Env') +const Env = use('Env'); module.exports = { @@ -94,7 +93,7 @@ module.exports = { | response.send('Hello', { ignoreEtag: true }) | */ - etag: false + etag: false, }, views: { @@ -107,7 +106,7 @@ module.exports = { | production to optimize view loading time. | */ - cache: Env.get('CACHE_VIEWS', true) + cache: Env.get('CACHE_VIEWS', true), }, static: { @@ -146,7 +145,7 @@ module.exports = { | that exists will be served. Example: ['html', 'htm']. | */ - extensions: false + extensions: false, }, locales: { @@ -173,7 +172,7 @@ module.exports = { | based on HTTP headers/query string. | */ - locale: 'en' + locale: 'en', }, logger: { @@ -202,7 +201,7 @@ module.exports = { console: { driver: 'console', name: 'adonis-app', - level: 'info' + level: 'info', }, /* @@ -220,8 +219,8 @@ module.exports = { driver: 'file', name: 'adonis-app', filename: 'adonis.log', - level: 'info' - } + level: 'info', + }, }, /* @@ -238,6 +237,6 @@ module.exports = { httpOnly: true, sameSite: false, path: '/', - maxAge: 7200 - } -} + maxAge: 7200, + }, +}; diff --git a/config/auth.js b/config/auth.js index c70db3f..b831b06 100644 --- a/config/auth.js +++ b/config/auth.js @@ -1,7 +1,6 @@ -'use strict' /** @type {import('@adonisjs/framework/src/Env')} */ -const Env = use('Env') +const Env = use('Env'); module.exports = { /* @@ -32,7 +31,7 @@ module.exports = { model: 'App/Models/User', scheme: 'session', uid: 'email', - password: 'password' + password: 'password', }, /* @@ -53,7 +52,7 @@ module.exports = { model: 'App/Models/User', scheme: 'basic', uid: 'email', - password: 'password' + password: 'password', }, /* @@ -72,8 +71,8 @@ module.exports = { uid: 'email', password: 'password', options: { - secret: Env.get('APP_KEY') - } + secret: Env.get('APP_KEY'), + }, }, /* @@ -89,6 +88,6 @@ module.exports = { model: 'App/Models/User', scheme: 'api', uid: 'email', - password: 'password' - } -} + password: 'password', + }, +}; diff --git a/config/bodyParser.js b/config/bodyParser.js index f04d291..c336e67 100644 --- a/config/bodyParser.js +++ b/config/bodyParser.js @@ -1,4 +1,3 @@ -'use strict' module.exports = { /* @@ -47,8 +46,8 @@ module.exports = { 'application/json', 'application/json-patch+json', 'application/vnd.api+json', - 'application/csp-report' - ] + 'application/csp-report', + ], }, /* @@ -61,8 +60,8 @@ module.exports = { */ raw: { types: [ - 'text/*' - ] + 'text/*', + ], }, /* @@ -75,8 +74,8 @@ module.exports = { */ form: { types: [ - 'application/x-www-form-urlencoded' - ] + 'application/x-www-form-urlencoded', + ], }, /* @@ -89,7 +88,7 @@ module.exports = { */ files: { types: [ - 'multipart/form-data' + 'multipart/form-data', ], /* @@ -133,7 +132,7 @@ module.exports = { | is to true. Otherwise everything is processed manually. | */ - processManually: [] + processManually: [], /* |-------------------------------------------------------------------------- @@ -153,5 +152,5 @@ module.exports = { | } | */ - } -} + }, +}; diff --git a/config/cors.js b/config/cors.js index ffc1951..7ebbe3f 100644 --- a/config/cors.js +++ b/config/cors.js @@ -1,4 +1,3 @@ -'use strict' module.exports = { /* @@ -83,5 +82,5 @@ module.exports = { | Define Access-Control-Allow-Max-Age | */ - maxAge: 90 -} + maxAge: 90, +}; diff --git a/config/database.js b/config/database.js index a7a2776..0e9cfba 100644 --- a/config/database.js +++ b/config/database.js @@ -1,10 +1,9 @@ -'use strict' /** @type {import('@adonisjs/framework/src/Env')} */ -const Env = use('Env') +const Env = use('Env'); /** @type {import('@adonisjs/ignitor/src/Helpers')} */ -const Helpers = use('Helpers') +const Helpers = use('Helpers'); module.exports = { /* @@ -32,10 +31,10 @@ module.exports = { sqlite: { client: 'sqlite3', connection: { - filename: Helpers.databasePath(`${Env.get('DB_DATABASE', 'development')}.sqlite`) + filename: Helpers.databasePath(`${Env.get('DB_DATABASE', 'development')}.sqlite`), }, useNullAsDefault: true, - debug: Env.get('DB_DEBUG', false) + debug: Env.get('DB_DEBUG', false), }, /* @@ -55,9 +54,9 @@ module.exports = { port: Env.get('DB_PORT', ''), user: Env.get('DB_USER', 'root'), password: Env.get('DB_PASSWORD', ''), - database: Env.get('DB_DATABASE', 'adonis') + database: Env.get('DB_DATABASE', 'adonis'), }, - debug: Env.get('DB_DEBUG', false) + debug: Env.get('DB_DEBUG', false), }, /* @@ -77,8 +76,8 @@ module.exports = { port: Env.get('DB_PORT', ''), user: Env.get('DB_USER', 'root'), password: Env.get('DB_PASSWORD', ''), - database: Env.get('DB_DATABASE', 'adonis') + database: Env.get('DB_DATABASE', 'adonis'), }, - debug: Env.get('DB_DEBUG', false) - } -} + debug: Env.get('DB_DEBUG', false), + }, +}; diff --git a/config/drive.js b/config/drive.js index 901e699..617ce47 100644 --- a/config/drive.js +++ b/config/drive.js @@ -1,7 +1,4 @@ -'use strict' - -const Helpers = use('Helpers') -const Env = use('Env') +const Env = use('Env'); module.exports = { /* @@ -25,8 +22,8 @@ module.exports = { | */ local: { - root: __dirname + '/../recipes', - driver: 'local' + root: `${__dirname}/../recipes`, + driver: 'local', }, /* @@ -42,7 +39,7 @@ module.exports = { key: Env.get('S3_KEY'), secret: Env.get('S3_SECRET'), bucket: Env.get('S3_BUCKET'), - region: Env.get('S3_REGION') - } - } -} + region: Env.get('S3_REGION'), + }, + }, +}; diff --git a/config/hash.js b/config/hash.js index 42f5805..297c977 100644 --- a/config/hash.js +++ b/config/hash.js @@ -1,7 +1,6 @@ -'use strict' /** @type {import('@adonisjs/framework/src/Env')} */ -const Env = use('Env') +const Env = use('Env'); module.exports = { /* @@ -25,7 +24,7 @@ module.exports = { | */ bcrypt: { - rounds: 10 + rounds: 10, }, /* @@ -44,6 +43,6 @@ module.exports = { | */ argon: { - type: 1 - } -} + type: 1, + }, +}; diff --git a/config/session.js b/config/session.js index f49b9b7..bce28bd 100644 --- a/config/session.js +++ b/config/session.js @@ -1,6 +1,5 @@ -'use strict' -const Env = use('Env') +const Env = use('Env'); module.exports = { /* @@ -65,7 +64,7 @@ module.exports = { cookie: { httpOnly: true, path: '/', - sameSite: false + sameSite: false, }, /* @@ -78,7 +77,7 @@ module.exports = { | */ file: { - location: 'sessions' + location: 'sessions', }, /* @@ -94,6 +93,6 @@ module.exports = { port: 6379, password: null, db: 0, - keyPrefix: '' - } -} + keyPrefix: '', + }, +}; diff --git a/config/shield.js b/config/shield.js index 3d4526a..5c1c5cd 100644 --- a/config/shield.js +++ b/config/shield.js @@ -1,4 +1,3 @@ -'use strict' module.exports = { /* @@ -64,7 +63,7 @@ module.exports = { | if you want to know the behavior. https://github.com/helmetjs/helmet/pull/82 | */ - disableAndroid: true + disableAndroid: true, }, /* @@ -80,7 +79,7 @@ module.exports = { */ xss: { enabled: true, - enableOnOldIE: false + enableOnOldIE: false, }, /* @@ -139,7 +138,7 @@ module.exports = { httpOnly: false, sameSite: true, path: '/', - maxAge: 7200 - } - } -} + maxAge: 7200, + }, + }, +}; diff --git a/database/factory.js b/database/factory.js index 16b5084..550c5e6 100644 --- a/database/factory.js +++ b/database/factory.js @@ -1,4 +1,3 @@ -'use strict' /* |-------------------------------------------------------------------------- diff --git a/database/migrations/1503250034279_user.js b/database/migrations/1503250034279_user.js index 9148593..5010bec 100644 --- a/database/migrations/1503250034279_user.js +++ b/database/migrations/1503250034279_user.js @@ -1,22 +1,21 @@ -'use strict' /** @type {import('@adonisjs/lucid/src/Schema')} */ -const Schema = use('Schema') +const Schema = use('Schema'); class UserSchema extends Schema { - up () { + up() { this.create('users', (table) => { - table.increments() - table.string('username', 80).notNullable() - table.string('email', 254).notNullable().unique() - table.string('password', 60).notNullable() - table.timestamps() - }) + table.increments(); + table.string('username', 80).notNullable(); + table.string('email', 254).notNullable().unique(); + table.string('password', 60).notNullable(); + table.timestamps(); + }); } - down () { - this.drop('users') + down() { + this.drop('users'); } } -module.exports = UserSchema +module.exports = UserSchema; diff --git a/database/migrations/1503250034280_token.js b/database/migrations/1503250034280_token.js index c8bb9fc..ad97dba 100644 --- a/database/migrations/1503250034280_token.js +++ b/database/migrations/1503250034280_token.js @@ -1,23 +1,22 @@ -'use strict' /** @type {import('@adonisjs/lucid/src/Schema')} */ -const Schema = use('Schema') +const Schema = use('Schema'); class TokensSchema extends Schema { - up () { + up() { this.create('tokens', (table) => { - table.increments() - table.integer('user_id').unsigned().references('id').inTable('users') - table.string('token', 255).notNullable().unique().index() - table.string('type', 80).notNullable() - table.boolean('is_revoked').defaultTo(false) - table.timestamps() - }) + table.increments(); + table.integer('user_id').unsigned().references('id').inTable('users'); + table.string('token', 255).notNullable().unique().index(); + table.string('type', 80).notNullable(); + table.boolean('is_revoked').defaultTo(false); + table.timestamps(); + }); } - down () { - this.drop('tokens') + down() { + this.drop('tokens'); } } -module.exports = TokensSchema +module.exports = TokensSchema; diff --git a/database/migrations/1566385379883_service_schema.js b/database/migrations/1566385379883_service_schema.js index a725699..093fb13 100644 --- a/database/migrations/1566385379883_service_schema.js +++ b/database/migrations/1566385379883_service_schema.js @@ -1,24 +1,23 @@ -'use strict' /** @type {import('@adonisjs/lucid/src/Schema')} */ -const Schema = use('Schema') +const Schema = use('Schema'); class ServiceSchema extends Schema { - up () { + up() { this.create('services', (table) => { - table.increments() - table.string('userId', 80).notNullable() - table.string('serviceId', 80).notNullable() - table.string('name', 80).notNullable() - table.string('recipeId', 254).notNullable() - table.json('settings') - table.timestamps() - }) + table.increments(); + table.string('userId', 80).notNullable(); + table.string('serviceId', 80).notNullable(); + table.string('name', 80).notNullable(); + table.string('recipeId', 254).notNullable(); + table.json('settings'); + table.timestamps(); + }); } - down () { - this.drop('services') + down() { + this.drop('services'); } } -module.exports = ServiceSchema +module.exports = ServiceSchema; diff --git a/database/migrations/1566554231482_recipe_schema.js b/database/migrations/1566554231482_recipe_schema.js index 7d8f5a8..14fcb82 100644 --- a/database/migrations/1566554231482_recipe_schema.js +++ b/database/migrations/1566554231482_recipe_schema.js @@ -1,22 +1,21 @@ -'use strict' /** @type {import('@adonisjs/lucid/src/Schema')} */ -const Schema = use('Schema') +const Schema = use('Schema'); class RecipeSchema extends Schema { - up () { + up() { this.create('recipes', (table) => { - table.increments() - table.string('name', 80).notNullable() - table.string('recipeId', 254).notNullable().unique() - table.json('data') - table.timestamps() - }) + table.increments(); + table.string('name', 80).notNullable(); + table.string('recipeId', 254).notNullable().unique(); + table.json('data'); + table.timestamps(); + }); } - down () { - this.drop('recipes') + down() { + this.drop('recipes'); } } -module.exports = RecipeSchema +module.exports = RecipeSchema; diff --git a/database/migrations/1566554359294_workspace_schema.js b/database/migrations/1566554359294_workspace_schema.js index 84e0bb9..0a3c138 100644 --- a/database/migrations/1566554359294_workspace_schema.js +++ b/database/migrations/1566554359294_workspace_schema.js @@ -1,25 +1,24 @@ -'use strict' /** @type {import('@adonisjs/lucid/src/Schema')} */ -const Schema = use('Schema') +const Schema = use('Schema'); class WorkspaceSchema extends Schema { - up () { + up() { this.create('workspaces', (table) => { - table.increments() - table.string('workspaceId', 80).notNullable().unique() - table.string('userId', 80).notNullable() - table.string('name', 80).notNullable() - table.integer('order') - table.json('services') - table.json('data') - table.timestamps() - }) + table.increments(); + table.string('workspaceId', 80).notNullable().unique(); + table.string('userId', 80).notNullable(); + table.string('name', 80).notNullable(); + table.integer('order'); + table.json('services'); + table.json('data'); + table.timestamps(); + }); } - down () { - this.drop('workspaces') + down() { + this.drop('workspaces'); } } -module.exports = WorkspaceSchema +module.exports = WorkspaceSchema; diff --git a/package-lock.json b/package-lock.json index 0a8707b..00d3f18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,6 +40,16 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } } } }, @@ -109,6 +119,16 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } } } }, @@ -322,6 +342,16 @@ "ms": "^2.1.1" } }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -352,6 +382,43 @@ "lodash": "^4.17.11" } }, + "@babel/code-frame": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", + "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", + "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/runtime": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.5.tgz", + "integrity": "sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "dev": true + } + } + }, "@slynova/flydrive": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/@slynova/flydrive/-/flydrive-0.3.1.tgz", @@ -394,6 +461,12 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.0.0.tgz", "integrity": "sha512-PaF/MduxijYYt7unVGRuds1vBC9bFxbNf+VWqhOClfdgy7RlVkQqt610ig1/yxTgsDIfW1cWDel5EBbOy3jdtQ==" }, + "acorn-jsx": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz", + "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==", + "dev": true + }, "acorn-node": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.8.2.tgz", @@ -558,6 +631,12 @@ "ansi-wrap": "0.1.0" } }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, "ansi-gray": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", @@ -699,6 +778,25 @@ "readable-stream": "^2.0.6" } }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "aria-query": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", + "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", + "dev": true, + "requires": { + "ast-types-flow": "0.0.7", + "commander": "^2.11.0" + } + }, "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", @@ -727,6 +825,16 @@ "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=" }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, "array-slice": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", @@ -755,6 +863,18 @@ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, "async": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", @@ -783,6 +903,15 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" }, + "axobject-query": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", + "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", + "dev": true, + "requires": { + "ast-types-flow": "0.0.7" + } + }, "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", @@ -990,6 +1119,12 @@ "resolved": "https://registry.npmjs.org/chance/-/chance-1.0.18.tgz", "integrity": "sha512-g9YLQVHVZS/3F+zIicfB58vjcxopvYQRp7xHzvyDFDhXH1aRZI/JhwSAO0X5qYiQluoGnaNAU6wByD2KTxJN1A==" }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "choices-separator": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/choices-separator/-/choices-separator-2.0.0.tgz", @@ -1077,6 +1212,15 @@ } } }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, "cli-table": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", @@ -1085,6 +1229,12 @@ "colors": "1.0.3" } }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, "clone": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", @@ -1214,11 +1364,23 @@ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "confusing-browser-globals": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.8.tgz", + "integrity": "sha512-lI7asCibVJ6Qd3FGU7mu4sfG4try4LX3+GVS+Gv8UlrEf2AeW57piecapnog2UHZSbcX/P/1UDWVaTsblowlZg==", + "dev": true + }, "console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, "content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", @@ -1298,6 +1460,12 @@ "uid-safe": "2.1.5" } }, + "damerau-levenshtein": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz", + "integrity": "sha512-CBCRqFnpu715iPmw1KrdOrzRqbdFwQTwAWyyyYS42+iAgHCuXZ+/TdMgQkUENPomxEz9z1BEzuQU2Xw0kUuAgA==", + "dev": true + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -1324,6 +1492,21 @@ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, "define-property": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", @@ -1372,6 +1555,15 @@ "kuler": "1.0.x" } }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "dotenv": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz", @@ -1430,6 +1622,12 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, "enabled": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/enabled/-/enabled-1.0.2.tgz", @@ -1475,11 +1673,57 @@ "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.5.tgz", "integrity": "sha512-zoB603vQReOFvTg5xMl9I1P2PnHsHQQKTEowsKKD7nseUfJq6UWzK+4YtlWUO1nhiQUxe6XMkk+JleSZD1NZFA==" }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + } + } + }, "error-symbol": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/error-symbol/-/error-symbol-0.1.0.tgz", "integrity": "sha1-Ck2uN9YA0VopukU9jvkg8YRDM/Y=" }, + "es-abstract": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.14.1.tgz", + "integrity": "sha512-cp/Tb1oA/rh2X7vqeSOvM+TSo3UkJLX70eNihgVEvnzwAgikjkTFr/QVgRCaxjm0knCNQzNoxxxcw2zO2LJdZA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.0", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.0.0", + "string.prototype.trimright": "^2.0.0" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", @@ -1490,11 +1734,299 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, + "eslint": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.3.0.tgz", + "integrity": "sha512-ZvZTKaqDue+N8Y9g0kp6UPZtS4FSY3qARxBs7p4f0H0iof381XHduqVerFWtK8DPtKmemqbqCFENWSQgPR/Gow==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.2", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.4.1", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true + } + } + }, + "eslint-config-airbnb": { + "version": "18.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.0.1.tgz", + "integrity": "sha512-hLb/ccvW4grVhvd6CT83bECacc+s4Z3/AEyWQdIT2KeTsG9dR7nx1gs7Iw4tDmGKozCNHFn4yZmRm3Tgy+XxyQ==", + "dev": true, + "requires": { + "eslint-config-airbnb-base": "^14.0.0", + "object.assign": "^4.1.0", + "object.entries": "^1.1.0" + } + }, + "eslint-config-airbnb-base": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.0.0.tgz", + "integrity": "sha512-2IDHobw97upExLmsebhtfoD3NAKhV4H0CJWP3Uprd/uk+cHuWYOczPVxQ8PxLFUAw7o3Th1RAU8u1DoUpr+cMA==", + "dev": true, + "requires": { + "confusing-browser-globals": "^1.0.7", + "object.assign": "^4.1.0", + "object.entries": "^1.1.0" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + } + }, + "eslint-module-utils": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz", + "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==", + "dev": true, + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.18.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz", + "integrity": "sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.11.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + } + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.3.tgz", + "integrity": "sha512-CawzfGt9w83tyuVekn0GDPU9ytYtxyxyFZ3aSWROmnRRFQFT2BiPJd7jvRdzNDi6oLWaS2asMeYSNMjWTV4eNg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.5", + "aria-query": "^3.0.0", + "array-includes": "^3.0.3", + "ast-types-flow": "^0.0.7", + "axobject-query": "^2.0.2", + "damerau-levenshtein": "^1.0.4", + "emoji-regex": "^7.0.2", + "has": "^1.0.3", + "jsx-ast-utils": "^2.2.1" + } + }, + "eslint-plugin-react": { + "version": "7.14.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz", + "integrity": "sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.1.0", + "object.entries": "^1.1.0", + "object.fromentries": "^2.0.0", + "object.values": "^1.1.0", + "prop-types": "^15.7.2", + "resolve": "^1.10.1" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + } + } + }, + "eslint-plugin-react-hooks": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-1.7.0.tgz", + "integrity": "sha512-iXTCFcOmlWvw4+TOE8CLWj6yX1GwzT0Y6cUfHHZqWnSk144VmVIRcVGtUAzrLES7C798lmvnt02C7rxaOX1HNA==", + "dev": true + }, + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz", + "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.0.0" + } + }, + "eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true + }, + "espree": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz", + "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==", + "dev": true, + "requires": { + "acorn": "^7.0.0", + "acorn-jsx": "^5.0.2", + "eslint-visitor-keys": "^1.1.0" + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", @@ -1601,6 +2133,17 @@ "is-extendable": "^0.1.0" } }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -1654,6 +2197,24 @@ "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==" }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, "fill-range": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", @@ -1665,6 +2226,15 @@ "to-regex-range": "^2.1.0" } }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, "findup-sync": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", @@ -1693,6 +2263,34 @@ "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==" }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -1745,11 +2343,11 @@ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==" }, "fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", "requires": { - "graceful-fs": "^4.1.2", + "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } @@ -1767,6 +2365,18 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, "gauge": { "version": "2.7.4", "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", @@ -1836,6 +2446,26 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.0.0.tgz", + "integrity": "sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + }, + "dependencies": { + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + } + } + }, "global-modules": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", @@ -1858,6 +2488,12 @@ "which": "^1.2.14" } }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, "graceful-fs": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz", @@ -1877,11 +2513,26 @@ "har-schema": "^2.0.0" } }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -1929,6 +2580,12 @@ "parse-passwd": "^1.0.0" } }, + "hosted-git-info": { + "version": "2.8.4", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.4.tgz", + "integrity": "sha512-pzXIvANXEFrc5oFFXRMkbLPQ2rXRoDERwDLyrcUxGhaZhgP54BBSl9Oheh7Vv0T090cszWBxPjkQQ5Sq1PbBRQ==", + "dev": true + }, "http-errors": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", @@ -1959,6 +2616,12 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, "ignore-walk": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", @@ -1967,6 +2630,30 @@ "minimatch": "^3.0.4" } }, + "import-fresh": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz", + "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, "indent-string": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", @@ -2006,6 +2693,55 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, + "inquirer": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "interpret": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", @@ -2064,6 +2800,12 @@ "kind-of": "^6.0.0" } }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", @@ -2123,6 +2865,21 @@ "isobject": "^3.0.1" } }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, "is-relative": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", @@ -2136,6 +2893,15 @@ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -2174,6 +2940,22 @@ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", @@ -2189,6 +2971,12 @@ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -2237,6 +3025,16 @@ "verror": "1.10.0" } }, + "jsx-ast-utils": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.1.tgz", + "integrity": "sha512-v3FxCcAf20DayI+uxnCuw795+oOIkVu6EnJ1+kSzhqqTZHNkTZ7B66ZgLp4oLJ/gbA64cI0B7WRoHZMSRdyVRQ==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "object.assign": "^4.1.0" + } + }, "jwa": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", @@ -2330,6 +3128,16 @@ "set-getter": "^0.1.0" } }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, "liftoff": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", @@ -2345,6 +3153,36 @@ "resolve": "^1.1.7" } }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", @@ -2432,6 +3270,15 @@ } } }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", @@ -2555,6 +3402,12 @@ "mime-db": "1.40.0" } }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -2724,6 +3577,12 @@ } } }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, "needle": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", @@ -2853,6 +3712,18 @@ "osenv": "^0.1.4" } }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, "npm-bundled": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", @@ -2954,6 +3825,18 @@ } } }, + "object-inspect": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -2962,6 +3845,18 @@ "isobject": "^3.0.0" } }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, "object.defaults": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", @@ -2973,6 +3868,30 @@ "isobject": "^3.0.0" } }, + "object.entries": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", + "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "object.fromentries": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", + "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.11.0", + "function-bind": "^1.1.1", + "has": "^1.0.1" + } + }, "object.map": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", @@ -2990,6 +3909,18 @@ "isobject": "^3.0.1" } }, + "object.values": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz", + "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, "on-finished": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", @@ -3011,6 +3942,29 @@ "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz", "integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=" }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", @@ -3030,11 +3984,52 @@ "os-tmpdir": "^1.0.0" } }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, "packet-reader": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + }, + "dependencies": { + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + } + } + }, "parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", @@ -3045,6 +4040,15 @@ "path-root": "^0.1.1" } }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, "parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", @@ -3060,6 +4064,12 @@ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -3093,6 +4103,23 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.4.0.tgz", "integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==" }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -3164,6 +4191,15 @@ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, "platform": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.5.tgz", @@ -3207,6 +4243,12 @@ "xtend": "^4.0.0" } }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, "pretty-hrtime": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", @@ -3217,6 +4259,12 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, "promise-reduce": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/promise-reduce/-/promise-reduce-2.1.0.tgz", @@ -3566,6 +4614,17 @@ } } }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, "proxy-addr": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", @@ -3646,6 +4705,33 @@ "strip-json-comments": "~2.0.1" } }, + "react-is": { + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.9.0.tgz", + "integrity": "sha512-tJBzzzIgnnRfEm046qRcURvwQnZVXmuCbscxUO5RWrGTXpon2d4c8mI0D8WE6ydVIm29JiLB6+RslkIvym9Rjw==", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", @@ -3735,6 +4821,12 @@ } } }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, "repeat-element": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", @@ -3841,6 +4933,16 @@ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", @@ -3859,6 +4961,24 @@ "resolved": "https://registry.npmjs.org/rndm/-/rndm-1.2.0.tgz", "integrity": "sha1-8z/pz7Urv9UgqhgyO8ZdsRCht2w=" }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz", + "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", @@ -4063,6 +5183,17 @@ "is-arrayish": "^0.3.1" } }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -4196,6 +5327,38 @@ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=" }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", + "dev": true + }, "split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", @@ -4231,6 +5394,12 @@ } } }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, "sqlite3": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-4.1.0.tgz", @@ -4361,6 +5530,26 @@ } } }, + "string.prototype.trimleft": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.0.0.tgz", + "integrity": "sha1-aLaqjhYsaoDnbjqKDC50cYbicf8=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.0.2" + } + }, + "string.prototype.trimright": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.0.0.tgz", + "integrity": "sha1-q0pW2AKgH75yk+EehPJNyBZGYd0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.0.2" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -4384,6 +5573,12 @@ "ansi-regex": "^2.0.0" } }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, "strip-color": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/strip-color/-/strip-color-0.1.0.tgz", @@ -4415,6 +5610,46 @@ "acorn-node": "^1.2.0" } }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "tar": { "version": "4.4.10", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz", @@ -4493,6 +5728,12 @@ "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==" }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -4624,6 +5865,12 @@ "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.3.0.tgz", "integrity": "sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw==" }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, "tsscmp": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", @@ -4642,6 +5889,15 @@ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -4784,6 +6040,12 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, "v8flags": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz", @@ -4792,6 +6054,16 @@ "homedir-polyfill": "^1.0.1" } }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -4874,11 +6146,26 @@ "triple-beam": "^1.2.0" } }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index 927c513..3211894 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "main": "index.js", "scripts": { "start": "node server.js", - "test": "node ace test" + "test": "node ace test", + "lint": "eslint --fix ./" }, "keywords": [ "adonisjs", @@ -37,7 +38,15 @@ "targz": "^1.0.1", "uuid": "^3.3.3" }, - "devDependencies": {}, + "devDependencies": { + "eslint": "^6.3.0", + "eslint-config-airbnb": "^18.0.1", + "eslint-config-airbnb-base": "^14.0.0", + "eslint-plugin-import": "^2.18.2", + "eslint-plugin-jsx-a11y": "^6.2.3", + "eslint-plugin-react": "^7.14.3", + "eslint-plugin-react-hooks": "^1.7.0" + }, "autoload": { "App": "./app" } diff --git a/public/js/new.js b/public/js/new.js index 4f54245..beaa36d 100644 --- a/public/js/new.js +++ b/public/js/new.js @@ -1,12 +1,13 @@ +/* eslint-env browser */ const elDrop = document.getElementById('dropzone'); const submitBtn = document.getElementById('submitbutton'); const fileInput = document.getElementById('files'); -elDrop.addEventListener('dragover', function (event) { +elDrop.addEventListener('dragover', (event) => { event.preventDefault(); }); -elDrop.addEventListener('drop', async function (event) { +elDrop.addEventListener('drop', async (event) => { event.preventDefault(); submitBtn.disabled = true; @@ -19,5 +20,5 @@ elDrop.addEventListener('drop', async function (event) { submitBtn.disabled = false; }); elDrop.addEventListener('click', () => { - fileInput.click(); -}) \ No newline at end of file + fileInput.click(); +}); diff --git a/server.js b/server.js index e2371aa..e56b08e 100644 --- a/server.js +++ b/server.js @@ -1,4 +1,3 @@ -'use strict' /* |-------------------------------------------------------------------------- @@ -17,9 +16,10 @@ | Make sure to pass a relative path from the project root. */ -const { Ignitor } = require('@adonisjs/ignitor') +const { Ignitor } = require('@adonisjs/ignitor'); +const fold = require('@adonisjs/fold'); -new Ignitor(require('@adonisjs/fold')) +new Ignitor(fold) .appRoot(__dirname) .fireHttpServer() - .catch(console.error) + .catch(console.error); // eslint-disable-line no-console diff --git a/start/app.js b/start/app.js index 9cf2735..d0986fe 100644 --- a/start/app.js +++ b/start/app.js @@ -1,4 +1,3 @@ -'use strict' /* |-------------------------------------------------------------------------- @@ -21,7 +20,7 @@ const providers = [ '@adonisjs/framework/providers/ViewProvider', '@adonisjs/session/providers/SessionProvider', '@adonisjs/shield/providers/ShieldProvider', -] +]; /* |-------------------------------------------------------------------------- @@ -33,8 +32,8 @@ const providers = [ | */ const aceProviders = [ - '@adonisjs/lucid/providers/MigrationsProvider' -] + '@adonisjs/lucid/providers/MigrationsProvider', +]; /* |-------------------------------------------------------------------------- @@ -48,7 +47,7 @@ const aceProviders = [ | { Route: 'Adonis/Src/Route' } | */ -const aliases = {} +const aliases = {}; /* |-------------------------------------------------------------------------- @@ -58,6 +57,8 @@ const aliases = {} | Here you store ace commands for your package | */ -const commands = [] +const commands = []; -module.exports = { providers, aceProviders, aliases, commands } +module.exports = { + providers, aceProviders, aliases, commands, +}; diff --git a/start/kernel.js b/start/kernel.js index 18fb5bf..b54fc29 100644 --- a/start/kernel.js +++ b/start/kernel.js @@ -1,7 +1,6 @@ -'use strict' /** @type {import('@adonisjs/framework/src/Server')} */ -const Server = use('Server') +const Server = use('Server'); /* |-------------------------------------------------------------------------- @@ -17,7 +16,7 @@ const globalMiddleware = [ 'App/Middleware/ConvertEmptyStringsToNull', 'Adonis/Middleware/AuthInit', 'Adonis/Middleware/Session', -] +]; /* |-------------------------------------------------------------------------- @@ -40,7 +39,7 @@ const namedMiddleware = { auth: 'Adonis/Middleware/Auth', guest: 'Adonis/Middleware/AllowGuestOnly', shield: 'Adonis/Middleware/Shield', -} +}; /* |-------------------------------------------------------------------------- @@ -54,10 +53,10 @@ const namedMiddleware = { */ const serverMiddleware = [ 'Adonis/Middleware/Static', - 'Adonis/Middleware/Cors' -] + 'Adonis/Middleware/Cors', +]; Server .registerGlobal(globalMiddleware) .registerNamed(namedMiddleware) - .use(serverMiddleware) + .use(serverMiddleware); diff --git a/start/routes.js b/start/routes.js index 5cf9fda..8e0f640 100644 --- a/start/routes.js +++ b/start/routes.js @@ -1,4 +1,3 @@ -'use strict' /* |-------------------------------------------------------------------------- @@ -8,99 +7,92 @@ */ /** @type {typeof import('@adonisjs/framework/src/Route/Manager')} */ -const Route = use('Route') -const Env = use('Env') +const Route = use('Route'); +const Env = use('Env'); // Health: Returning if all systems function correctly Route.get('health', ({ - response -}) => { - return response.send({ - api: 'success', - db: 'success' - }) -}) + response, +}) => response.send({ + api: 'success', + db: 'success', +})); // API is grouped under '/v1/' route Route.group(() => { // User authentification - Route.post('auth/signup', 'UserController.signup').middleware('guest') - Route.post('auth/login', 'UserController.login').middleware('guest') + Route.post('auth/signup', 'UserController.signup').middleware('guest'); + Route.post('auth/login', 'UserController.login').middleware('guest'); // User info - Route.get('me', 'UserController.me').middleware('auth') + Route.get('me', 'UserController.me').middleware('auth'); // Service info - Route.post('service', 'ServiceController.create').middleware('auth') - Route.put('service/:id', 'ServiceController.edit').middleware('auth') - Route.delete('service/:id', 'ServiceController.delete').middleware('auth') - Route.get('me/services', 'ServiceController.list').middleware('auth') - Route.put('service/reorder', 'ServiceController.reorder').middleware('auth') - Route.get('recipe', 'ServiceController.list').middleware('auth') - Route.post('recipes/update', 'ServiceController.update').middleware('auth') - + Route.post('service', 'ServiceController.create').middleware('auth'); + Route.put('service/:id', 'ServiceController.edit').middleware('auth'); + Route.delete('service/:id', 'ServiceController.delete').middleware('auth'); + Route.get('me/services', 'ServiceController.list').middleware('auth'); + Route.put('service/reorder', 'ServiceController.reorder').middleware('auth'); + Route.get('recipe', 'ServiceController.list').middleware('auth'); + Route.post('recipes/update', 'ServiceController.update').middleware('auth'); + // Recipe store - Route.get('recipes', 'RecipeController.list') - Route.get('recipes/download/:recipe', 'RecipeController.download') - Route.get('recipes/search', 'RecipeController.search') - Route.get('recipes/popular', 'StaticController.popularRecipes') - Route.get('recipes/update', 'StaticController.emptyArray') + Route.get('recipes', 'RecipeController.list'); + Route.get('recipes/download/:recipe', 'RecipeController.download'); + Route.get('recipes/search', 'RecipeController.search'); + Route.get('recipes/popular', 'StaticController.popularRecipes'); + Route.get('recipes/update', 'StaticController.emptyArray'); // Workspaces - Route.put('workspace/:id', 'WorkspaceController.edit').middleware('auth') - Route.delete('workspace/:id', 'WorkspaceController.delete').middleware('auth') - Route.post('workspace', 'WorkspaceController.create').middleware('auth') - Route.get('workspace', 'WorkspaceController.list').middleware('auth') + Route.put('workspace/:id', 'WorkspaceController.edit').middleware('auth'); + Route.delete('workspace/:id', 'WorkspaceController.delete').middleware('auth'); + Route.post('workspace', 'WorkspaceController.create').middleware('auth'); + Route.get('workspace', 'WorkspaceController.list').middleware('auth'); // Static responses - Route.get('features', 'StaticController.features') - Route.get('services', 'StaticController.emptyArray') - Route.get('news', 'StaticController.emptyArray') - Route.get('payment/plans', 'StaticController.plans') - Route.get('announcements/:version', 'StaticController.announcement') -}).prefix('v1') + Route.get('features', 'StaticController.features'); + Route.get('services', 'StaticController.emptyArray'); + Route.get('news', 'StaticController.emptyArray'); + Route.get('payment/plans', 'StaticController.plans'); + Route.get('announcements/:version', 'StaticController.announcement'); +}).prefix('v1'); // User dashboard Route.group(() => { // Auth - Route.get('login', ({view}) => { - return view.render('dashboard.login'); - }).middleware('guest'); - Route.post('login', 'DashboardController.login').middleware('guest') + Route.get('login', ({ view }) => view.render('dashboard.login')).middleware('guest'); + Route.post('login', 'DashboardController.login').middleware('guest'); // Dashboard - Route.get('account', 'DashboardController.account').middleware('auth:session') - Route.post('account', 'DashboardController.edit').middleware('auth:session') - Route.get('data', 'DashboardController.data').middleware('auth:session') - Route.get('delete', ({view}) => { - return view.render('dashboard.delete'); - }).middleware('auth:session'); - Route.post('delete', 'DashboardController.delete').middleware('auth:session') - Route.get('logout', 'DashboardController.logout').middleware('auth:session') - - Route.get('*', ({ response }) => response.redirect('/user/account')) -}).prefix('user').middleware('shield') + Route.get('account', 'DashboardController.account').middleware('auth:session'); + Route.post('account', 'DashboardController.edit').middleware('auth:session'); + Route.get('data', 'DashboardController.data').middleware('auth:session'); + Route.get('delete', ({ view }) => view.render('dashboard.delete')).middleware('auth:session'); + Route.post('delete', 'DashboardController.delete').middleware('auth:session'); + Route.get('logout', 'DashboardController.logout').middleware('auth:session'); + + Route.get('*', ({ response }) => response.redirect('/user/account')); +}).prefix('user').middleware('shield'); // Recipe creation -Route.post('new', 'RecipeController.create') +Route.post('new', 'RecipeController.create'); Route.get('new', ({ response, view }) => { - if (Env.get('IS_CREATION_ENABLED') == 'false') { + if (Env.get('IS_CREATION_ENABLED') == 'false') { // eslint-disable-line eqeqeq return response.send('This server doesn\'t allow the creation of new recipes.\n\nIf you are the server owner, please set IS_CREATION_ENABLED to true to enable recipe creation.'); - } else { - return view.render('others.new') } -}) + return view.render('others.new'); +}); // Franz account import -Route.post('import', 'UserController.import') -Route.get('import', ({ view }) => view.render('others.import')) +Route.post('import', 'UserController.import'); +Route.get('import', ({ view }) => view.render('others.import')); // Legal documents -Route.get('terms', ({ response }) => response.redirect('/terms.html')) -Route.get('privacy', ({ response }) => response.redirect('/privacy.html')) +Route.get('terms', ({ response }) => response.redirect('/terms.html')); +Route.get('privacy', ({ response }) => response.redirect('/privacy.html')); // Index -Route.get('/', ({ view }) => view.render('others.index')) +Route.get('/', ({ view }) => view.render('others.index')); // 404 handler -Route.get('/*', ({ response }) => response.redirect('/')) \ No newline at end of file +Route.get('/*', ({ response }) => response.redirect('/')); -- cgit v1.2.3-54-g00ecf