From 5d4037f90acb42778772f5d23cad2d14c749196e Mon Sep 17 00:00:00 2001 From: Snazzah Date: Wed, 23 Jun 2021 21:55:35 -0500 Subject: [PATCH] Start rewriting to dexare --- .editorconfig | 9 + .eslintignore | 4 +- .eslintrc.js | 37 + .eslintrc.json | 79 - .gitignore | 13 +- .prettierrc | 8 + README.md | 1 - config/_default.js | 117 +- package.json | 47 +- pm2.json | 4 +- src/bot.js | 151 -- src/bot.ts | 97 ++ src/commandloader.js | 101 -- src/commands/admin/abandonall.js | 58 - src/commands/admin/adminbalance.js | 28 - src/commands/admin/allsupports.js | 60 - src/commands/admin/deleteaccount.js | 42 - src/commands/admin/deleteall.js | 39 - src/commands/admin/deposit.js | 24 - src/commands/admin/fund.js | 38 - src/commands/admin/fundall.js | 72 - src/commands/admin/listall.js | 49 - src/commands/admin/sync.js | 20 - src/commands/admin/withdraw.js | 45 - src/commands/curator/abandon.js | 35 - src/commands/curator/balance.js | 59 - src/commands/curator/support.js | 52 - src/commands/curator/supports.js | 61 - src/commands/help.js | 101 -- src/commands/owner/asynceval.js | 38 - src/commands/owner/eval.js | 35 - src/commands/owner/exec.js | 34 - src/commands/owner/reload.js | 23 - src/commands/owner/reloadone.js | 46 - src/commands/owner/restart.js | 22 - src/commands/ping.js | 27 - src/commands/trusted/tabandon.js | 40 - src/commands/trusted/tbalance.js | 30 - src/commands/trusted/tsupport.js | 51 - src/commands/trusted/tsupports.js | 42 - src/crons/flushCache.cron.ts | 10 + src/database.js | 139 -- src/events.js | 50 - src/index.ts | 9 + src/messageawaiter.js | 154 -- src/sqlitedb.js | 63 - src/structures/ArgumentInterpreter.js | 182 --- src/structures/Command.js | 149 -- src/structures/GenericPager.js | 103 -- src/structures/GenericPrompt.js | 141 -- src/structures/Halt.js | 61 - src/structures/LBRY.js | 210 --- src/structures/MultiSelect.js | 145 -- src/structures/Paginator.js | 184 --- src/structures/ReactionCollector.js | 60 - src/structures/SubMenu.js | 44 - src/util.js | 363 ----- src/util/abstracts.ts | 70 + src/util/index.ts | 72 + tsconfig.json | 21 + yarn.lock | 1966 +++++++++++++++++-------- 61 files changed, 1824 insertions(+), 4211 deletions(-) create mode 100644 .editorconfig create mode 100644 .eslintrc.js delete mode 100644 .eslintrc.json create mode 100644 .prettierrc delete mode 100644 src/bot.js create mode 100644 src/bot.ts delete mode 100644 src/commandloader.js delete mode 100644 src/commands/admin/abandonall.js delete mode 100644 src/commands/admin/adminbalance.js delete mode 100644 src/commands/admin/allsupports.js delete mode 100644 src/commands/admin/deleteaccount.js delete mode 100644 src/commands/admin/deleteall.js delete mode 100644 src/commands/admin/deposit.js delete mode 100644 src/commands/admin/fund.js delete mode 100644 src/commands/admin/fundall.js delete mode 100644 src/commands/admin/listall.js delete mode 100644 src/commands/admin/sync.js delete mode 100644 src/commands/admin/withdraw.js delete mode 100644 src/commands/curator/abandon.js delete mode 100644 src/commands/curator/balance.js delete mode 100644 src/commands/curator/support.js delete mode 100644 src/commands/curator/supports.js delete mode 100644 src/commands/help.js delete mode 100644 src/commands/owner/asynceval.js delete mode 100644 src/commands/owner/eval.js delete mode 100644 src/commands/owner/exec.js delete mode 100644 src/commands/owner/reload.js delete mode 100644 src/commands/owner/reloadone.js delete mode 100644 src/commands/owner/restart.js delete mode 100644 src/commands/ping.js delete mode 100644 src/commands/trusted/tabandon.js delete mode 100644 src/commands/trusted/tbalance.js delete mode 100644 src/commands/trusted/tsupport.js delete mode 100644 src/commands/trusted/tsupports.js create mode 100644 src/crons/flushCache.cron.ts delete mode 100644 src/database.js delete mode 100644 src/events.js create mode 100644 src/index.ts delete mode 100644 src/messageawaiter.js delete mode 100644 src/sqlitedb.js delete mode 100644 src/structures/ArgumentInterpreter.js delete mode 100644 src/structures/Command.js delete mode 100644 src/structures/GenericPager.js delete mode 100644 src/structures/GenericPrompt.js delete mode 100644 src/structures/Halt.js delete mode 100644 src/structures/LBRY.js delete mode 100644 src/structures/MultiSelect.js delete mode 100644 src/structures/Paginator.js delete mode 100644 src/structures/ReactionCollector.js delete mode 100644 src/structures/SubMenu.js delete mode 100644 src/util.js create mode 100644 src/util/abstracts.ts create mode 100644 src/util/index.ts create mode 100644 tsconfig.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..53b061a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true \ No newline at end of file diff --git a/.eslintignore b/.eslintignore index 2ec5195..db794ee 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,3 @@ -config/ \ No newline at end of file +config/ +src-old/ +node_modules/ diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..4a2f8db --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,37 @@ +module.exports = { + env: { + commonjs: true, + es6: true, + node: true + }, + extends: ['eslint:recommended', 'plugin:prettier/recommended'], + globals: { + NodeJS: true, + BigInt: true + }, + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 6, + sourceType: 'module' + }, + plugins: ['@typescript-eslint'], + rules: { + 'prettier/prettier': 'warn', + 'no-cond-assign': [2, 'except-parens'], + 'no-unused-vars': 0, + '@typescript-eslint/no-unused-vars': 1, + 'no-empty': [ + 'error', + { + allowEmptyCatch: true + } + ], + 'prefer-const': [ + 'warn', + { + destructuring: 'all' + } + ], + 'spaced-comment': 'warn' + } +}; diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 39b4666..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "env": { - "commonjs": true, - "es6": true, - "node": true - }, - "extends": "eslint:recommended", - "globals": {}, - "parserOptions": { - "ecmaVersion": 2020, - "sourceType": "module" - }, - "rules": { - "array-bracket-spacing": [ - "warn", - "never" - ], - "computed-property-spacing": "warn", - "indent": [ - "warn", - 2 - ], - "keyword-spacing": [ - "warn", - { - "before": true, - "after": true - } - ], - "max-len": [ - "warn", - { - "code": 110, - "ignoreComments": true, - "ignoreUrls": true - } - ], - "no-cond-assign": [ - 2, - "except-parens" - ], - "no-use-before-define": [ - 2, - { - "functions": false, - "classes": false, - "variables": false - } - ], - "new-cap": 0, - "no-caller": 2, - "no-undef": 2, - "no-unused-vars": 1, - "no-empty": [ - "error", - { - "allowEmptyCatch": true - } - ], - "no-console": "off", - "no-multi-spaces": "warn", - "prefer-const": [ - "warn", - { - "destructuring": "all" - } - ], - "quotes": [ - "warn", - "single" - ], - "semi": [ - "warn", - "always" - ], - "spaced-comment": "warn", - "space-infix-ops": "warn" - } -} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 6511d93..14a526d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,11 @@ node_modules -config/default.js -config/production.js -config/curate.sqlite +config/* +!config/_default.js +*.sqlite package-lock.json -.idea/ \ No newline at end of file +yarn.lock +yarn-error.log +.idea/ +.vscode/* +!.vscode/extensions.json +src-old/ diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..6e77b63 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,8 @@ +{ + "semi": true, + "singleQuote": true, + "tabWidth": 2, + "useTabs": false, + "trailingComma": "none", + "printWidth": 110 +} diff --git a/README.md b/README.md index af9c838..16f88e3 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ This bot allows the community of LBRY to support eachother through the [LBRY Fou * Pull the repo * Install [Node.JS LTS](https://nodejs.org/) (Currently Node v12.x) * Install [Yarn](https://yarnpkg.com/) (`npm install yarn -g`) -* Install [Redis](https://redis.io/) ([quickstart](https://redis.io/topics/quickstart)) * Install LBRY-SDK * Set your NODE_ENV (Node environment) Environment Variable to Production (`EXPORT NODE_ENV=production`) * In the `config/` folder, copy `_default.js` to `production.js` and edit the config as needed diff --git a/config/_default.js b/config/_default.js index d1d5ba3..debcf4b 100644 --- a/config/_default.js +++ b/config/_default.js @@ -1,56 +1,71 @@ module.exports = { - // [string] The token for the bot - token: "", - // [string] The prefix for the bot - prefix: "!", - // [Array] An array of elevated IDs, giving them access to developer commands - elevated: [], // [string] The path where the commands will be found commandsPath: "./src/commands", - // [boolean] Whether debug logs will be shown - debug: false, - // [number] The main embed color (#ffffff -> 0xffffff) - embedColor: 0x15521c, - // [string|Array] The role ID(s) for curator roles - curatorRoleID: "", - // [string|Array] The role ID(s) for trusted roles - trustedRoleID: "", - // [string|Array] The role ID(s) for admin roles - adminRoleID: "", - // [string] guild_id - guildID: "", - // [string] sdk_url - sdkURL: "", - // [string] The ABSOLUTE path to the main wallet file to back up - walletPath: "~/.lbryum/wallets/default_wallet", - // [string] The ABSOLUTE path folder to store wallet backups after every deletion - walletBackupFolder: "~/.lbryum_backup/", - // [string] Amount to auto-fund upon account creation - startingBalance: "", - // [Object] Eris client options (https://abal.moe/Eris/docs/Client) - discordConfig: { - autoreconnect: true, - allowedMentions: { - everyone: false, - roles: false, - users: true + + // Dexare config + dexare: { + // [string] The token for the bot + token: "", + // [string] The prefix for the bot + prefix: "c!", + // [boolean?] Whether to use the bots mention as a prefix + mentionPrefix: true, + // [Array] An array of elevated IDs, giving them access to developer commands + elevated: [], + // [number] The main embed color (#ffffff -> 0xffffff) + embedColor: 0x15521c, + // [string|Array] The role ID(s) for curator roles + curatorRoles: "", + // [string|Array] The role ID(s) for trusted roles + trustedRoles: "", + // [string|Array] The role ID(s) for admin roles + adminRoles: "", + // [string] The ID of the main Discord guild + guildID: "", + + + // [Object] Eris client options (https://abal.moe/Eris/docs/Client) + erisConfig: { + autoreconnect: true, + allowedMentions: { + everyone: false, + roles: false, + users: true + }, + maxShards: "auto", + messageLimit: 0, + intents: [ + "guilds", + "guildMessages", + "guildMessageReactions", + "directMessages", + "directMessageReactions" + ] }, - maxShards: "auto", - messageLimit: 0, - intents: [ - "guilds", - "guildEmojis", - "guildMessages", - "guildMessageReactions", - "directMessages", - "directMessageReactions" - ] - }, - // [Object] Redis config - redis: { - host: "localhost", - port: 6379, - password: "", - prefix: "lbrycurate:" + + logger: { + level: 'debug' + }, + + cron: { + loadFolder: './src/crons' + }, + + lbry: { + // [string] The SDK url to request from + sdkURL: "" + }, + + lbryx: { + // [string?] Amount to auto-fund upon account creation + startingBalance: "" + }, + + wallet: { + // [string] The ABSOLUTE path to the main wallet file to back up + path: "~/.lbryum/wallets/default_wallet", + // [string] The ABSOLUTE path folder to store wallet backups after every deletion + backupFolder: "~/.lbryum_backup/", + } } -} \ No newline at end of file +} diff --git a/package.json b/package.json index dc83fb0..663226a 100644 --- a/package.json +++ b/package.json @@ -1,29 +1,44 @@ { "name": "lbry-curate", - "version": "0.1.1", + "version": "1.0.0", "description": "Support the LBRY Community through Discord!", - "main": "src/bot.js", + "main": "dist/index.js", "scripts": { - "start": "node src/bot.js", - "eslint": "eslint ./src", - "eslint:fix": "eslint ./src --fix" + "start": "cd dist && node index.js", + "start:prod": "cd dist && NODE_ENV=production node index.js", + "build": "tsc", + "dev": "devScript", + "lint": "npx eslint --ext .ts ./src", + "lint:fix": "npx eslint --ext .ts ./src --fix" + }, + "devScript": { + "depCheck": false }, "dependencies": { - "abort-controller": "^3.0.0", - "cat-loggr": "^1.2.2", + "@dexare/cron": "^1.0.0", + "@dexare/logger": "^1.0.0", + "common-tags": "^1.8.0", "config": "^3.3.6", - "eris": "^0.15.1", + "dexare": "^2.0.1", "eventemitter3": "^4.0.7", - "fuzzy": "^0.1.3", - "moment": "^2.29.1", - "node-fetch": "^2.6.1", - "redis": "^3.1.2", - "require-reload": "^0.2.2", - "sequelize": "^6.6.2", - "sqlite3": "^5.0.2" + "quick.db": "^7.1.3", + "steno": "^2.0.0" }, "devDependencies": { - "eslint": "^7.28.0" + "@types/common-tags": "^1.8.0", + "@types/config": "^0.0.38", + "@types/cron": "^1.7.2", + "@types/needle": "^2.5.1", + "@types/node": "^15.12.4", + "@typescript-eslint/eslint-plugin": "^4.28.0", + "@typescript-eslint/parser": "^4.28.0", + "eslint": "^7.29.0", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-prettier": "^3.4.0", + "prettier": "^2.3.1", + "ts-devscript": "^3.0.5", + "ts-node": "^10.0.0", + "typescript": "^4.3.4" }, "repository": { "type": "git", diff --git a/pm2.json b/pm2.json index cbe1de0..8ac19cd 100644 --- a/pm2.json +++ b/pm2.json @@ -2,8 +2,8 @@ "apps": [ { "name": "LBRYCurate", - "script": "node", - "args": "src/bot.js" + "script": "yarn", + "args": "start:prod" } ] } diff --git a/src/bot.js b/src/bot.js deleted file mode 100644 index 28f1a73..0000000 --- a/src/bot.js +++ /dev/null @@ -1,151 +0,0 @@ -const Eris = require('eris'); -const Database = require('./database'); -const EventHandler = require('./events'); -const CommandLoader = require('./commandloader'); -const MessageAwaiter = require('./messageawaiter'); -const SQLiteDB = require('./sqlitedb'); -const path = require('path'); -const CatLoggr = require('cat-loggr'); -const config = require('config'); -const LBRY = require('./structures/LBRY'); - -class CurateBot extends Eris.Client { - constructor({ packagePath, mainDir } = {}) { - // Initialization - const pkg = require(packagePath || `${mainDir}/package.json`); - super(config.token, JSON.parse(JSON.stringify(config.discordConfig))); - this.dir = mainDir; - this.pkg = pkg; - this.logger = new CatLoggr({ - level: config.debug ? 'debug' : 'info', - levels: [ - { name: 'fatal', color: CatLoggr._chalk.red.bgBlack, err: true }, - { name: 'error', color: CatLoggr._chalk.black.bgRed, err: true }, - { name: 'warn', color: CatLoggr._chalk.black.bgYellow, err: true }, - { name: 'init', color: CatLoggr._chalk.black.bgGreen }, - { name: 'webserv', color: CatLoggr._chalk.black.bgBlue }, - { name: 'info', color: CatLoggr._chalk.black.bgCyan }, - { name: 'assert', color: CatLoggr._chalk.cyan.bgBlack }, - { name: 'poster', color: CatLoggr._chalk.yellow.bgBlack }, - { name: 'debug', color: CatLoggr._chalk.magenta.bgBlack, aliases: ['log', 'dir'] }, - { name: 'limiter', color: CatLoggr._chalk.gray.bgBlack }, - { name: 'fileload', color: CatLoggr._chalk.white.bgBlack } - ] - }); - this.logger.setGlobal(); - this.typingIntervals = new Map(); - - // Events - this.on('ready', () => console.info('All shards ready.')); - this.on('disconnect', () => console.warn('All shards Disconnected.')); - this.on('reconnecting', () => console.warn('Reconnecting client.')); - this.on('debug', message => console.debug(message)); - - // Shard Events - this.on('connect', id => console.info(`Shard ${id} connected.`)); - this.on('error', (error, id) => console.error(`Error in shard ${id}`, error)); - this.on('hello', (_, id) => console.debug(`Shard ${id} recieved hello.`)); - this.on('warn', (message, id) => console.warn(`Warning in Shard ${id}`, message)); - this.on('shardReady', id => console.info(`Shard ${id} ready.`)); - this.on('shardResume', id => console.warn(`Shard ${id} resumed.`)); - this.on('shardDisconnect', (error, id) => console.warn(`Shard ${id} disconnected`, error)); - - // SIGINT & uncaught exceptions - process.once('uncaughtException', async err => { - console.error('Uncaught Exception', err.stack); - await this.dieGracefully(); - process.exit(0); - }); - - process.once('SIGINT', async () => { - console.info('Caught SIGINT'); - await this.dieGracefully(); - process.exit(0); - }); - - console.init('Client initialized'); - } - - /** - * Creates a promise that resolves on the next event - * @param {string} event The event to wait for - */ - waitTill(event) { - return new Promise(resolve => this.once(event, resolve)); - } - - /** - * Starts the processes and log-in to Discord. - */ - async start() { - // Redis - this.db = new Database(this); - await this.db.connect(config.redis); - this.sqlite = new SQLiteDB(this); - - // Discord - await this.connect(); - await this.waitTill('ready'); - this.editStatus('online', { - name: `${config.prefix}help`, - type: 3, - }); - - // Commands - this.cmds = new CommandLoader(this, path.join(this.dir, config.commandsPath)); - this.cmds.reload(); - this.cmds.preloadAll(); - - // Events - this.messageAwaiter = new MessageAwaiter(this); - this.eventHandler = new EventHandler(this); - this.lbry = new LBRY(this); - } - - /** - * KIlls the bot - */ - dieGracefully() { - return super.disconnect(); - } - - // Typing - - /** - * Start typing in a channel - * @param {Channel} channel The channel to start typing in - */ - async startTyping(channel) { - if (this.isTyping(channel)) return; - await channel.sendTyping(); - this.typingIntervals.set(channel.id, setInterval(() => { - channel.sendTyping().catch(() => this.stopTyping(channel)); - }, 5000)); - } - - /** - * Whether the bot is currently typing in a channel - * @param {Channel} channel - */ - isTyping(channel) { - return this.typingIntervals.has(channel.id); - } - - /** - * Stops typing in a channel - * @param {Channel} channel - */ - stopTyping(channel) { - if (!this.isTyping(channel)) return; - const interval = this.typingIntervals.get(channel.id); - clearInterval(interval); - this.typingIntervals.delete(channel.id); - } -} - -const Bot = new CurateBot({ mainDir: path.join(__dirname, '..') }); -Bot.start().catch(e => { - Bot.logger.error('Failed to start bot! Exiting in 10 seconds...'); - console.error(e); - setTimeout(() => process.exit(0), 10000); -}); diff --git a/src/bot.ts b/src/bot.ts new file mode 100644 index 0000000..ba5c2aa --- /dev/null +++ b/src/bot.ts @@ -0,0 +1,97 @@ +import { DexareClient, BaseConfig, PermissionObject } from 'dexare'; +import config from 'config'; +import path from 'path'; +import chalk from 'chalk'; +import LoggerModule, { LoggerModuleOptions } from '@dexare/logger'; +import CronModule, { CronModuleOptions } from '@dexare/cron'; +import WalletModule, { WalletModuleOptions } from './modules/wallet'; +import LBRYModule, { LBRYModuleOptions } from './modules/lbry'; +import LBRYXModule, { LBRYXModuleOptions } from './modules/lbryx'; + +export const PRODUCTION = process.env.NODE_ENV === 'production'; + +export interface CurateConfig extends BaseConfig { + prefix: string | string[]; + mentionPrefix: boolean; + guildID: string; + embedColor: number; + + trustedRoles: string | string[]; + curatorRoles: string | string[]; + adminRoles: string | string[]; + + logger: LoggerModuleOptions; + wallet: WalletModuleOptions; + lbry: LBRYModuleOptions; + lbryx: LBRYXModuleOptions; + cron?: CronModuleOptions; +} + +export const client = new DexareClient(config.get('dexare') as CurateConfig); + +client.loadModules(LoggerModule, WalletModule, LBRYModule, LBRYXModule, CronModule); +client.commands.registerDefaults(['eval', 'kill', 'exec', 'load', 'unload', 'reload', 'help']); +client.commands.registerFromFolder(path.join(config.get('commandsPath' as string))); + +/* #region perms */ +export function rolePermissionCheck(...roles: (string | string[])[]) { + return (object: PermissionObject) => { + if (!object.member) return false; + const roleIDs: string[] = []; + roles.map((role) => roleIDs.concat(Array.isArray(role) ? role : [role])); + const member = client.bot.guilds.get(client.config.guildID)!.members.get(object.user.id)!; + + // elevated user bypass + if (client.config.elevated) { + if (Array.isArray(client.config.elevated)) return client.config.elevated.includes(object.user.id); + else if (client.config.elevated === object.user.id) return true; + } + + return roleIDs.map((r) => member.roles.includes(r)).includes(true); + }; +} + +client.permissions.register('lbry.curator', rolePermissionCheck(client.config.curatorRoles)); +client.permissions.register('lbry.trusted', rolePermissionCheck(client.config.trustedRoles)); +client.permissions.register('lbry.admin', rolePermissionCheck(client.config.adminRoles)); +client.permissions.register( + 'lbry.curatorOrAdmin', + rolePermissionCheck(client.config.curatorRoles, client.config.adminRoles) +); +client.permissions.register( + 'lbry.trustedOrAdmin', + rolePermissionCheck(client.config.trustedRoles, client.config.adminRoles) +); +/* #endregion */ + +const logger = client.modules.get('logger') as any as LoggerModule; +logger.moduleColors.lbry = chalk.black.bgCyan; +logger.moduleColors.lbryx = chalk.red.bgCyan; +logger.moduleColors.lbrybot = chalk.cyan.bgBlack; +logger.moduleColors.wallet = chalk.black.bgKeyword('brown'); + +process.once('SIGINT', async () => { + client.emit('logger', 'warn', 'sys', ['Caught SIGINT']); + await client.disconnect(); + process.exit(0); +}); + +process.once('beforeExit', async () => { + client.emit('logger', 'warn', 'sys', ['Exiting....']); + await client.disconnect(); + process.exit(0); +}); + +export async function connect() { + await client.connect(); + client.bot.shards.forEach((shard) => + shard.editStatus( + 'online', + PRODUCTION ? { name: 'the blockchain | c!help', type: 5 } : { name: 'logs | c!help', type: 3 } + ) + ); +} + +export async function disconnect() { + await client.disconnect(); +} diff --git a/src/commandloader.js b/src/commandloader.js deleted file mode 100644 index 691a7d7..0000000 --- a/src/commandloader.js +++ /dev/null @@ -1,101 +0,0 @@ -const fs = require('fs'); -const path = require('path'); -const reload = require('require-reload')(require); -const config = require('config'); - -module.exports = class CommandLoader { - constructor(client, cPath) { - this.commands = []; - this.path = path.resolve(cPath); - this.client = client; - } - - /** - * Loads commands from a folder - * @param {String} folderPath - */ - iterateFolder(folderPath) { - const files = fs.readdirSync(folderPath); - files.map(file => { - const filePath = path.join(folderPath, file); - const stat = fs.lstatSync(filePath); - if (stat.isSymbolicLink()) { - const realPath = fs.readlinkSync(filePath); - if (stat.isFile() && file.endsWith('.js')) { - this.load(realPath); - } else if (stat.isDirectory()) { - this.iterateFolder(realPath); - } - } else if (stat.isFile() && file.endsWith('.js')) - this.load(filePath); - else if (stat.isDirectory()) - this.iterateFolder(filePath); - }); - } - - /** - * Loads a command - * @param {string} commandPath - */ - load(commandPath) { - console.fileload('Loading command', commandPath); - const cls = reload(commandPath); - const cmd = new cls(this.client); - cmd.path = commandPath; - this.commands.push(cmd); - return cmd; - } - - /** - * Reloads all commands - */ - reload() { - this.commands = []; - this.iterateFolder(this.path); - } - - /** - * Gets a command based on it's name or alias - * @param {string} name The command's name or alias - */ - get(name) { - let cmd = this.commands.find(c => c.name === name); - if (cmd) return cmd; - this.commands.forEach(c => { - if (c.options.aliases.includes(name)) cmd = c; - }); - return cmd; - } - - /** - * Preloads a command - * @param {string} name The command's name or alias - */ - preload(name) { - if (!this.get(name)) return; - this.get(name)._preload(); - } - - /** - * Preloads all commands - */ - preloadAll() { - this.commands.forEach(c => c._preload()); - } - - /** - * Processes the cooldown of a command - * @param {Message} message - * @param {Command} command - */ - async processCooldown(message, command) { - if (config.elevated.includes(message.author.id)) return true; - const now = Date.now() - 1; - const cooldown = command.cooldownAbs; - let userCD = await this.client.db.hget(`cooldowns:${message.author.id}`, command.name) || 0; - if (userCD) userCD = parseInt(userCD); - if (userCD + cooldown > now) return false; - await this.client.db.hset(`cooldowns:${message.author.id}`, command.name, now); - return true; - } -}; diff --git a/src/commands/admin/abandonall.js b/src/commands/admin/abandonall.js deleted file mode 100644 index 832ce89..0000000 --- a/src/commands/admin/abandonall.js +++ /dev/null @@ -1,58 +0,0 @@ -const Command = require('../../structures/Command'); -const Util = require('../../util'); - -module.exports = class AbaondonAll extends Command { - get name() { return 'abandonall'; } - - get _options() { return { - aliases: ['abanall', 'dropall'], - permissions: ['admin'], - minimumArgs: 0 - }; } - - // @TODO: Refactor this command to be able to abandon all supports on the bot. - async exec(message, { args }) { - if (args.length) { - const discordID = Util.resolveToUserID(args[0]); - if (!discordID) - return message.channel.createMessage('That Discord user isn\'t valid.'); - - const account = await Util.LBRY.findOrCreateAccount(this.client, discordID, false); - if (!account.accountID) - return message.channel.createMessage('That user does not have an account.'); - - const supportsCount = await Util.LBRY.getSupportsCount(this.client, account.accountID); - if (supportsCount <= 0) - return message.channel.createMessage('That user does not have any supports.'); - - if (!await this.client.messageAwaiter.confirm(message, { - header: - `Are you sure you want to abandon **all supports** from that account? *(${ - supportsCount.toLocaleString()} support[s])*` - })) return; - await Util.LBRY.abandonAllClaims(this.client, account.accountID); - return message.channel.createMessage(`Abandoned ${supportsCount.toLocaleString()} claim(s).`); - } else { - if (!await this.client.messageAwaiter.confirm(message, { - header: 'Are you sure you want to abandon **all supports** from **all accounts**?' - })) return; - await this.client.startTyping(message.channel); - await Util.LBRY.syncPairs(this.client); - const pairs = await this.client.sqlite.getAll(); - let count = 0; - for (let i = 0, len = pairs.length; i < len; i++) { - const pair = pairs[i]; - const result = await Util.LBRY.abandonAllClaims(this.client, pair.lbryID); - count += result.count; - } - this.client.stopTyping(message.channel); - return message.channel.createMessage(`Abandoned ${count.toLocaleString()} claim(s).`); - } - } - - get metadata() { return { - category: 'Admin', - description: 'Abandons all supports of the bot or of a given account.', - usage: '[id|@mention]' - }; } -}; diff --git a/src/commands/admin/adminbalance.js b/src/commands/admin/adminbalance.js deleted file mode 100644 index 42bcc31..0000000 --- a/src/commands/admin/adminbalance.js +++ /dev/null @@ -1,28 +0,0 @@ -const Command = require('../../structures/Command'); -const config = require('config'); - -module.exports = class AdminBalance extends Command { - get name() { return 'adminbalance'; } - - get _options() { return { - aliases: ['abal', 'adminbal'], - permissions: ['admin'] - }; } - - async exec(message) { - const response = await this.client.lbry.walletBalance(); - const wallet = await response.json(); - if (await this.handleResponse(message, response, wallet)) return; - return message.channel.createMessage({ embed: { - color: config.embedColor, - description: `**Available:** ${wallet.result.available} LBC\n\n` + - `Reserved in Supports: ${wallet.result.reserved_subtotals.supports} LBC\n` + - `Total: ${wallet.result.total} LBC` - } }); - } - - get metadata() { return { - category: 'Admin', - description: 'Shows the master wallet balance.' - }; } -}; diff --git a/src/commands/admin/allsupports.js b/src/commands/admin/allsupports.js deleted file mode 100644 index bb14341..0000000 --- a/src/commands/admin/allsupports.js +++ /dev/null @@ -1,60 +0,0 @@ -const Command = require('../../structures/Command'); -const Util = require('../../util'); -const GenericPager = require('../../structures/GenericPager'); - -module.exports = class AllSupports extends Command { - get name() { return 'allsupports'; } - - get _options() { return { - aliases: ['asups', 'allsups'], - permissions: ['admin'], - minimumArgs: 0 - }; } - - async exec(message, { args }) { - let givenClaim; - if (args[0]) { - givenClaim = Util.resolveToClaimID(args[0]); - if (!givenClaim) - // @TODO use claim_search for invalid claim ids - return message.channel.createMessage('That Claim ID isn\'t valid.'); - } - - await Util.LBRY.syncPairs(this.client); - const pairs = await this.client.sqlite.getAll(); - if (pairs.length <= 0) - return message.channel.createMessage('No users found in the database.'); - - const allSupports = []; - - for (const pair of pairs) { - const supportsCount = await Util.LBRY.getSupportsCount(this.client, pair.lbryID); - if (supportsCount <= 0) continue; - const supportsResponse = await this.client.lbry.listSupports({ - accountID: pair.lbryID, page_size: supportsCount, claimID: givenClaim }); - const supports = (await supportsResponse.json()).result.items; - for (const support of supports) - allSupports.push({ - ...support, - pair - }); - } - - if (allSupports.length <= 0) - return message.channel.createMessage('No supports found.'); - - const paginator = new GenericPager(this.client, message, { - items: allSupports, - header: `All supports${ - givenClaim ? ` on claim \`${givenClaim}\`` : ''}`, itemTitle: 'Supports',itemsPerPage: 5, - display: item => `> ${item.name} \`${item.claim_id}\`\n> <@${item.pair.discordID}> ${item.amount} LBC\n` - }); - return paginator.start(message.channel.id, message.author.id); - } - - get metadata() { return { - category: 'Admin', - description: 'List all supports from all users.', - usage: '[claimID]' - }; } -}; diff --git a/src/commands/admin/deleteaccount.js b/src/commands/admin/deleteaccount.js deleted file mode 100644 index 98eadf6..0000000 --- a/src/commands/admin/deleteaccount.js +++ /dev/null @@ -1,42 +0,0 @@ -const Command = require('../../structures/Command'); -const Util = require('../../util'); - -module.exports = class DeleteAccount extends Command { - get name() { return 'deleteaccount'; } - - get _options() { return { - aliases: ['del', 'delacc'], - permissions: ['admin'], - minimumArgs: 1 - }; } - - async exec(message, { args }) { - const discordID = Util.resolveToUserID(args[0]); - if (!discordID) - return message.channel.createMessage('That Discord user isn\'t valid.'); - const account = await Util.LBRY.findOrCreateAccount(this.client, discordID, false); - if (account.accountID) { - const supportsCount = await Util.LBRY.getSupportsCount(this.client, account.accountID); - if (!await this.client.messageAwaiter.confirm(message, { - header: - `Are you sure you want to delete that account? *(${supportsCount.toLocaleString()} support[s])*` - })) return; - try { - await Util.LBRY.deleteAccount(this.client, discordID, account.accountID); - return message.channel.createMessage('Deleted account.'); - } catch (e) { - return message.channel.createMessage( - 'Failed to delete the account. An error most likely occured while backing up the wallet.' + - `\n\`\`\`\n${e.toString()}\`\`\`` - ); - } - } else - return message.channel.createMessage('That user does not have an account.'); - } - - get metadata() { return { - category: 'Admin', - description: 'Deletes a given Discord user\'s Curation account.', - usage: '' - }; } -}; diff --git a/src/commands/admin/deleteall.js b/src/commands/admin/deleteall.js deleted file mode 100644 index 7d3ff39..0000000 --- a/src/commands/admin/deleteall.js +++ /dev/null @@ -1,39 +0,0 @@ -const Command = require('../../structures/Command'); -const Util = require('../../util'); - -module.exports = class DeleteAll extends Command { - get name() { return 'deleteall'; } - - get _options() { return { - aliases: ['delall'], - permissions: ['admin'], - minimumArgs: 0 - }; } - - async exec(message) { - await Util.LBRY.syncPairs(this.client); - const pairs = await this.client.sqlite.getAll(); - - if (!await this.client.messageAwaiter.confirm(message, { - header: - `Are you sure you want to delete **all** ${pairs.length} accounts?` - })) return; - - for (const pair of pairs) { - try { - await Util.LBRY.deleteAccount(this.client, pair.discordID, pair.lbryID); - } catch (e) { - return message.channel.createMessage( - 'Failed to delete an account. An error most likely occured while backing up the wallet.' + - `\n\`\`\`\n${e.toString()}\`\`\`` - ); - } - } - return message.channel.createMessage('Deleted all accounts.'); - } - - get metadata() { return { - category: 'Admin', - description: 'Deletes all accounts in the database.' - }; } -}; diff --git a/src/commands/admin/deposit.js b/src/commands/admin/deposit.js deleted file mode 100644 index aa7ed8b..0000000 --- a/src/commands/admin/deposit.js +++ /dev/null @@ -1,24 +0,0 @@ -const Command = require('../../structures/Command'); -const Util = require('../../util'); - -module.exports = class Deposit extends Command { - get name() { return 'deposit'; } - - get _options() { return { - aliases: ['dp'], - permissions: ['admin'] - }; } - - async exec(message) { - const account = await Util.LBRY.findSDKAccount(this.client, account => account.is_default); - const response = await this.client.lbry.listAddresses({ account_id: account.id }); - const address = await response.json(); - if (await this.handleResponse(message, response, address)) return; - return message.channel.createMessage(`Address: ${address.result.items[0].address}`); - } - - get metadata() { return { - category: 'Admin', - description: 'Gets the address of the master wallet.' - }; } -}; diff --git a/src/commands/admin/fund.js b/src/commands/admin/fund.js deleted file mode 100644 index aef1d39..0000000 --- a/src/commands/admin/fund.js +++ /dev/null @@ -1,38 +0,0 @@ -const Command = require('../../structures/Command'); -const Util = require('../../util'); - -module.exports = class Fund extends Command { - get name() { return 'fund'; } - - get _options() { return { - aliases: ['fundacc', 'fundaccount'], - permissions: ['admin'], - minimumArgs: 2 - }; } - - async exec(message, { args }) { - const givenAmount = Util.LBRY.ensureDecimal(args[1]); - if (!givenAmount) - return message.channel.createMessage('The second argument must be a numeric amount of LBC to send!'); - - const discordID = Util.resolveToUserID(args[0]); - if (!discordID) - return message.channel.createMessage('That Discord user isn\'t valid.'); - - const account = await Util.LBRY.findOrCreateAccount(this.client, discordID); - if (!await this.client.messageAwaiter.confirm(message, { - header: `Are you sure you want to fund this account? *(${givenAmount} LBC)*` - })) return; - const response = await this.client.lbry.fundAccount({ to: account.accountID, amount: givenAmount }); - const transaction = await response.json(); - console.info('Funded account', account.accountID, transaction.result.txid); - const txid = transaction.result.txid; - return message.channel.createMessage(`Successfully funded account! https://explorer.lbry.com/tx/${txid}`); - } - - get metadata() { return { - category: 'Admin', - description: 'Funds a given Discord user\'s Curation account with the specified amount of LBC.', - usage: ' ' - }; } -}; diff --git a/src/commands/admin/fundall.js b/src/commands/admin/fundall.js deleted file mode 100644 index 007e585..0000000 --- a/src/commands/admin/fundall.js +++ /dev/null @@ -1,72 +0,0 @@ -const Command = require('../../structures/Command'); -const Util = require('../../util'); -const config = require('config'); - -module.exports = class FundAll extends Command { - get name() { return 'fundall'; } - - get _options() { return { - permissions: ['admin'], - minimumArgs: 1 - }; } - - async exec(message, { args }) { - const givenAmount = Util.LBRY.ensureDecimal(args[0]); - if (!givenAmount) - return message.channel.createMessage('The second argument must be a numeric amount of LBC to send!'); - - await Util.LBRY.syncPairs(this.client); - const pairs = await this.client.sqlite.getAll(); - if (pairs.length <= 0) { - await this.client.startTyping(message.channel); - const curatorRoles = Array.isArray(config.curatorRoleID) - ? config.curatorRoleID : [config.curatorRoleID]; - const members = await this.client.guilds.get(config.guildID).fetchMembers(); - for (const member of members) { - if (curatorRoles.map(r => member.roles.includes(r)).includes(true)) { - const account = await Util.LBRY.findOrCreateAccount(this.client, member.id); - pairs.push({ discordID: member.id, lbryID: account.accountID }); - } - } - await Util.halt(5000); - this.client.stopTyping(message.channel); - } - - if (!await this.client.messageAwaiter.confirm(message, { - header: `Are you sure you want to fund **all** accounts? *(${givenAmount} LBC)*` - })) return; - - await this.client.startTyping(message.channel); - const resultLines = []; - let funded = 0, - errored = 0; - for (const pair of pairs) { - const response = await this.client.lbry.fundAccount({ to: pair.lbryID, amount: givenAmount }); - await Util.halt(2000); - const transaction = await response.json(); - if ('code' in transaction) { - console.info('Failed to fund account', pair.lbryID, transaction.code, transaction.message); - resultLines.push(`${pair.discordID} ! ${transaction.code} - ${transaction.message}`); - errored++; - } else { - console.info('Funded account', pair.lbryID, transaction.result.txid); - resultLines.push(`${pair.discordID} - https://explorer.lbry.com/tx/${transaction.result.txid}`); - funded++; - } - await Util.halt(2000); - } - this.client.stopTyping(message.channel); - return message.channel.createMessage(errored - ? `Failed to fund ${errored} accounts! (${funded} funded)` - : `Successfully funded ${funded} account(s)!`, { - name: 'result.txt', - file: Buffer.from(resultLines.join('\n'), 'utf8') - }); - } - - get metadata() { return { - category: 'Admin', - description: 'Funds all users in the database a specified amount of LBC.', - usage: '' - }; } -}; diff --git a/src/commands/admin/listall.js b/src/commands/admin/listall.js deleted file mode 100644 index 09b94d1..0000000 --- a/src/commands/admin/listall.js +++ /dev/null @@ -1,49 +0,0 @@ -const Command = require('../../structures/Command'); -const GenericPager = require('../../structures/GenericPager'); - -module.exports = class ListAll extends Command { - get name() { return 'listall'; } - get _options() { return { - permissions: ['admin'], - minimumArgs: 0 - }; } - async exec(message, { args }) { - const pairs = await this.client.sqlite.getAll(); - if (pairs.length <= 0) - return message.channel.createMessage('No users found in the database.'); - - for (const pair of pairs) { - const response = await this.client.lbry.accountBalance(pair.lbryID); - const wallet = await response.json(); - if (!wallet.code) { - pair.wallet_available = wallet.result.available; - pair.wallet_reserve = wallet.result.reserved_subtotals.supports; - pair.wallet_ok = true; - } else { - console.error([ - 'There was an error while retrieving the balance of an account.', - 'This was likely caused by an old version of the Bot\'s SQLite database file. ' + - 'Run the sync command to avoid this error!' - ].join('\n')); - } - } - - const paginator = new GenericPager(this.client, message, { - items: pairs, itemTitle: 'Users', itemsPerPage: 5, - display: pair => `> <@${pair.discordID}> - \`${pair.lbryID}\`\n` + - `> ${pair.wallet_ok - ? `${pair.wallet_available} available, ${pair.wallet_reserve} staked.` - : 'Wallet Unavailable'}\n` - }); - - if (args[0]) - paginator.toPage(args[0]); - - return paginator.start(message.channel.id, message.author.id); - } - get metadata() { return { - category: 'Admin', - description: 'List all users in the database.', - usage: '[page]' - }; } -}; diff --git a/src/commands/admin/sync.js b/src/commands/admin/sync.js deleted file mode 100644 index a9fb2d6..0000000 --- a/src/commands/admin/sync.js +++ /dev/null @@ -1,20 +0,0 @@ -const Command = require('../../structures/Command'); -const Util = require('../../util'); - -module.exports = class Sync extends Command { - get name() { return 'sync'; } - - get _options() { return { - permissions: ['admin'] - }; } - - async exec(message) { - const synced = await Util.LBRY.syncPairs(this.client); - return message.channel.createMessage(`Synced ${synced} new pairs.`); - } - - get metadata() { return { - category: 'Admin', - description: 'Sync SDK-Discord pairs.' - }; } -}; diff --git a/src/commands/admin/withdraw.js b/src/commands/admin/withdraw.js deleted file mode 100644 index 091616e..0000000 --- a/src/commands/admin/withdraw.js +++ /dev/null @@ -1,45 +0,0 @@ -const Command = require('../../structures/Command'); -const Util = require('../../util'); - -module.exports = class Withdraw extends Command { - get name() { return 'withdraw'; } - - get _options() { return { - aliases: ['wd'], - permissions: ['admin'], - minimumArgs: 2 - }; } - - async exec(message, { args }) { - const amount = Util.LBRY.ensureDecimal(args[0]); - if (!amount) - return message.channel.createMessage('The first argument must be a numeric amount of LBC to send!'); - - // Check if the balance is more than requested - const balance = await this.client.lbry.walletBalance(); - const balanceJSON = await balance.json(); - if (await this.handleResponse(message, balance, balanceJSON)) return; - const availableBalance = parseFloat(balanceJSON.result.available); - if (parseFloat(amount) > availableBalance) - return message.channel.createMessage( - 'There is not enough available LBC in the wallet to send that amount!'); - - // Send to wallet - if (!await this.client.messageAwaiter.confirm(message, { - header: `Are you sure you want to send ${amount} to \`${args[1]}\`? ` + - `*(remaining: ${availableBalance - parseFloat(amount)})*` - })) return; - const response = await this.client.lbry.sendToWallet({ amount, to: args[1] }); - const transaction = await response.json(); - if (await this.handleResponse(message, response, transaction)) return; - console.debug('withdrew from master wallet', transaction); - return message.channel.createMessage(`Sent ${amount} LBC to ${args[1]}.\n` + - `https://explorer.lbry.com/tx/${transaction.result.txid}`); - } - - get metadata() { return { - category: 'Admin', - description: 'Sends funds to an address from the master wallet.', - usage: '
' - }; } -}; diff --git a/src/commands/curator/abandon.js b/src/commands/curator/abandon.js deleted file mode 100644 index 6503f82..0000000 --- a/src/commands/curator/abandon.js +++ /dev/null @@ -1,35 +0,0 @@ -const Command = require('../../structures/Command'); -const Util = require('../../util'); - -module.exports = class Abandon extends Command { - get name() { return 'abandon'; } - - get _options() { return { - aliases: ['aban', 'drop'], - permissions: ['curatorOrAdmin'], - minimumArgs: 1 - }; } - - async exec(message, { args }) { - const givenClaim = Util.resolveToClaimID(args[0]); - if (!givenClaim) - // @TODO use claim_search for invalid claim ids - return message.channel.createMessage('That Claim ID isn\'t valid.'); - - const account = await Util.LBRY.findOrCreateAccount(this.client, message.author.id); - - // Drop support - const response = await this.client.lbry.abandonSupport({ - accountID: account.accountID, claimID: givenClaim }); - const transaction = await response.json(); - if (await this.handleResponse(message, response, transaction)) return; - const txid = transaction.result.txid; - return message.channel.createMessage(`Abandon successful! https://explorer.lbry.com/tx/${txid}`); - } - - get metadata() { return { - category: 'Curator', - description: 'Abandons a support on a given claim.', - usage: '' - }; } -}; diff --git a/src/commands/curator/balance.js b/src/commands/curator/balance.js deleted file mode 100644 index b8034a0..0000000 --- a/src/commands/curator/balance.js +++ /dev/null @@ -1,59 +0,0 @@ -const Command = require('../../structures/Command'); -const Util = require('../../util'); -const config = require('config'); - -module.exports = class Balance extends Command { - get name() { return 'balance'; } - - get _options() { return { - aliases: ['bal'], - permissions: ['curatorOrAdmin'] - }; } - - async exec(message, { args }) { - if (args.length) { - if (!Util.CommandPermissions.admin(this.client, message)) { - const admins = (Array.isArray(config.adminRoleID) ? config.adminRoleID : [config.adminRoleID]) - .map(id => `"${this.client.guilds.get(config.guildID).roles.get(id).name}"`); - return message.channel.createMessage( - `You need to have the ${admins.join('/')} role(s) to see others balances!`); - } - - const discordID = Util.resolveToUserID(args[0]); - if (!discordID) - return message.channel.createMessage('That Discord user isn\'t valid.'); - - const account = await Util.LBRY.findOrCreateAccount(this.client, discordID, false); - if (!account.accountID) - return message.channel.createMessage('That Discord user does not have an account.'); - - const response = await this.client.lbry.accountBalance(account.accountID); - const wallet = await response.json(); - if (await this.handleResponse(message, response, wallet)) return; - return message.channel.createMessage({ embed: { - color: config.embedColor, - description: `<@${discordID}> has **${wallet.result.available}** LBC available.\n\n` + - `Reserved in Supports: ${wallet.result.reserved_subtotals.supports} LBC\n` + - `Total: ${wallet.result.total} LBC` - } }); - } else { - const account = await Util.LBRY.findOrCreateAccount(this.client, message.author.id); - const response = await this.client.lbry.accountBalance(account.accountID); - const wallet = await response.json(); - if (await this.handleResponse(message, response, wallet)) return; - return message.channel.createMessage({ embed: { - color: config.embedColor, - description: `You have **${wallet.result.available}** LBC available.\n\n` + - `Reserved in Supports: ${wallet.result.reserved_subtotals.supports} LBC\n` + - `Total: ${wallet.result.total} LBC` + - (account.newAccount ? '\n\n:warning: This account was just created. ' + - 'Please wait a few seconds, and run the command again to get an accurate balance.' : '') - } }); - } - } - - get metadata() { return { - category: 'Curator', - description: 'Shows the user\'s account balance.' - }; } -}; diff --git a/src/commands/curator/support.js b/src/commands/curator/support.js deleted file mode 100644 index d165f00..0000000 --- a/src/commands/curator/support.js +++ /dev/null @@ -1,52 +0,0 @@ -const Command = require('../../structures/Command'); -const Util = require('../../util'); - -module.exports = class Support extends Command { - get name() { return 'support'; } - - get _options() { return { - aliases: ['sup'], - permissions: ['curatorOrAdmin'], - minimumArgs: 2 - }; } - - async exec(message, { args }) { - const givenAmount = Util.LBRY.ensureDecimal(args[1]); - if (!givenAmount) - return message.channel.createMessage('The second argument must be a numeric amount of LBC to send!'); - - const givenClaim = Util.resolveToClaimID(args[0]); - if (!givenClaim) - // @TODO use claim_search for invalid claim ids - return message.channel.createMessage('That Claim ID isn\'t valid.'); - - const account = await Util.LBRY.findOrCreateAccount(this.client, message.author.id); - if (account.newAccount) { - // Wait for the blockchain to complete the funding - await message.channel.sendTyping(); - await Util.halt(3000); - } - - // Get and check balance - const walletResponse = await this.client.lbry.accountBalance(account.accountID); - const wallet = await walletResponse.json(); - if (await this.handleResponse(message, walletResponse, wallet)) return; - const balance = wallet.result.available; - if (parseFloat(givenAmount) > parseFloat(balance)) - return message.channel.createMessage('You don\'t have enough LBC to do this!'); - - // Create support - const response = await this.client.lbry.createSupport({ - accountID: account.accountID, claimID: givenClaim, amount: givenAmount }); - const transaction = await response.json(); - if (await this.handleResponse(message, response, transaction)) return; - const txid = transaction.result.txid; - return message.channel.createMessage(`Support successful! https://explorer.lbry.com/tx/${txid}`); - } - - get metadata() { return { - category: 'Curator', - description: 'Support a given claim.', - usage: ' ' - }; } -}; diff --git a/src/commands/curator/supports.js b/src/commands/curator/supports.js deleted file mode 100644 index ddd9d28..0000000 --- a/src/commands/curator/supports.js +++ /dev/null @@ -1,61 +0,0 @@ -const Command = require('../../structures/Command'); -const GenericPager = require('../../structures/GenericPager'); -const Util = require('../../util'); - -module.exports = class Supports extends Command { - get name() { return 'supports'; } - get _options() { return { - aliases: ['sups'], - permissions: ['curatorOrAdmin'], - minimumArgs: 0 - }; } - async exec(message, { args }) { - let account, givenClaim, discordID; - if (args.length === 2) { - // Check for if claim ID and discord user is given - givenClaim = args[1]; - if (!/^[a-f0-9]{40}$/.test(givenClaim)) - return message.channel.createMessage('That Claim ID isn\'t valid.'); - - discordID = Util.resolveToUserID(args[0]); - if (!discordID) - return message.channel.createMessage('That Discord user isn\'t valid.'); - account = await Util.LBRY.findOrCreateAccount(this.client, discordID, false); - } else if (args.length === 1) { - // Check for only if a discord user is given - discordID = Util.resolveToUserID(args[0]); - if (!discordID) - return message.channel.createMessage('That Discord user isn\'t valid.'); - account = await Util.LBRY.findOrCreateAccount(this.client, discordID, false); - } else { - // Default to message author - account = await Util.LBRY.findOrCreateAccount(this.client, message.author.id); - } - - if (!account.accountID) - return message.channel.createMessage('That Discord user does not have an account.'); - - const supportsCount = await Util.LBRY.getSupportsCount(this.client, account.accountID); - if (supportsCount <= 0) - return message.channel.createMessage('No supports found.'); - - const supportsResponse = await this.client.lbry.listSupports({ - accountID: account.accountID, page_size: supportsCount, claimID: givenClaim }); - console.debug( - `Displaying supports for ${ - account.accountID}${givenClaim ? ` and claimID ${givenClaim}` : ''}, (${supportsCount})`); - const supports = (await supportsResponse.json()).result.items; - const paginator = new GenericPager(this.client, message, { - items: supports, - header: `All supports for <@${discordID || message.author.id}>${ - givenClaim ? ` on claim \`${givenClaim}\`` : ''}`, itemTitle: 'Supports',itemsPerPage: 5, - display: item => `> ${item.name} \`${item.claim_id}\`\n> ${item.amount} LBC\n` - }); - return paginator.start(message.channel.id, message.author.id); - } - get metadata() { return { - category: 'Curator', - description: 'Shows the user\'s list of supports.', - usage: '[id/@mention] [claimID]' - }; } -}; diff --git a/src/commands/help.js b/src/commands/help.js deleted file mode 100644 index 73a4dfd..0000000 --- a/src/commands/help.js +++ /dev/null @@ -1,101 +0,0 @@ -const Command = require('../structures/Command'); -const Util = require('../util'); -const config = require('config'); - -module.exports = class Help extends Command { - get name() { return 'help'; } - - get _options() { return { - aliases: [ - '?', 'h', 'commands', 'cmds', // English - 'yardim', 'yardım', 'komutlar', // Turkish - 'ayuda', // Spanish - 'ajuda' // Catalan & Portuguese - ], - permissions: ['embed'], - cooldown: 0, - }; } - - exec(message, { args, }) { - if (args[0]) { - // Display help on a command - const command = this.client.cmds.get(args[0]); - if (!command) - return message.channel.createMessage(`The command \`${args[0]}\` could not be found.`); - else { - const embed = { - title: `${config.prefix}${command.name}`, - color: config.embedColor, - fields: [ - { name: '*Usage*', - value: `${config.prefix}${command.name}${ - command.metadata.usage ? - ` \`${command.metadata.usage}\`` : ''}` } - ], - description: command.metadata.description - }; - - // Cooldown - if (command.options.cooldown) - embed.fields.push({ - name: '*Cooldown*', - value: `${command.options.cooldown.toLocaleString()} second(s)`, - inline: false - }); - - // Aliases - if (command.options.aliases.length !== 0) embed.fields.push({ - name: '*Alias(es)*', - value: command.options.aliases.map(a => `\`${a}\``).join(', ') - }); - - // Image - if (command.metadata.image) - embed.image = { url: command.metadata.image }; - - // Note - if (command.metadata.note) - embed.fields.push({ - name: '*Note*', - value: command.metadata.note - }); - - return message.channel.createMessage({ embed }); - } - } else { - // Display general help command - const embed = { - color: config.embedColor, - description: 'LBRY Curate', - footer: { text: `\`${config.prefix}help [command]\` for more info.` }, - fields: [] - }; - - // Populate categories - const categories = {}; - this.client.cmds.commands.forEach(v => { - if (!v.options.listed && !config.elevated.includes(message.author.id)) return; - const string = v.name; - if (categories[v.metadata.category]) - categories[v.metadata.category].push(string); - else categories[v.metadata.category] = [string]; - }); - - // List categories - Util.keyValueForEach(categories, (k, v) => { - embed.fields.push({ - name: `*${k}*`, - value: '```' + v.join(', ') + '```', - inline: true - }); - }); - return message.channel.createMessage({ embed }); - } - } - - get metadata() { return { - category: 'General', - description: 'Shows the help message and gives information on commands.', - usage: '[command]' - }; } -}; diff --git a/src/commands/owner/asynceval.js b/src/commands/owner/asynceval.js deleted file mode 100644 index a068b20..0000000 --- a/src/commands/owner/asynceval.js +++ /dev/null @@ -1,38 +0,0 @@ -/* jshint evil: true */ - -const Command = require('../../structures/Command'); -const Util = require('../../util'); - -module.exports = class AsyncEval extends Command { - get name() { return 'asynceval'; } - - get _options() { return { - aliases: ['ae', 'aeval', 'aevaluate', 'asyncevaluate'], - permissions: ['elevated'], - listed: false, - }; } - - // eslint-disable-next-line no-unused-vars - async exec(message, opts) { - try { - const start = Date.now(); - const code = Util.Prefix.strip(message, this.client).split(' ').slice(1).join(' '); - const result = await eval(`(async () => {${code}})()`); - const time = Date.now() - start; - return Util.Hastebin.autosend( - `Took ${time.toLocaleString()} ms\n\`\`\`js\n${result}\`\`\`\n`, - message); - } catch (e) { - return Util.Hastebin.autosend('```js\n' + e.stack + '\n```', message); - } - } - - get metadata() { return { - category: 'Developer', - description: 'Evaluate code asynchronously.', - usage: '', - note: 'Due to the added async IIFE wrapper in this command, ' + - 'it is necessary to use the return statement to return a result.\n' + - 'e.g. `return 1`' - }; } -}; diff --git a/src/commands/owner/eval.js b/src/commands/owner/eval.js deleted file mode 100644 index f1fb708..0000000 --- a/src/commands/owner/eval.js +++ /dev/null @@ -1,35 +0,0 @@ -/* jshint evil: true */ - -const Command = require('../../structures/Command'); -const Util = require('../../util'); - -module.exports = class Eval extends Command { - get name() { return 'eval'; } - - get _options() { return { - aliases: ['e'], - permissions: ['elevated'], - listed: false, - minimumArgs: 1 - }; } - - // eslint-disable-next-line no-unused-vars - async exec(message, opts) { - try { - const start = Date.now(); - const result = eval(Util.Prefix.strip(message, this.client).split(' ').slice(1).join(' ')); - const time = Date.now() - start; - return Util.Hastebin.autosend( - `Took ${time.toLocaleString()} ms\n\`\`\`js\n${result}\`\`\`\n`, - message); - } catch (e) { - return Util.Hastebin.autosend('```js\n' + e.stack + '\n```', message); - } - } - - get metadata() { return { - category: 'Developer', - description: 'Evaluate code.', - usage: '' - }; } -}; diff --git a/src/commands/owner/exec.js b/src/commands/owner/exec.js deleted file mode 100644 index e28dce0..0000000 --- a/src/commands/owner/exec.js +++ /dev/null @@ -1,34 +0,0 @@ -const Command = require('../../structures/Command'); -const Util = require('../../util'); -const { exec } = require('child_process'); - -module.exports = class Exec extends Command { - get name() { return 'exec'; } - - get _options() { return { - aliases: ['ex', 'sys'], - permissions: ['elevated'], - listed: false, - minimumArgs: 1 - }; } - - codeBlock(content, lang = null) { - return `\`\`\`${lang ? `${lang}\n` : ''}${content}\`\`\``; - } - - async exec(message) { - await this.client.startTyping(message.channel); - exec(Util.Prefix.strip(message, this.client).split(' ').slice(1).join(' '), (err, stdout, stderr) => { - this.client.stopTyping(message.channel); - if (err) return message.channel.createMessage(this.codeBlock(err, 'js')); - const stdErrBlock = (stderr ? this.codeBlock(stderr, 'js') + '\n' : ''); - return Util.Hastebin.autosend(stdErrBlock + this.codeBlock(stdout), message); - }); - } - - get metadata() { return { - category: 'Developer', - description: 'Do some terminal commands.', - usage: ' …' - }; } -}; diff --git a/src/commands/owner/reload.js b/src/commands/owner/reload.js deleted file mode 100644 index 4378d3a..0000000 --- a/src/commands/owner/reload.js +++ /dev/null @@ -1,23 +0,0 @@ -const Command = require('../../structures/Command'); - -module.exports = class Reload extends Command { - get name() { return 'reload'; } - - get _options() { return { - aliases: ['r'], - permissions: ['elevated'], - listed: false, - }; } - - async exec(message) { - const sentMessage = await message.channel.createMessage('♻️ Reloading commands…'); - this.client.cmds.reload(); - this.client.cmds.preloadAll(); - return sentMessage.edit('✅ Reloaded commands.'); - } - - get metadata() { return { - category: 'Developer', - description: 'Reloads all commands.' - }; } -}; diff --git a/src/commands/owner/reloadone.js b/src/commands/owner/reloadone.js deleted file mode 100644 index a552cc0..0000000 --- a/src/commands/owner/reloadone.js +++ /dev/null @@ -1,46 +0,0 @@ -const Command = require('../../structures/Command'); -const fs = require('fs'); - -module.exports = class ReloadOne extends Command { - get name() { return 'reloadone'; } - - get _options() { return { - aliases: ['r1', 'reloadsingle', 'rs'], - permissions: ['elevated'], - minimumArgs: 1, - listed: false, - }; } - - async exec(message, { args }) { - const commands = args.map(name => this.client.cmds.get(name)); - if (commands.includes(undefined)) - return message.channel.createMessage('Invalid command!'); - - const fileExist = commands.map(command => { - const path = command.path; - const stat = fs.lstatSync(path); - return stat.isFile(); - }); - - if (fileExist.includes(false)) - return message.channel.createMessage('A file that had a specified command no longer exists!'); - - const sentMessage = await message.channel.createMessage('♻️ Reloading commands…'); - - const reloadedCommands = commands.map(command => { - const path = command.path; - const index = this.client.cmds.commands.indexOf(command); - this.client.cmds.commands.splice(index, 1); - const newCommand = this.client.cmds.load(path); - newCommand.preload(); - return newCommand; - }); - return sentMessage.edit(`✅ Reloaded ${reloadedCommands.map(c => `\`${c.name}\``).join(', ')}.`); - } - - get metadata() { return { - category: 'Developer', - description: 'Reloads specific commands.', - usage: ' [commandName] …' - }; } -}; diff --git a/src/commands/owner/restart.js b/src/commands/owner/restart.js deleted file mode 100644 index 517e223..0000000 --- a/src/commands/owner/restart.js +++ /dev/null @@ -1,22 +0,0 @@ -const Command = require('../../structures/Command'); - -module.exports = class Restart extends Command { - get name() { return 'restart'; } - - get _options() { return { - aliases: ['re'], - permissions: ['elevated'], - listed: false, - }; } - - async exec(message) { - await message.channel.createMessage('Restarting...'); - await this.client.dieGracefully(); - process.exit(0); - } - - get metadata() { return { - category: 'Developer', - description: 'Restarts the bot.' - }; } -}; diff --git a/src/commands/ping.js b/src/commands/ping.js deleted file mode 100644 index 41dda22..0000000 --- a/src/commands/ping.js +++ /dev/null @@ -1,27 +0,0 @@ -const Command = require('../structures/Command'); - -module.exports = class Ping extends Command { - get name() { return 'ping'; } - - get _options() { return { - aliases: ['p', 'pong'], - cooldown: 0, - }; } - - async exec(message) { - const currentPing = Array.from(this.client.shards.values()) - .map(shard => shard.latency).reduce((prev, val) => prev + val, 0); - const timeBeforeMessage = Date.now(); - const sentMessage = await message.channel.createMessage('> :ping_pong: ***Ping...***\n' + - `> WS: ${currentPing.toLocaleString()} ms`); - await sentMessage.edit( - '> :ping_pong: ***Pong!***\n' + - `> WS: ${currentPing.toLocaleString()} ms\n` + - `> REST: ${(Date.now() - timeBeforeMessage).toLocaleString()} ms`); - } - - get metadata() { return { - category: 'General', - description: 'Pong!' - }; } -}; diff --git a/src/commands/trusted/tabandon.js b/src/commands/trusted/tabandon.js deleted file mode 100644 index be6e999..0000000 --- a/src/commands/trusted/tabandon.js +++ /dev/null @@ -1,40 +0,0 @@ -const Command = require('../../structures/Command'); -const Util = require('../../util'); - -module.exports = class TAbandon extends Command { - get name() { return 'tabandon'; } - - get _options() { return { - aliases: ['taban', 'tdrop'], - permissions: ['trustedOrAdmin'], - minimumArgs: 1 - }; } - - async exec(message, { args }) { - const givenClaim = Util.resolveToClaimID(args[0]); - if (!givenClaim) - // @TODO use claim_search for invalid claim ids - return message.channel.createMessage('That Claim ID isn\'t valid.'); - - if (!await this.client.messageAwaiter.confirm(message, { - header: - 'Are you sure you want to abandon a claim from a **trusted** account?' - })) return; - - const account = await Util.LBRY.findSDKAccount(this.client, account => account.is_default); - - // Drop support - const response = await this.client.lbry.abandonSupport({ - accountID: account.id, claimID: givenClaim }); - const transaction = await response.json(); - if (await this.handleResponse(message, response, transaction)) return; - const txid = transaction.result.txid; - return message.channel.createMessage(`Abandon successful! https://explorer.lbry.com/tx/${txid}`); - } - - get metadata() { return { - category: 'Trusted', - description: 'Abandons a support on a given claim from the trusted account.', - usage: '' - }; } -}; diff --git a/src/commands/trusted/tbalance.js b/src/commands/trusted/tbalance.js deleted file mode 100644 index b5c1262..0000000 --- a/src/commands/trusted/tbalance.js +++ /dev/null @@ -1,30 +0,0 @@ -const Command = require('../../structures/Command'); -const Util = require('../../util'); -const config = require('config'); - -module.exports = class TBalance extends Command { - get name() { return 'tbalance'; } - - get _options() { return { - aliases: ['tbal', 'trustedbal', 'trustedbalance'], - permissions: ['trustedOrAdmin'] - }; } - - async exec(message) { - const account = await Util.LBRY.findSDKAccount(this.client, account => account.is_default); - const response = await this.client.lbry.accountBalance(account.id); - const wallet = await response.json(); - if (await this.handleResponse(message, response, wallet)) return; - return message.channel.createMessage({ embed: { - color: config.embedColor, - description: `**${wallet.result.available}** LBC is available in the trusted account.\n\n` + - `Reserved in Supports: ${wallet.result.reserved_subtotals.supports} LBC\n` + - `Total: ${wallet.result.total} LBC` - } }); - } - - get metadata() { return { - category: 'Trusted', - description: 'Shows the trusted wallet balance.' - }; } -}; diff --git a/src/commands/trusted/tsupport.js b/src/commands/trusted/tsupport.js deleted file mode 100644 index d196197..0000000 --- a/src/commands/trusted/tsupport.js +++ /dev/null @@ -1,51 +0,0 @@ -const Command = require('../../structures/Command'); -const Util = require('../../util'); - -module.exports = class TSupport extends Command { - get name() { return 'tsupport'; } - - get _options() { return { - aliases: ['tsup'], - permissions: ['trustedOrAdmin'], - minimumArgs: 2 - }; } - - async exec(message, { args }) { - const givenAmount = Util.LBRY.ensureDecimal(args[1]); - if (!givenAmount) - return message.channel.createMessage('The second argument must be a numeric amount of LBC to send!'); - - const givenClaim = Util.resolveToClaimID(args[0]); - if (!givenClaim) - // @TODO use claim_search for invalid claim ids - return message.channel.createMessage('That Claim ID isn\'t valid.'); - - // Get and check balance - const account = await Util.LBRY.findSDKAccount(this.client, account => account.is_default); - const walletResponse = await this.client.lbry.accountBalance(account.id); - const wallet = await walletResponse.json(); - if (await this.handleResponse(message, walletResponse, wallet)) return; - const balance = wallet.result.available; - if (parseFloat(givenAmount) > parseFloat(balance)) - return message.channel.createMessage('You don\'t have enough LBC to do this!'); - - if (!await this.client.messageAwaiter.confirm(message, { - header: - 'Are you sure you want to support a claim from a **trusted** account?' - })) return; - - // Create support - const response = await this.client.lbry.createSupport({ - accountID: account.id, claimID: givenClaim, amount: givenAmount }); - const transaction = await response.json(); - if (await this.handleResponse(message, response, transaction)) return; - const txid = transaction.result.txid; - return message.channel.createMessage(`Support successful! https://explorer.lbry.com/tx/${txid}`); - } - - get metadata() { return { - category: 'Trusted', - description: 'Support a given claim from the trusted account.', - usage: ' ' - }; } -}; diff --git a/src/commands/trusted/tsupports.js b/src/commands/trusted/tsupports.js deleted file mode 100644 index fe26636..0000000 --- a/src/commands/trusted/tsupports.js +++ /dev/null @@ -1,42 +0,0 @@ -const Command = require('../../structures/Command'); -const GenericPager = require('../../structures/GenericPager'); -const Util = require('../../util'); - -module.exports = class TSupports extends Command { - get name() { return 'tsupports'; } - get _options() { return { - aliases: ['tsups'], - permissions: ['trustedOrAdmin'], - minimumArgs: 0 - }; } - async exec(message, { args }) { - let givenClaim; - if (args[0]) { - givenClaim = Util.resolveToClaimID(args[0]); - if (!givenClaim) - // @TODO use claim_search for invalid claim ids - return message.channel.createMessage('That Claim ID isn\'t valid.'); - } - - const account = await Util.LBRY.findSDKAccount(this.client, account => account.is_default); - const supportsCount = await Util.LBRY.getSupportsCount(this.client, account.id); - if (supportsCount <= 0) - return message.channel.createMessage('No supports found.'); - - const supportsResponse = await this.client.lbry.listSupports({ - accountID: account.id, page_size: supportsCount, claimID: givenClaim }); - const supports = (await supportsResponse.json()).result.items; - const paginator = new GenericPager(this.client, message, { - items: supports, - header: `All supports for the trusted account${ - givenClaim ? ` on claim \`${givenClaim}\`` : ''}`, itemTitle: 'Supports', itemsPerPage: 5, - display: item => `> ${item.name} \`${item.claim_id}\`\n> ${item.amount} LBC\n` - }); - return paginator.start(message.channel.id, message.author.id); - } - get metadata() { return { - category: 'Trusted', - description: 'Shows the list of supports from the trusted account.', - usage: '[claimID]' - }; } -}; diff --git a/src/crons/flushCache.cron.ts b/src/crons/flushCache.cron.ts new file mode 100644 index 0000000..9a271bf --- /dev/null +++ b/src/crons/flushCache.cron.ts @@ -0,0 +1,10 @@ +import { DexareClient, MemoryDataManager } from 'dexare'; +import { CurateConfig } from '../bot'; + +export const name = 'flush-cache'; +export const time = '0 * * * *'; +export const start = true; +export async function onTick(client: DexareClient) { + const data = client.data as MemoryDataManager; + data.flushThrottles(); +} diff --git a/src/database.js b/src/database.js deleted file mode 100644 index 2faa71c..0000000 --- a/src/database.js +++ /dev/null @@ -1,139 +0,0 @@ -const redis = require('redis'); -const { EventEmitter } = require('eventemitter3'); - -/** - * The Redis database handler - */ -module.exports = class Database extends EventEmitter { - constructor(client) { - super(); - this.client = client; - this.reconnectAfterClose = true; - console.init('Redis initialized'); - } - - /** - * Creates a client and connects to the database - * @param {Object} options - */ - connect({ host = 'localhost', port, password, prefix }) { - console.info('Connecting to redis...'); - return new Promise((resolve, reject) => { - this.redis = redis.createClient({ host, port, password, prefix }); - this.redis.on('error', this.onError.bind(this)); - this.redis.on('warning', w => console.warn('Redis Warning', w)); - this.redis.on('end', () => this.onClose.bind(this)); - this.redis.on('reconnecting', () => console.warn('Reconnecting to redis...')); - this.redis.on('ready', () => console.info('Redis client ready.')); - this.redis.on('connect', () => console.info('Redis connection has started.')); - this.host = host; - this.port = port; - this.password = password; - - this.redis.once('ready', resolve.bind(this)); - this.redis.once('error', reject.bind(this)); - }); - } - - // #region Redis functions - hget(key, hashkey) { - return new Promise((resolve, reject) => { - this.redis.HGET(key, hashkey, (err, value) => { - if (err) reject(err); - resolve(value); - }); - }); - } - - hset(key, hashkey, value) { - return new Promise((resolve, reject) => { - this.redis.HSET(key, hashkey, value, (err, res) => { - if (err) reject(err); - resolve(res); - }); - }); - } - - incr(key) { - return new Promise((resolve, reject) => { - this.redis.incr(key, (err, res) => { - if (err) reject(err); - resolve(res); - }); - }); - } - - get(key) { - return new Promise((resolve, reject) => { - this.redis.get(key, function(err, reply) { - if (err) reject(err); - resolve(reply); - }); - }); - } - - expire(key, ttl) { - return new Promise((resolve, reject) => { - this.redis.expire(key, ttl, (err, value) => { - if (err) reject(err); - resolve(value); - }); - }); - } - - - exists(key) { - return new Promise((resolve, reject) => { - this.redis.exists(key, (err, value) => { - if (err) reject(err); - resolve(value === 1); - }); - }); - } - - set(key, value) { - return new Promise((resolve, reject) => { - this.redis.set(key, value, (err, res) => { - if (err) reject(err); - resolve(res); - }); - }); - } - // #endregion - - /** - * Reconnects the client - */ - async reconnect() { - console.warn('Attempting redis reconnection'); - this.conn = await this.connect(this); - } - - /** - * Disconnects the client - */ - disconnect() { - this.reconnectAfterClose = false; - return new Promise(resolve => { - this.redis.once('end', resolve); - this.redis.quit(); - }); - } - - /** - * @private - */ - onError(err) { - console.error('Redis Error', err); - this.emit('error', err); - } - - /** - * @private - */ - async onClose() { - console.error('Redis closed'); - this.emit('close'); - if (this.reconnectAfterClose) await this.reconnect(); - } -}; diff --git a/src/events.js b/src/events.js deleted file mode 100644 index c03fa00..0000000 --- a/src/events.js +++ /dev/null @@ -1,50 +0,0 @@ -const ArgumentInterpreter = require('./structures/ArgumentInterpreter'); -const Util = require('./util'); -const config = require('config'); - -module.exports = class Events { - constructor(client) { - this.client = client; - client.on('messageCreate', this.onMessage.bind(this)); - client.on('messageReactionAdd', this.onReaction.bind(this)); - } - - async onMessage(message) { - if (message.author.bot || message.author.system) return; - - // Check to see if bot can send messages - if (message.channel.type !== 1 && - !message.channel.permissionsOf(this.client.user.id).has('sendMessages')) return; - - // Message awaiter - if (this.client.messageAwaiter.processHalt(message)) return; - - // Command parsing - const argInterpretor = new ArgumentInterpreter(Util.Prefix.strip(message, this.client)); - const args = argInterpretor.parseAsStrings(); - const commandName = args.splice(0, 1)[0]; - const command = this.client.cmds.get(commandName, message); - if (!message.content.match(Util.Prefix.regex(this.client)) || !command) return; - - try { - await command._exec(message, { - args - }); - } catch (e) { - if (config.debug) { - console.error(`The '${command.name}' command failed.`); - console.log(e); - } - message.channel.createMessage(':fire: An error occurred while processing that command!'); - this.client.stopTyping(message.channel); - } - } - - onReaction(message, emoji, member) { - const id = `${message.id}:${member.id}`; - if (this.client.messageAwaiter.reactionCollectors.has(id)) { - const collector = this.client.messageAwaiter.reactionCollectors.get(id); - collector._onReaction(emoji, member.id); - } - } -}; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..e6fcbc0 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,9 @@ +import path from 'path'; + +// Config fix for running in devscript +if (path.parse(process.cwd()).name === 'dist') + process.env.NODE_CONFIG_DIR = path.join(process.cwd(), '..', 'config'); + +import { connect } from './bot'; + +connect(); \ No newline at end of file diff --git a/src/messageawaiter.js b/src/messageawaiter.js deleted file mode 100644 index bb54aad..0000000 --- a/src/messageawaiter.js +++ /dev/null @@ -1,154 +0,0 @@ -const Halt = require('./structures/Halt'); -const ReactionCollector = require('./structures/ReactionCollector'); - -/** - * Handles async message functions - */ -class MessageAwaiter { - constructor(client) { - this.client = client; - this.halts = new Map(); - this.reactionCollectors = new Map(); - } - - /** - * Creates a halt. This pauses any events in the event handler for a specific channel and user. - * This allows any async functions to handle any follow-up messages. - * @param {string} channelID The channel's ID - * @param {string} userID The user's ID - * @param {number} [timeout=30000] The time until the halt is auto-cleared - */ - createHalt(channelID, userID, timeout = 30000) { - const id = `${channelID}:${userID}`; - if (this.halts.has(id)) this.halts.get(id).end(); - const halt = new Halt(this, timeout); - halt.once('end', () => this.halts.delete(id)); - this.halts.set(id, halt); - return halt; - } - - /** - * Creates a reaction collector. Any reactions from the user will be emitted from the collector. - * @param {string} message The message to collect from - * @param {string} userID The user's ID - * @param {number} [timeout=30000] The time until the halt is auto-cleared - */ - createReactionCollector(message, userID, timeout = 30000) { - const id = `${message.id}:${userID}`; - if (this.reactionCollectors.has(id)) this.reactionCollectors.get(id).end(); - const collector = new ReactionCollector(this, timeout); - collector.once('end', () => this.reactionCollectors.delete(id)); - this.reactionCollectors.set(id, collector); - return collector; - } - - /** - * Gets an ongoing halt based on a message - * @param {Message} message - */ - getHalt(message) { - const id = `${message.channel.id}:${message.author.id}`; - return this.halts.get(id); - } - - /** - * Processes a halt based on a message - * @param {Message} message - */ - processHalt(message) { - const id = `${message.channel.id}:${message.author.id}`; - if (this.halts.has(id)) { - const halt = this.halts.get(id); - halt._onMessage(message); - return true; - } - return false; - } - - /** - * Awaits the next message from a user - * @param {Message} message The message to wait for - * @param {Object} [options] The options for the await - * @param {number} [options.filter] The message filter - * @param {number} [options.timeout=30000] The timeout for the halt - * @returns {?Message} - */ - awaitMessage(message, { filter = () => true, timeout = 30000 } = {}) { - return new Promise(resolve => { - const halt = this.createHalt(message.channel.id, message.author.id, timeout); - let foundMessage = null; - halt.on('message', nextMessage => { - if (filter(nextMessage)) { - foundMessage = nextMessage; - halt.end(); - } - }); - halt.on('end', () => resolve(foundMessage)); - }); - } - - /** - * Same as {@see #awaitMessage}, but is used for getting user input via next message - * @param {Message} message The message to wait for - * @param {Object} [options] The options for the await - * @param {number} [options.filter] The message filter - * @param {number} [options.timeout=30000] The timeout for the halt - * @param {string} [options.header] The content to put in the bot message - * @returns {?Message} - */ - async getInput(message, { filter = () => true, timeout = 30000, header = null } = {}) { - await message.channel.createMessage(`<@${message.author.id}>, ` + - (header || 'Type the message you want to input.') + '\n\n' + - `Typing "<@!${this.client.user.id}> cancel" will cancel the input.`); - return new Promise(resolve => { - const halt = this.createHalt(message.channel.id, message.author.id, timeout); - let handled = false, input = null; - halt.on('message', nextMessage => { - if (filter(nextMessage)) { - const cancelRegex = new RegExp(`^(?:<@!?${this.client.user.id}>\\s?)(cancel|stop|end)$`); - - if (!nextMessage.content || cancelRegex.test(nextMessage.content.toLowerCase())) { - handled = true; - message.channel.createMessage(`<@${message.author.id}>, Your last input was canceled.`); - } else input = nextMessage.content; - halt.end(); - } - }); - halt.on('end', async () => { - if (!input && !handled) - await message.channel.createMessage(`<@${message.author.id}>, Your last input was canceled.`); - resolve(input); - }); - }); - } - - /** - * Same as {@see #awaitMessage}, but is used for confirmation - * @param {Message} message The message to wait for - * @param {Object} [options] The options for the await - * @param {number} [options.timeout=30000] The timeout for the halt - * @param {string} [options.header] The content to put in the bot message - * @returns {?Message} - */ - async confirm(message, { timeout = 30000, header = null } = {}) { - await message.channel.createMessage(`<@${message.author.id}>, ` + - (header || 'Are you sure you want to do this?') + '\n\n' + - 'Type `yes` to confirm. Any other message will cancel the confirmation.'); - return new Promise(resolve => { - const halt = this.createHalt(message.channel.id, message.author.id, timeout); - let input = false; - halt.on('message', nextMessage => { - input = nextMessage.content === 'yes'; - halt.end(); - }); - halt.on('end', async () => { - if (!input) - await message.channel.createMessage(`<@${message.author.id}>, Confirmation canceled.`); - resolve(input); - }); - }); - } -} - -MessageAwaiter.Halt = Halt; -module.exports = MessageAwaiter; \ No newline at end of file diff --git a/src/sqlitedb.js b/src/sqlitedb.js deleted file mode 100644 index 31b5081..0000000 --- a/src/sqlitedb.js +++ /dev/null @@ -1,63 +0,0 @@ -const Sequelize = require('sequelize'); - -module.exports = class SQLiteDB { - constructor() { - this.sequelize = new Sequelize({ - dialect: 'sqlite', - storage: 'config/curate.sqlite', - define: { timestamps: false } - }); - - class UserPair extends Sequelize.Model {} - - UserPair.init({ - discordID: { - type: Sequelize.STRING, - allowNull: false, - primaryKey: true, - unique: true, - }, - lbryID: { - type: Sequelize.STRING, - allowNull: false, - unique: true, - } - }, { sequelize: this.sequelize, modelName: 'user' }); - UserPair.sync(); - this.model = UserPair; - } - - /** - * Gets a pair from a Discord ID - * @param {string} id - */ - async get(id) { - const item = await this.model.findOne({ where: { discordID: id } }); - return item ? item.get({ plain: true }) : null; - } - - /** - * Creates an ID pair - * @param {string} discordID - * @param {string} lbryID - */ - pair(discordID, lbryID) { - return this.model.create({ discordID, lbryID }); - } - - /** - * Removes an ID pair - * @param {string} discordID - */ - remove(discordID) { - return this.model.destroy({ where: { discordID } }); - } - - /** - * Gets all pairs in the database - */ - async getAll() { - const items = await this.model.findAll(); - return items.map(item => item.get({ plain: true })); - } -}; \ No newline at end of file diff --git a/src/structures/ArgumentInterpreter.js b/src/structures/ArgumentInterpreter.js deleted file mode 100644 index c06066d..0000000 --- a/src/structures/ArgumentInterpreter.js +++ /dev/null @@ -1,182 +0,0 @@ -/** - * A class that iterates a string's index - * @see ArgumentInterpreter - */ -class StringIterator { - /** - * @param {string} string The string to iterate through - */ - constructor(string) { - this.string = string; - this.index = 0; - this.previous = 0; - this.end = string.length; - } - - /** - * Get the character on an index and moves the index forward. - * @returns {?string} - */ - get() { - const nextChar = this.string[this.index]; - if (!nextChar) - return nextChar; - else { - this.previous += this.index; - this.index += 1; - return nextChar; - } - } - - /** - * Reverts to the previous index. - */ - undo() { - this.index = this.previous; - } - - /** - * The previous character that was used - * @type {string} - */ - get prevChar() { - return this.string[this.previous]; - } - - /** - * Whether or not the index is out of range - * @type {boolean} - */ - get inEOF() { - return this.index >= this.end; - } -} - -/** - * Parses arguments from a message. - */ -class ArgumentInterpreter { - /** - * @param {string} string The string that will be parsed for arguments - * @param {?Object} options The options for the interpreter - * @param {?boolean} [options.allowWhitespace=false] Whether to allow whitespace characters in the arguments - */ - constructor(string, { allowWhitespace = false } = {}) { - this.string = string; - this.allowWhitespace = allowWhitespace; - } - - /** - * Parses the arguements as strings. - * @returns {Array} - */ - parseAsStrings() { - const args = []; - let currentWord = ''; - let quotedWord = ''; - const string = this.allowWhitespace ? this.string : this.string.trim(); - const iterator = new StringIterator(string); - while (!iterator.inEOF) { - const char = iterator.get(); - if (char === undefined) break; - - if (this.isOpeningQuote(char) && iterator.prevChar !== '\\') { - currentWord += char; - const closingQuote = ArgumentInterpreter.QUOTES[char]; - - // Quote iteration - while (!iterator.inEOF) { - const quotedChar = iterator.get(); - - // Unexpected EOF - if (quotedChar === undefined) { - args.push(...currentWord.split(' ')); - break; - } - - if (quotedChar == '\\') { - currentWord += quotedChar; - const nextChar = iterator.get(); - - if (nextChar === undefined) { - args.push(...currentWord.split(' ')); - break; - } - - currentWord += nextChar; - // Escaped quote - if (ArgumentInterpreter.ALL_QUOTES.includes(nextChar)) { - quotedWord += nextChar; - } else { - // Ignore escape - quotedWord += quotedChar + nextChar; - } - continue; - } - - // Closing quote - if (quotedChar == closingQuote) { - currentWord = ''; - args.push(quotedWord); - quotedWord = ''; - break; - } - - currentWord += quotedChar; - quotedWord += quotedChar; - } - continue; - } - - if (/^\s$/.test(char)) { - if (currentWord) - args.push(currentWord); - currentWord = ''; - continue; - } - - currentWord += char; - } - - if (currentWord.length) - args.push(...currentWord.split(' ')); - return args; - } - - /** - * Checks whether or not a character is an opening quote - * @param {string} char The character to check - */ - isOpeningQuote(char) { - return Object.keys(ArgumentInterpreter.QUOTES).includes(char); - } -} - -// Opening / Closing -ArgumentInterpreter.QUOTES = { - '"': '"', - '‘': '’', - '‚': '‛', - '“': '”', - '„': '‟', - '⹂': '⹂', - '「': '」', - '『': '』', - '〝': '〞', - '﹁': '﹂', - '﹃': '﹄', - '"': '"', - '「': '」', - '«': '»', - '‹': '›', - '《': '》', - '〈': '〉', -}; - -ArgumentInterpreter.ALL_QUOTES = Object.keys(ArgumentInterpreter.QUOTES) - .map(i => ArgumentInterpreter.QUOTES[i]) - .concat(Object.keys(ArgumentInterpreter.QUOTES)); - -ArgumentInterpreter.StringIterator = StringIterator; - -module.exports = ArgumentInterpreter; \ No newline at end of file diff --git a/src/structures/Command.js b/src/structures/Command.js deleted file mode 100644 index d26424b..0000000 --- a/src/structures/Command.js +++ /dev/null @@ -1,149 +0,0 @@ -const Util = require('../util'); -const config = require('config'); - -/** - * A command in the bot. - */ -class Command { - /** - * @param {TrelloBot} client - */ - constructor(client) { - this.client = client; - this.subCommands = {}; - } - - /** - * @private - */ - _preload() { - if (!this.preload() && config.debug) - this.client.cmds.logger.info('Preloading command', this.name); - } - - /** - * The function executed while loading the command into the command handler. - */ - preload() { - return true; - } - - /** - * @private - * @param {Message} message - * @param {Object} opts - */ - async _exec(message, opts) { - // Check minimum arguments - if (this.options.minimumArgs > 0 && opts.args.length < this.options.minimumArgs) - return message.channel.createMessage( - `${this.options.minimumArgsMessage}\nUsage: ${config.prefix}${this.name}${ - this.metadata.usage ? - ` \`${this.metadata.usage}\`` : ''}`); - - // Check commmand permissions - const curators = Array.isArray(config.curatorRoleID) ? config.curatorRoleID : [config.curatorRoleID]; - const admins = Array.isArray(config.adminRoleID) ? config.adminRoleID : [config.adminRoleID]; - const trusteds = Array.isArray(config.trustedRoleID) ? config.trustedRoleID : [config.trustedRoleID]; - if (this.options.permissions.length) - for (const i in this.options.permissions) { - const perm = this.options.permissions[i]; - if (!Util.CommandPermissions[perm]) - throw new Error(`Invalid command permission "${perm}"`); - if (!Util.CommandPermissions[perm](this.client, message, opts)) - return message.channel.createMessage({ - attach: 'I need the permission `Attach Files` to use this command!', - embed: 'I need the permission `Embed Links` to use this command!', - emoji: 'I need the permission `Use External Emojis` to use this command!', - elevated: 'Only the elevated users of the bot can use this command!', - curator: `This command requires you to have the ${ - curators.map(id => - `"${this.client.guilds.get(config.guildID).roles.get(id).name}"`).join('/')} role!`, - admin: `This command requires you to have the ${ - admins.map(id => - `"${this.client.guilds.get(config.guildID).roles.get(id).name}"`).join('/')} role!`, - curatorOrAdmin: `This command requires you to have the ${ - curators.map(id => - `"${this.client.guilds.get(config.guildID).roles.get(id).name}"`).join('/')} or ${ - admins.map(id => - `"${this.client.guilds.get(config.guildID).roles.get(id).name}"`).join('/')} role!`, - trustedOrAdmin: `This command requires you to have the ${ - trusteds.map(id => - `"${this.client.guilds.get(config.guildID).roles.get(id).name}"`).join('/')} or ${ - admins.map(id => - `"${this.client.guilds.get(config.guildID).roles.get(id).name}"`).join('/')} role!`, - guild: 'This command must be ran in a guild!', - }[perm]); - } - - // Process cooldown - if (!this.cooldownAbs || await this.client.cmds.processCooldown(message, this)) { - await this.exec(message, opts); - } else { - const cd = await this.client.db.hget(`cooldowns:${message.author.id}`, this.name); - return message.channel.createMessage( - `:watch: This command is on cooldown! Wait ${ - Math.ceil(this.cooldownAbs - (Date.now() - cd))} second(s) before doing this again!`); - } - } - - // eslint-disable-next-line no-empty-function, no-unused-vars - exec(Message, opts) { } - - /** - * @private - */ - async handleResponse(message, response, json) { - if (!json) json = await response.json(); - if (response.status !== 200 || json.error) { - const error = response.status === 500 ? - { message: 'Internal server error' } : json.error; - console.error(`SDK error in ${this.name}:${message.author.id}`, response, error); - await message.channel.createMessage( - `LBRY-SDK returned ${response.status} with an error: \`${error.message}\``); - return true; - } - return false; - } - - /** - * The options for the command - * @type {Object} - */ - get options() { - const options = { - aliases: [], - cooldown: 2, - listed: true, - minimumArgs: 0, - permissions: [], - - minimumArgsMessage: 'Not enough arguments!', - }; - Object.assign(options, this._options); - return options; - } - - /** - * @private - */ - _options() { return {}; } - - /** - * The cooldown in milliseconnds - * @returns {number} - */ - get cooldownAbs() { return this.options.cooldown * 1000; } - - /** - * The metadata for the command - * @return {Object} - */ - get metadata() { - return { - category: 'Misc.', - }; - } -} - -module.exports = Command; \ No newline at end of file diff --git a/src/structures/GenericPager.js b/src/structures/GenericPager.js deleted file mode 100644 index 1e3c586..0000000 --- a/src/structures/GenericPager.js +++ /dev/null @@ -1,103 +0,0 @@ -const Paginator = require('./Paginator'); -const lodash = require('lodash'); -const config = require('config'); - -/** - * A generic pager that shows a list of items - */ -class GenericPager extends Paginator { - /** - * @param {TrelloBot} client The client to use - * @param {Message} message The user's message to read permissions from - * @param {Object} options The options for the pager - * @param {Array} options.items The items the paginator will display - * @param {number} [options.itemsPerPage=15] How many items a page will have - * @param {Function} [options.display] The function that will be used to display items on the prompt - * @param {Object} [options.embedExtra] The embed object to add any extra embed elements to the prompt - * @param {string} [options.itemTitle='words.item.many'] The title to use for the items - * @param {string} [options.header] The text to show above the prompt - * @param {string} [options.footer] The text to show below the prompt - */ - constructor(client, message, { - items = [], itemsPerPage = 15, - display = item => item.toString(), - embedExtra = {}, itemTitle = 'Items', - header = null, footer = null - } = {}) { - super(client, message, { items, itemsPerPage }); - this.displayFunc = display; - this.embedExtra = embedExtra; - this.itemTitle = itemTitle; - this.header = header; - this.footer = footer; - } - - /** - * Whether or not this instance can use embed - * @returns {boolean} - */ - canEmbed() { - return this.message.channel.type === 1 || - this.message.channel.permissionsOf(this.client.user.id).has('embedLinks'); - } - - /** - * Updates the current message - * @returns {Promise} - */ - updateMessage() { - return this.message.edit(this.currentMessage).catch(() => {}); - } - - /** - * The message for the current page - * @type {Object|string} - */ - get currentMessage() { - const displayPage = this.page.map((item, index) => - this.displayFunc(item, index, ((this.pageNumber - 1) * this.itemsPerPage) + index)); - if (this.canEmbed()) { - const embed = lodash.defaultsDeep({ - title: `${this.itemTitle} ` + - `(${this.items.length}, Page ${this.pageNumber}/${this.maxPages})`, - description: this.header || undefined, - footer: this.footer ? { text: this.footer } : undefined, - fields: [] - }, this.embedExtra, { color: config.embedColor }); - - embed.fields.push({ - name: '*List Prompt*', - value: displayPage.join('\n') - }); - - return { embed }; - } else { - const top = `${this.itemTitle} ` + - `(${this.items.length}, Page ${this.pageNumber}/${this.maxPages})`; - const lines = '─'.repeat(top.length); - return (this.header || '') + '```prolog\n' + `${top}\n` + `${lines}\n` + - displayPage.join('\n') + `${lines}\`\`\`` + (this.footer || ''); - } - } - - /** - * Starts the reaction collector and pagination - * @param {string} channelID The channel to post the new message to - * @param {string} userID The user's ID that started the process - * @param {number} timeout - */ - async start(channelID, userID, timeout) { - this.message = await this.client.createMessage(channelID, this.currentMessage); - return super.start(userID, timeout); - } - - /** - * @private - */ - _change() { - this.updateMessage().catch(() => this.collector.end()); - this.emit('change', this.pageNumber); - } -} - -module.exports = GenericPager; \ No newline at end of file diff --git a/src/structures/GenericPrompt.js b/src/structures/GenericPrompt.js deleted file mode 100644 index 4de7427..0000000 --- a/src/structures/GenericPrompt.js +++ /dev/null @@ -1,141 +0,0 @@ -const GenericPager = require('./GenericPager'); -const Paginator = require('./Paginator'); -const lodash = require('lodash'); -const fuzzy = require('fuzzy'); - -/** - * A generic pager that shows a list of items - */ -class GenericPrompt { - /** - * @param {TrelloBot} client The client to use - * @param {Message} message The user's message to read permissions from - * @param {Object} pagerOptions The options for the pager - */ - constructor(client, message, pagerOptions = {}) { - this.client = client; - this.message = message; - this.pagerOptions = pagerOptions; - this.displayFunc = pagerOptions.display || ((item) => item.toString()); - - // Override some pager options - this.pagerOptions.display = (item, i, ai) => `${ai + 1}. ${this.displayFunc(item, i, ai)}`; - this.pagerOptions.header = pagerOptions.header || 'Type the number of the item you want to use.'; - this.pagerOptions.footer = (pagerOptions.footer ? pagerOptions.footer + '\n\n' : '') + - 'Typing "cancel" will close this prompt.'; - this.pagerOptions.embedExtra = this.pagerOptions.embedExtra || {}; - this.pagerOptions.embedExtra.author = { - name: `${message.author.username}#${message.author.discriminator}`, - icon_url: message.author.avatarURL || message.author.defaultAvatarURL - }; - - this.pager = new GenericPager(client, message, this.pagerOptions); - this.halt = null; - } - - /** - * Starts the prompt - * @param {string} channelID The channel to post the new message to - * @param {string} userID The user's ID that started the process - * @param {number} timeout - */ - async choose(channelID, userID, timeout) { - if (this.pager.items.length === 0) - return null; - else if (this.pager.items.length === 1) - return this.pager.items[0]; - - await this.pager.start(channelID, userID, timeout); - this.halt = this.client.messageAwaiter.createHalt(channelID, userID, timeout); - - // Sync timeouts - if (this.pager.collector) - this.pager.collector.restart(); - this.halt.restart(); - - return new Promise(resolve => { - let foundItem = null; - - this.halt.on('message', nextMessage => { - if (this.pager.canManage()) - nextMessage.delete().catch(() => {}); - - if (GenericPrompt.CANCEL_TRIGGERS.includes(nextMessage.content.toLowerCase())) { - foundItem = { _canceled: true }; - this.halt.end(); - } - const chosenIndex = parseInt(nextMessage.content); - if (chosenIndex <= 0) return; - const chosenItem = this.pager.items[chosenIndex - 1]; - if (chosenItem !== undefined) { - foundItem = chosenItem; - this.halt.end(); - } - }); - - this.halt.on('end', () => { - // In case the halt ends before reactions are finished coming up - this.pager.reactionsCleared = true; - if (this.pager.collector) - this.pager.collector.end(); - this.pager.message.delete().catch(() => {}); - - if (foundItem && foundItem._canceled) - foundItem = null; - else if (foundItem === null) - this.pager.message.channel.createMessage( - `<@${userID}>, Your last prompt was timed out.`).catch(() => {}); - - resolve(foundItem); - }); - - if (this.pager.collector) - this.pager.collector.on('reaction', emoji => { - if (Paginator.STOP === emoji.name) { - foundItem = { _canceled: true }; - this.halt.end(); - } - }); - }); - } - - /** - * Filters the items into a search and prompts results. - * @param {string} query The term to search for - * @param {Object} options The options passed on to {@see #choose} . - * @param {string} options.channelID The channel to post the new message to - * @param {string} options.userID The user's ID that started the process - * @param {number} options.timeout - * @param {string|Function} [key='name'] The path to use for searches - */ - async search(query, { channelID, userID, timeout }, key = 'name') { - if (!query) - return this.choose(channelID, userID, timeout); - - const results = fuzzy.filter(query, this.pager.items, { - extract: item => { - if (typeof key === 'string') - return lodash.get(item, key); - else if (typeof key === 'function') - return key(item); - else if (key === null) - return item; - } - }).map(el => el.original); - - if (!results.length) - return { _noresults: true }; - - const tempItems = this.pager.items; - this.pager.items = results; - const result = await this.choose(channelID, userID, timeout); - this.pager.items = tempItems; - return result; - } -} - -GenericPrompt.CANCEL_TRIGGERS = [ - 'c', 'cancel', 's', 'stop' -]; - -module.exports = GenericPrompt; \ No newline at end of file diff --git a/src/structures/Halt.js b/src/structures/Halt.js deleted file mode 100644 index 38559cd..0000000 --- a/src/structures/Halt.js +++ /dev/null @@ -1,61 +0,0 @@ -const EventEmitter = require('eventemitter3'); - -/** - * A class that represents a message halt - */ -class Halt extends EventEmitter { - constructor(messageAwaiter, timeout) { - super(); - this.messageAwaiter = messageAwaiter; - this.timeout = timeout; - this.interval = null; - this.ended = false; - this.messages = new Map(); - this._endBind = this._end.bind(this); - this._start(); - } - - /** - * Restarts the halt. - * @param {number} [timeout] The new timeout to halt by - */ - restart(timeout) { - if (this.ended) return; - clearTimeout(this.interval); - this.interval = setTimeout(this._endBind, timeout || this.timeout); - } - - /** - * Ends the halt. - */ - end() { - if (this.ended) return; - clearTimeout(this.interval); - this._end(); - } - - /** - * @private - */ - _onMessage(message) { - this.messages.set(message.id, message); - this.emit('message', message); - } - - /** - * @private - */ - _start() { - this.interval = setTimeout(this._endBind, this.timeout); - } - - /** - * @private - */ - _end() { - this.ended = true; - this.emit('end'); - } -} - -module.exports = Halt; \ No newline at end of file diff --git a/src/structures/LBRY.js b/src/structures/LBRY.js deleted file mode 100644 index f29d2e2..0000000 --- a/src/structures/LBRY.js +++ /dev/null @@ -1,210 +0,0 @@ -const fetch = require('node-fetch'); -const AbortController = require('abort-controller'); -const config = require('config'); -const Util = require('../util'); - -class LBRY { - constructor(client) { - this.client = client; - } - - _request(options = {}) { - if (!options.url) - throw new Error('No URL was provided!'); - - if (!options.method) - options.method = 'get'; - - const url = new URL(options.noBase ? options.url : config.sdkURL + options.url); - let body = options.body; - - // Query params - if (options.query && Object.keys(options.query).length) - Object.keys(options.query).map(key => - url.searchParams.append(key, options.query[key])); - - // Body Format - if (body && options.bodyType === 'json') - body = JSON.stringify(body); - else if (body && options.bodyType === 'form') { - body = new URLSearchParams(); - Object.keys(options.body).forEach(key => - body.append(key, options.body[key])); - } - - // Hash - if (options.hash) - url.hash = options.hash; - - // User Agent - const userAgent = `LBRYCurate (https://github.com/LBRYFoundation/curate ${this.client.pkg.version}) Node.js/${process.version}`; - if (!options.headers) - options.headers = { - 'User-Agent': userAgent - }; - else - options.headers['User-Agent'] = userAgent; - - // Abort Controller - const controller = new AbortController(); - const controllerTimeout = setTimeout(controller.abort.bind(controller), 5000); - - return new Promise((resolve, reject) => { - fetch(url.href, { - body, - headers: options.headers, - method: options.method, - signal: controller.signal - }).then(r => { - clearTimeout(controllerTimeout); - resolve(r); - }).catch(e => { - clearTimeout(controllerTimeout); - if (e && e.type === 'aborted') - resolve(e); else reject(e); - }); - }); - } - - _sdkRequest(method, params = {}) { - const payload = { method }; - if (params && Object.keys(params).length) - payload.params = params; - - return this._request({ - url: '/', - method: 'post', - bodyType: 'json', - body: payload - }); - } - - // #region Account Methods - /** - * List details of all of the accounts or a specific account. - */ - listAccounts(params) { - return this._sdkRequest('account_list', params); - } - - /** - * Create a new account. - * @param {string} accountName The account's name - */ - createAccount(accountName) { - return this._sdkRequest('account_create', { account_name: accountName, single_key: true }); - } - - /** - * Return the balance of an account - * @param {string} accountID The account's ID - */ - accountBalance(accountID) { - return this._sdkRequest('account_balance', { account_id: accountID }); - } - - /** - * Transfer some amount (or --everything) to an account from another account (can be the same account). - * @param {object} options - * @param {string} options.to The account ID to fund - * @param {string} options.from The account ID to fund from - * @param {boolean} options.everything Transfer everything - * @param {string} options.amount The amount to fund (integer/float string) - */ - fundAccount({ to, from, everything, amount }) { - return this._sdkRequest('account_fund', { - to_account: to, from_account: from, everything, - amount: Util.LBRY.ensureDecimal(amount), broadcast: true }); - } - - /** - * Remove an existing account. - * @param {string} accountID The account's ID - */ - removeAccount(accountID) { - return this._sdkRequest('account_remove', { account_id: accountID }); - } - // #endregion - - // #region Support Methods - /** - * List supports and tips in my control. - * @param {object} options - * @param {string} options.accountID The account ID to list - * @param {string|Array} options.claimID The clain ID to list - */ - listSupports({ accountID, claimID }) { - return this._sdkRequest('support_list', { account_id: accountID, claim_id: claimID }); - } - - /** - * Create a support or a tip for name claim. - * @param {object} options - * @param {string} options.accountID The account ID to use - * @param {string} options.claimID The claim ID to use - * @param {number} options.amount The amount of support - */ - createSupport({ accountID, claimID, amount }) { - return this._sdkRequest('support_create', { - account_id: accountID, claim_id: claimID, - amount: Util.LBRY.ensureDecimal(amount), funding_account_ids: [accountID] }); - } - - /** - * Abandon supports, including tips, of a specific claim, optionally keeping some amount as supports. - * @param {object} options - * @param {string} options.accountID The account ID to use - * @param {string} options.claimID The claim ID to use - */ - abandonSupport({ accountID, claimID }) { - return this._sdkRequest('support_abandon', { account_id: accountID, claim_id: claimID }); - } - // #endregion - - // #region Wallet, Address, Claim Methods - /** - * Return the balance of a wallet - */ - walletBalance() { - return this._sdkRequest('wallet_balance'); - } - - /** - * Send the same number of credits to multiple - * addresses using all accounts in wallet to fund the - * transaction and the default account to receive any change. - * @param {object} options - * @param {string} options.to The wallet address to fund - * @param {string} options.amount The amount to send - */ - sendToWallet({ amount, to }) { - return this._sdkRequest('wallet_send', { amount: Util.LBRY.ensureDecimal(amount), addresses: to }); - } - - /** - * List account addresses or details. - * @param {object} options - * @param {string} options.to How many items should be per page - * @param {string} options.amount The amount to send - */ - listAddresses({ page_size = 1, account_id } = {}) { - return this._sdkRequest('address_list', { page_size, account_id }); - } - - /** - * Search for stream and channel claims on the blockchain. - * @param {object} options - * @param {string} options.name The claim name to search - * @param {string} options.text The text to search - * @param {string} options.claimID The claim ID to search - * @param {string} options.channel Signed channel name (e.g: @Coolguy3289) - * @param {string} options.channelType The type of claim - */ - searchClaim({ name, text, claimID, channel, channelType }) { - return this._sdkRequest('claim_search', { - name, text, claim_id: claimID, channel, channel_type: channelType }); - } - // #endregion -} - -module.exports = LBRY; \ No newline at end of file diff --git a/src/structures/MultiSelect.js b/src/structures/MultiSelect.js deleted file mode 100644 index 2fb60f0..0000000 --- a/src/structures/MultiSelect.js +++ /dev/null @@ -1,145 +0,0 @@ -const EventEmitter = require('eventemitter3'); -const GenericPager = require('./GenericPager'); -const Paginator = require('./Paginator'); -const lodash = require('lodash'); - -/** - * A prompt that allows users to toggle multiple values - */ -class MultiSelect extends EventEmitter { - /** - * @param {TrelloBot} client The client to use - * @param {Message} message The user's message to read permissions from - * @param {Object} options The options for the multi-select - * @param {string|Array} options.path The path of the boolean - * @param {string} [options.checkEmoji] The emoji that resembles true - * @param {string} [options.uncheckEmoji] The emoji that resembles false - * @param {Object} pagerOptions The options for the pager - */ - constructor(client, message, { path, checkEmoji = '☑️', uncheckEmoji = '⬜' }, pagerOptions = {}) { - super(); - this.client = client; - this.message = message; - this.pagerOptions = pagerOptions; - this.displayFunc = pagerOptions.display || ((item) => item.toString()); - this.boolPath = path; - - // Override some pager options - this.pagerOptions.display = (item, i, ai) => { - const value = lodash.get(item, this.boolPath); - return `\`[${ai + 1}]\` ${value ? checkEmoji : uncheckEmoji} ${this.displayFunc(item, i, ai)}`; - }; - this.pagerOptions.header = pagerOptions.header || 'Type the number of the item to toggle its value.'; - this.pagerOptions.footer = (pagerOptions.footer ? pagerOptions.footer + '\n\n' : '') + - 'Type "save" to save the selection, otherwise type "cancel" to exit.'; - this.pagerOptions.embedExtra = this.pagerOptions.embedExtra || {}; - this.pagerOptions.embedExtra.author = { - name: `${message.author.username}#${message.author.discriminator}`, - icon_url: message.author.avatarURL || message.author.defaultAvatarURL - }; - - this.pager = new GenericPager(client, message, this.pagerOptions); - this.halt = null; - } - - /** - * Starts the prompt - * @param {string} channelID The channel to post the new message to - * @param {string} userID The user's ID that started the process - * @param {number} timeout - */ - async start(channelID, userID, timeout) { - if (this.pager.items.length === 0) - return null; - - await this.pager.start(channelID, userID, timeout); - // React with done - if (this.pager.collector) - await this.pager.message.addReaction(MultiSelect.DONE); - this.halt = this.client.messageAwaiter.createHalt(channelID, userID, timeout); - - // Sync timeouts - if (this.pager.collector) - this.pager.collector.restart(); - this.halt.restart(); - - return new Promise(resolve => { - let result = null; - - this.halt.on('message', nextMessage => { - if (this.pager.canManage()) - nextMessage.delete(); - - if (MultiSelect.CANCEL_TRIGGERS.includes(nextMessage.content.toLowerCase())) { - result = { _canceled: true }; - this.halt.end(); - } else if (MultiSelect.DONE_TRIGGERS.includes(nextMessage.content.toLowerCase())) { - result = this.pager.items; - this.halt.end(); - } - - // Find and update item - const chosenIndex = parseInt(nextMessage.content); - if (chosenIndex <= 0) return; - let chosenItem = this.pager.items[chosenIndex - 1]; - if (chosenItem !== undefined) { - const oldItem = chosenItem; - chosenItem = lodash.set(chosenItem, this.boolPath, !lodash.get(chosenItem, this.boolPath)); - this.emit('update', oldItem, chosenItem, chosenIndex - 1); - this.pager.items.splice(chosenIndex - 1, 1, chosenItem); - this.pager.updateMessage(); - } - - this.halt.restart(); - if (this.pager.collector) - this.pager.collector.restart(); - }); - - this.halt.on('end', () => { - // In case the halt ends before reactions are finished coming up - this.pager.reactionsCleared = true; - if (this.pager.collector) - this.pager.collector.end(); - this.pager.message.delete().catch(() => {}); - - if (result && result._canceled) { - this.pager.message.channel.createMessage( - `<@${userID}>, Your last prompt was canceled. All changes have been lost.`); - result = null; - } else if (result === null) - this.pager.message.channel.createMessage( - `<@${userID}>, Your last prompt was timed out. All changes have been lost.`); - - resolve(result); - }); - - if (this.pager.collector) { - this.pager.collector.on('clearReactions', () => { - if (!this.pager.canManage()) - this.pager.message.removeReaction(MultiSelect.DONE).catch(() => {}); - }); - this.pager.collector.on('reaction', emoji => { - if (Paginator.STOP === emoji.name) { - result = { _canceled: true }; - this.halt.end(); - } else if (MultiSelect.DONE === emoji.name) { - result = this.pager.items; - this.halt.end(); - } - - this.halt.restart(); - }); - } - }); - } -} - -MultiSelect.DONE = '✅'; -MultiSelect.CANCEL_TRIGGERS = [ - 'cancel', 'stop', 'quit' -]; -MultiSelect.DONE_TRIGGERS = [ - 'save', 'finish', 'done' -]; - -module.exports = MultiSelect; \ No newline at end of file diff --git a/src/structures/Paginator.js b/src/structures/Paginator.js deleted file mode 100644 index af7a0d3..0000000 --- a/src/structures/Paginator.js +++ /dev/null @@ -1,184 +0,0 @@ -const EventEmitter = require('eventemitter3'); - -/** - * A class that creates a paging process for messages - */ -class Paginator extends EventEmitter { - /** - * @param {TrelloBot} client The client to use - * @param {Message} message The user's message to read permissions from - * @param {Object} options The options for the paginator - * @param {Array} options.items The items the paginator will display - * @param {number} [options.itemsPerPage=15] How many items a page will have - */ - constructor(client, message, { items = [], itemsPerPage = 15 } = {}) { - super(); - this.messageAwaiter = client.messageAwaiter; - this.client = client; - this.collector = null; - this.items = items; - this.message = message; - this.itemsPerPage = itemsPerPage; - this.pageNumber = 1; - this.reactionsCleared = false; - this._reactBind = this._react.bind(this); - } - - /** - * All pages in the paginator - * @type {Array} - */ - get pages() { - const pages = []; - let i, j, page; - for (i = 0, j = this.items.length; i < j; i += this.itemsPerPage) { - page = this.items.slice(i, i + this.itemsPerPage); - pages.push(page); - } - return pages; - } - - /** - * The current page - * @type {Array} - */ - get page() { - return this.pages[this.pageNumber - 1]; - } - - /** - * The current page number - * @type {number} - */ - get maxPages() { - return Math.ceil(this.items.length / this.itemsPerPage); - } - - /** - * Changes the page number - * @param {number} newPage The page to change to - */ - toPage(newPage) { - if (Number(newPage)){ - this.pageNumber = Number(newPage); - if (this.pageNumber < 1) this.pageNumber = 1; - if (this.pageNumber > this.maxPages) this.pageNumber = this.maxPages; - } - return this; - } - - /** - * Moves to the next page - */ - nextPage() { - return this.toPage(this.pageNumber + 1); - } - - /** - * Moves to the previous page - */ - previousPage() { - return this.toPage(this.pageNumber - 1); - } - - /** - * Whether or not this instance can paginate - * @returns {boolean} - */ - canPaginate() { - return this.message.channel.type === 1 || - this.message.channel.permissionsOf(this.client.user.id).has('addReactions'); - } - - /** - * Whether or not this instance can manage messages - * @returns {boolean} - */ - canManage() { - return this.message.channel.type !== 1 && - this.message.channel.permissionsOf(this.client.user.id).has('manageMessages'); - } - - /** - * Starts the reaction collector and pagination - * @param {string} userID The user's ID that started the process - * @param {number} timeout - */ - async start(userID, timeout) { - this.reactionsCleared = false; - if (this.maxPages > 1 && this.canPaginate()) { - try { - await Promise.all([ - this.message.addReaction(Paginator.PREV), - this.message.addReaction(Paginator.STOP), - this.message.addReaction(Paginator.NEXT), - ]); - this.collector = this.messageAwaiter.createReactionCollector(this.message, userID, timeout); - this._hookEvents(); - } catch (e) { - return this.clearReactions(); - } - } - } - - /** - * Clears reaction from the message - */ - async clearReactions() { - if (!this.reactionsCleared) { - this.reactionsCleared = true; - this.emit('clearReactions'); - try { - if (!this.canManage()) - await Promise.all([ - this.message.removeReaction(Paginator.NEXT).catch(() => {}), - this.message.removeReaction(Paginator.STOP).catch(() => {}), - this.message.removeReaction(Paginator.PREV).catch(() => {}) - ]); - else - await this.message.removeReactions().catch(() => {}); - } catch (e) { - // Do nothing - } - } - } - - /** - * @private - */ - _hookEvents() { - this.collector.on('reaction', this._react.bind(this)); - this.collector.once('end', this.clearReactions.bind(this)); - } - - /** - * @private - */ - _change() { - this.emit('change', this.pageNumber); - } - - /** - * @private - */ - _react(emoji, userID) { - const oldPage = this.pageNumber; - if (Paginator.PREV == emoji.name) - this.previousPage(); - else if (Paginator.NEXT == emoji.name) - this.nextPage(); - else if (Paginator.STOP == emoji.name) - this.collector.end(); - if (this.pageNumber !== oldPage) - this._change(); - if ([Paginator.PREV, Paginator.STOP, Paginator.NEXT].includes(emoji.name) && this.canManage()) - this.message.removeReaction(emoji.name, userID).catch(() => {}); - this.collector.restart(); - } -} - -Paginator.PREV = '⬅️'; -Paginator.STOP = '🛑'; -Paginator.NEXT = '➡️'; - -module.exports = Paginator; \ No newline at end of file diff --git a/src/structures/ReactionCollector.js b/src/structures/ReactionCollector.js deleted file mode 100644 index f1db617..0000000 --- a/src/structures/ReactionCollector.js +++ /dev/null @@ -1,60 +0,0 @@ -const EventEmitter = require('eventemitter3'); - -/** - * A class that collects reactions from a message - */ -class ReactionCollector extends EventEmitter { - constructor(messageAwaiter, timeout) { - super(); - this.messageAwaiter = messageAwaiter; - this.timeout = timeout; - this.interval = null; - this.ended = false; - this._endBind = this._end.bind(this); - this._start(); - } - - /** - * Restarts the timeout. - * @param {number} [timeout] The new timeout to halt by - */ - restart(timeout) { - if (this.ended) return; - clearTimeout(this.interval); - this.interval = setTimeout(this._endBind, timeout || this.timeout); - } - - /** - * Ends the collection. - */ - end() { - if (this.ended) return; - clearTimeout(this.interval); - this._end(); - } - - /** - * @private - */ - _onReaction(emoji, userID) { - this.emit('reaction', emoji, userID); - this.restart(); - } - - /** - * @private - */ - _start() { - this.interval = setTimeout(this._endBind, this.timeout); - } - - /** - * @private - */ - _end() { - this.ended = true; - this.emit('end'); - } -} - -module.exports = ReactionCollector; \ No newline at end of file diff --git a/src/structures/SubMenu.js b/src/structures/SubMenu.js deleted file mode 100644 index 744719f..0000000 --- a/src/structures/SubMenu.js +++ /dev/null @@ -1,44 +0,0 @@ -const GenericPrompt = require('./GenericPrompt'); - -class SubMenu { - /** - * @param {TrelloBot} client The client to use - * @param {Message} message The user's message to read permissions from - * @param {Object} pagerOptions The options for the pager - */ - constructor(client, message, pagerOptions = {}) { - this.client = client; - this.message = message; - this.pagerOptions = pagerOptions; - this.prompt = new GenericPrompt(client, message, this.pagerOptions); - } - - /** - * Starts the menu - * @param {string} channelID The channel to post the new message to - * @param {string} userID The user's ID that started the process - * @param {Array} menu - * @param {number} timeout - */ - async start(channelID, userID, name, menu = [], timeout = 30000) { - /* - menu = [ - { - names: ['a', 'b'], - title: 'Title', - exec: (client) => ... - } - ] - */ - const command = menu.find(command => command.names.includes(name ? name.toLowerCase() : null)); - if (!command) { - this.prompt.pager.items = menu; - this.prompt.pager.displayFunc = (item, _, ai) => `\`[${ai + 1}]\` ${item.title}`; - const chosenCommand = await this.prompt.choose(channelID, userID, timeout); - if (!chosenCommand) return; - return chosenCommand.exec(this.client); - } else return command.exec(this.client); - } -} - -module.exports = SubMenu; \ No newline at end of file diff --git a/src/util.js b/src/util.js deleted file mode 100644 index baf12b0..0000000 --- a/src/util.js +++ /dev/null @@ -1,363 +0,0 @@ -const fetch = require('node-fetch'); -const config = require('config'); -const fs = require('fs'); -const path = require('path'); - -/** - * Represents the utilities for the bot - * @typedef {Object} Util - */ -const Util = module.exports = {}; - -/** - * Iterates through each key of an object - * @memberof Util. - */ -Util.keyValueForEach = (obj, func) => Object.keys(obj).map(key => func(key, obj[key])); - -/** - * Randomness generator - * @memberof Util. - */ -Util.Random = { - int(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min; - }, - bool() { - return Util.Random.int(0, 1) === 1; - }, - array(array) { - return array[Util.Random.int(0, array.length - 1)]; - }, - shuffle(array) { - return array.sort(() => Math.random() - 0.5); - }, -}; - -/** - * Prefix-related functions - * @memberof Util. - */ -Util.Prefix = { - regex(client, prefixes = null) { - if (!prefixes) - prefixes = [config.prefix]; - return new RegExp(`^((?:<@!?${client.user.id}>|${ - prefixes.map(prefix => Util.Prefix.escapeRegex(prefix)).join('|')})\\s?)(\\n|.)`, 'i'); - }, - strip(message, client, prefixes) { - return message.content.replace( - Util.Prefix.regex(client, prefixes), '$2').replace(/\s\s+/g, ' ').trim(); - }, - escapeRegex(s) { - return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&'); - } -}; - -/** - * Command permission parsers - * @memberof Util. - */ -Util.CommandPermissions = { - attach: (client, message) => message.channel.type === 1 || - message.channel.permissionsOf(client.user.id).has('attachFiles'), - embed: (client, message) => message.channel.type === 1 || - message.channel.permissionsOf(client.user.id).has('embedLinks'), - emoji: (client, message) => message.channel.type === 1 || - message.channel.permissionsOf(client.user.id).has('externalEmojis'), - guild: (_, message) => !!message.guildID, - elevated: (_, message) => config.elevated.includes(message.author.id), - curator: (client, message) => { - const member = message.guildID ? message.member : - client.guilds.get(config.guildID).members.get(message.author.id); - const roles = Array.isArray(config.curatorRoleID) ? config.curatorRoleID : [config.curatorRoleID]; - if (!member) return false; - if (Util.CommandPermissions.elevated(client, message)) return true; - return roles.map(r => member.roles.includes(r)).includes(true); - }, - admin: (client, message) => { - const member = message.guildID ? message.member : - client.guilds.get(config.guildID).members.get(message.author.id); - const roles = Array.isArray(config.adminRoleID) ? config.adminRoleID : [config.adminRoleID]; - if (!member) return false; - if (Util.CommandPermissions.elevated(client, message)) return true; - return roles.map(r => member.roles.includes(r)).includes(true); - }, - curatorOrAdmin: (client, message) => { - const member = message.guildID ? message.member : - client.guilds.get(config.guildID).members.get(message.author.id); - const roles = [ - ...(Array.isArray(config.adminRoleID) ? config.adminRoleID : [config.adminRoleID]), - ...(Array.isArray(config.curatorRoleID) ? config.curatorRoleID : [config.curatorRoleID]), - ]; - if (!member) return false; - if (Util.CommandPermissions.elevated(client, message)) return true; - return roles.map(r => member.roles.includes(r)).includes(true); - }, - trustedOrAdmin: (client, message) => { - const member = message.guildID ? message.member : - client.guilds.get(config.guildID).members.get(message.author.id); - const roles = [ - ...(Array.isArray(config.adminRoleID) ? config.adminRoleID : [config.adminRoleID]), - ...(Array.isArray(config.trustedRoleID) ? config.trustedRoleID : [config.trustedRoleID]), - ]; - if (!member) return false; - if (Util.CommandPermissions.elevated(client, message)) return true; - return roles.map(r => member.roles.includes(r)).includes(true); - }, -}; - -/** - * Creates a module that makes emoji fallbacks - * @memberof Util. - */ -Util.emojiFallback = ({ message, client }) => { - return (id, fallback, animated = false) => { - if (Util.CommandPermissions.emoji(client, message)) - return `<${animated ? 'a' : ''}:_:${id}>`; - else return fallback; - }; -}; - -/** - * Cuts off text to a limit - * @memberof Util. - * @param {string} text - * @param {number} limit - */ -Util.cutoffText = (text, limit = 2000) => { - return text.length > limit ? text.slice(0, limit - 1) + '…' : text; -}; - -/** - * Cuts off an array of text to a limit - * @memberof Util. - * @param {Array} texts - * @param {number} limit - * @param {number} rollbackAmount Amount of items to roll back when the limit has been hit - */ -Util.cutoffArray = (texts, limit = 2000, rollbackAmount = 1, paddingAmount = 1) => { - let currLength = 0; - for (let i = 0; i < texts.length; i++) { - const text = texts[i]; - currLength += text.length + paddingAmount; - if (currLength > limit) { - const clampedRollback = rollbackAmount > i ? i : rollbackAmount; - return texts.slice(0, (i + 1) - clampedRollback); - } - } - return texts; -}; - -/** - * Resolve argument to a user ID - * @memberof Util. - * @param {string} arg - * @returns {?string} - */ -Util.resolveToUserID = (arg) => { - if (/^\d{17,18}$/.test(arg)) - return arg; - else if (/^<@!?\d{17,18}>$/.test(arg)) - return arg.replace(/^<@!?(\d{17,18})>$/, '$1'); - else return null; -}; - -/** - * Resolve argument to a claim ID - * @memberof Util. - * @param {string} arg - * @returns {?string} - */ -Util.resolveToClaimID = (arg) => { - if (/^[a-f0-9]{40}$/.test(arg)) - return arg; - else if (/^lbry:\/\/@?[\w-]+#([a-f0-9]{40})$/.test(arg)) - return arg.replace(/^lbry:\/\/@?[\w-]+#([a-f0-9]{40})$/, '$1'); - else return null; -}; - -/** - * Make a promise that resolves after some time - * @memberof Util. - * @param {string} arg - * @returns {?string} - */ -Util.halt = (ms) => { - return new Promise(resolve => setTimeout(resolve, ms)); -}; - -/** - * Hastebin-related functions - * @memberof Util. - */ -Util.Hastebin = { - async autosend(content, message) { - if (content.length > 2000) { - const haste = await Util.Hastebin.post(content); - if (haste.ok) - return message.channel.createMessage(``); - else - return message.channel.createMessage({}, { - name: 'output.txt', - file: new Buffer(content) - }); - } else return message.channel.createMessage(content); - }, - /** - * Post text to hastebin - * @param {string} content - The content to upload - */ - async post(content) { - const haste = await fetch('https://hastebin.com/documents', { - method: 'POST', - body: content - }); - if (haste.status >= 400) - return { - ok: false, - status: haste.status - }; - else { - const hasteInfo = await haste.json(); - return { - ok: true, - key: hasteInfo.key - }; - } - } -}; - -/** - * LBRY-related utility - * @memberof Util. - */ -Util.LBRY = { - async syncPairs(client) { - const response = await client.lbry.listAccounts({ page_size: await Util.LBRY.getAccountCount(client) }); - const accounts = await response.json(); - - let syncedAccounts = 0; - for (const account of accounts.result.items) { - if (/\d{17,19}/.test(account.name)) { - if (await client.sqlite.get(account.name)) continue; - await client.sqlite.pair(account.name, account.id); - syncedAccounts++; - } - } - - return syncedAccounts; - }, - async findSDKAccount(client, fn) { - const response = await client.lbry.listAccounts({ page_size: await Util.LBRY.getAccountCount(client) }); - const accounts = await response.json(); - return accounts.result.items.find(fn); - }, - async findOrCreateAccount(client, discordID, create = true) { - // Check SQLite - const pair = await client.sqlite.get(discordID); - if (pair) - return { accountID: pair.lbryID }; - - // Check accounts via SDK - const foundAccount = await Util.LBRY.findSDKAccount(client, account => account.name === discordID); - if (foundAccount) { - await client.sqlite.pair(discordID, foundAccount.id); - return { accountID: foundAccount.id }; - } - - // Create account if not found - if (create) { - const newAccount = await Util.LBRY.createAccount(client, discordID); - return { - accountID: newAccount.account.result.id, - txID: newAccount.transaction.result.txid, - newAccount: true - }; - } else return { accountID: null }; - }, - async getAccountCount(client) { - const response = await client.lbry.listAccounts({ page_size: 1 }).then(r => r.json()); - return response.result.total_items; - }, - async getSupportsCount(client, accountID) { - const response = await client.lbry.listSupports({ accountID, page_size: 1 }).then(r => r.json()); - return response.result.total_items; - }, - async createAccount(client, discordID) { - console.info('Creating account for user', discordID); - const account = await client.lbry.createAccount(discordID).then(r => r.json()); - await client.sqlite.pair(discordID, account.result.id); - console.info('Created pair', discordID, account.result.id); - const response = await client.lbry.fundAccount({ to: account.result.id, amount: config.startingBalance }); - const transaction = await response.json(); - console.info('Funded account', account.result.id, transaction.result.txid); - return { account, transaction }; - }, - ensureDecimal(str) { - const num = parseFloat(str); - if (isNaN(num)) return null; - return Number.isInteger(num) ? `${num}.0` : num.toString(); - }, - async deleteAccount(client, discordID, lbryID) { - // Backup the wallet before doing any delete function - try { - Util.LBRY.backupWallet(); - } catch (err) { - console.error('Error occurred while backing up wallet file!'); - console.error(err); - throw err; - } - - // Abandon supports - await Util.LBRY.abandonAllClaims(client, lbryID); - - // Take out funds from account - const balanceResponse = await client.lbry.accountBalance(lbryID); - let amount = (await balanceResponse.json()).result.total; - while (amount >= 2) { - await client.lbry.fundAccount({ from: lbryID, everything: true, amount }); - const finalBalance = await client.lbry.accountBalance(lbryID); - amount = (await finalBalance.json()).result.total; - await Util.halt(3000); - } - - // Remove account from SDK & SQLite - await client.lbry.removeAccount(lbryID); - await client.sqlite.remove(discordID); - }, - async abandonAllClaims(client, lbryID) { - if (!lbryID) - throw new Error('lbryID must be defined!'); - const supportsCount = await Util.LBRY.getSupportsCount(client, lbryID); - const supportsResponse = await client.lbry.listSupports({ - accountID: lbryID, page_size: supportsCount }); - console.info(`Abandoning claims for ${lbryID} (${supportsCount})`); - const supports = (await supportsResponse.json()).result.items; - for (let i = 0, len = supports.length; i < len; i++) { - const support = supports[i]; - await client.lbry.abandonSupport({ claimID: support.claim_id, accountID: lbryID }); - await Util.halt(3000); - } - return { count: supports.length }; - }, - backupWallet() { - const wallet = fs.readFileSync(config.walletPath); - const d = new Date(); - const date = [ - d.getUTCFullYear(), - d.getUTCMonth().toString().padStart(2, '0'), - d.getUTCDay().toString().padStart(2, '0'), - ].join('-'); - const time = [ - d.getUTCHours().toString().padStart(2, '0'), - d.getUTCMinutes().toString().padStart(2, '0'), - d.getUTCSeconds().toString().padStart(2, '0'), - d.getUTCMilliseconds().toString() - ].join('-'); - const backupName = 'default_wallet.' + date + '_' + time + '.bak'; - const backupPath = path.join(config.walletBackupFolder, backupName); - fs.writeFileSync(backupPath, wallet); - console.log(`Backed up wallet file: ${backupPath}`); - } -}; diff --git a/src/util/abstracts.ts b/src/util/abstracts.ts new file mode 100644 index 0000000..552b72a --- /dev/null +++ b/src/util/abstracts.ts @@ -0,0 +1,70 @@ +import { oneLine } from 'common-tags'; +import { ClientEvent, CommandContext, DexareCommand, PermissionNames } from 'dexare'; +import LBRYModule from '../modules/lbry'; +import WalletModule from '../modules/wallet'; + +export abstract class GeneralCommand extends DexareCommand { + get lbry() { + return this.client.modules.get('lbry')! as LBRYModule; + } + + get lbryx() { + return this.client.modules.get('lbryx')! as LBRYModule; + } + + get wallet() { + return this.client.modules.get('wallet')! as WalletModule; + } + + get embedColor(): number { + return this.client.config.embedColor; + } + + hasPermission(ctx: CommandContext, event?: ClientEvent): boolean | string { + if (this.userPermissions) { + let permissionMap = event && event.has('dexare/permissionMap') ? event.get('dexare/permissionMap') : {}; + permissionMap = this.client.permissions.map( + this.client.permissions.toObject(ctx.message), + this.userPermissions, + permissionMap, + event + ); + if (event) event.set('dexare/permissionMap', permissionMap); + const missing = this.userPermissions.filter((perm: string) => !permissionMap[perm]); + + if (missing.length > 0) { + if (missing.includes('dexare.elevated')) + return `The \`${this.name}\` command can only be used by the bot developers or elevated users.`; + else if (missing.includes('lbry.curator') || missing.includes('lbry.curatorOrAdmin')) + return `The \`${this.name}\` command can only be ran by LBRY curators.`; + else if (missing.includes('lbry.trusted') || missing.includes('lbry.trustedOrAdmin')) + return `The \`${this.name}\` command can only be ran by LBRY trusteds.`; + else if (missing.includes('lbry.admin')) + return `The \`${this.name}\` command can only be ran by LBRY admins.`; + else if (missing.includes('dexare.nsfwchannel')) + return `The \`${this.name}\` command can only be ran in NSFW channels.`; + else if (missing.includes('dexare.inguild')) + return `The \`${this.name}\` command can only be ran in guilds.`; + else if (missing.length === 1) { + return `The \`${this.name}\` command requires you to have the "${ + PermissionNames[missing[0]] || missing[0] + }" permission.`; + } + return oneLine` + The \`${this.name}\` command requires you to have the following permissions: + ${missing.map((perm) => PermissionNames[perm] || perm).join(', ')} + `; + } + } + + return true; + } + + finalize(response: any, ctx: CommandContext) { + if ( + typeof response === 'string' || + (response && response.constructor && response.constructor.name === 'Object') + ) + return ctx.reply(response); + } +} diff --git a/src/util/index.ts b/src/util/index.ts new file mode 100644 index 0000000..9317cf0 --- /dev/null +++ b/src/util/index.ts @@ -0,0 +1,72 @@ +/** + * Make a promise that resolves after some time + * @param ms The time to resolve at + */ +export function wait(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +/** + * Resolves a Discord users ID. + * @param arg The value to resolve + */ +export function resolveUser(arg: string) { + if (/^\d{17,18}$/.test(arg)) return arg; + else if (/^<@!?\d{17,18}>$/.test(arg)) return arg.replace(/^<@!?(\d{17,18})>$/, '$1'); + else return null; +} + +/** + * Makes sure a value is a decimal usable for the LBRY SDK. + * @param arg The value to ensure + */ +export function ensureDecimal(arg: string | number) { + const num = parseFloat(arg as any); + if (isNaN(num)) return null; + return Number.isInteger(num) ? `${num}.0` : num.toString(); +} + +export interface SplitOptions { + maxLength?: number; + char?: string; + prepend?: string; + append?: string; +} + +/** + * Splits a string into multiple chunks at a designated character that do not exceed a specific length. + * @param text Content to split + * @param options Options controlling the behavior of the split + */ +export function splitMessage( + text: string, + { maxLength = 2000, char = '\n', prepend = '', append = '' }: SplitOptions = {} +) { + if (text.length <= maxLength) return [text]; + let splitText = [text]; + if (Array.isArray(char)) { + while (char.length > 0 && splitText.some((elem) => elem.length > maxLength)) { + const currentChar = char.shift(); + if (currentChar instanceof RegExp) { + // @ts-ignore + splitText = splitText.map((chunk) => chunk.match(currentChar)); + } else { + // @ts-ignore + splitText = splitText.map((chunk) => chunk.split(currentChar)); + } + } + } else { + splitText = text.split(char); + } + if (splitText.some((elem) => elem.length > maxLength)) throw new RangeError('SPLIT_MAX_LEN'); + const messages = []; + let msg = ''; + for (const chunk of splitText) { + if (msg && (msg + char + chunk + append).length > maxLength) { + messages.push(msg + append); + msg = prepend; + } + msg += (msg && msg !== prepend ? char : '') + chunk; + } + return messages.concat(msg).filter((m) => m); +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..5b19e78 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,21 @@ + +{ + "compilerOptions": { + "target": "es6", + "module": "commonjs", + "outDir": "dist", + "strict": true, + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true + }, + "include": [ + "./src/**/*" + ], + "exclude": [ + "node_modules", + "dist", + "testing", + "src-old" + ] +} diff --git a/yarn.lock b/yarn.lock index be0ca7e..1cea006 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,6 +23,38 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@dabh/diagnostics@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.2.tgz#290d08f7b381b8f94607dc8f471a12c675f9db31" + integrity sha512-+A1YivoVDNNVCdfozHSR8v/jyuuLTMXwjWuxPFlFlUapXoGc+Gj9mDlTDDfrwl7rXCl2tNZ0kE8sIBO6YOn96Q== + dependencies: + colorspace "1.1.x" + enabled "2.0.x" + kuler "^2.0.0" + +"@dexare/cron@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@dexare/cron/-/cron-1.0.0.tgz#5634a5dc81b83866c4f84f448379026cc82e9e49" + integrity sha512-Ct2Ld/CzK0OQd8GvX+4Jm97eEAaVN/XSD9Zg1pfon+vIdsjT/FLo3jRJ1bFlDQz0/oRKLjgSs53/d6I3beepWw== + dependencies: + cron "^1.8.2" + dexare "^2.0.1" + +"@dexare/logger@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@dexare/logger/-/logger-1.0.0.tgz#21ec0510fd529da541f96cfcbe824c07c922f8f9" + integrity sha512-ZsmRYq2JB5OTwgtDWum6tG6d2Wjg+4Gy2xiXW4p1AkzIX2zmkACW2Jy1Q+UqMAmYS5JJuvrDGSmoUgOFP/lmvg== + dependencies: + chalk "^4.1.0" + dayjs "^1.10.4" + dexare "^1.3.1" + winston "^3.3.3" + +"@discordjs/collection@^0.1.6": + version "0.1.6" + resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-0.1.6.tgz#9e9a7637f4e4e0688fd8b2b5c63133c91607682c" + integrity sha512-utRNxnd9kSS2qhyivo9lMlt5qgAUasH2gb7BEOn6p0efFh24gjGomHzWKMAPn2hEReOPQZCJaRKoURwRotKucQ== + "@eslint/eslintrc@^0.4.2": version "0.4.2" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.2.tgz#f63d0ef06f5c0c57d76c4ab5f63d3835c51b0179" @@ -38,27 +70,175 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.7.tgz#94c23db18ee4653e129abd26fb06f870ac9e1ee2" + integrity sha512-BTIhocbPBSrRmHxOAJFtR18oLhxTtAFDAvL8hY1S3iU8k+E60W/YFs4jrixGzQjMpF4qPXxIQHcjVD9dz1C2QA== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + +"@tsconfig/node10@^1.0.7": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" + integrity sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg== + +"@tsconfig/node12@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.9.tgz#62c1f6dee2ebd9aead80dc3afa56810e58e1a04c" + integrity sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw== + +"@tsconfig/node14@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.1.tgz#95f2d167ffb9b8d2068b0b235302fafd4df711f2" + integrity sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg== + +"@tsconfig/node16@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.1.tgz#a6ca6a9a0ff366af433f42f5f0e124794ff6b8f1" + integrity sha512-FTgBI767POY/lKNDNbIzgAX6miIDBs6NTCbdlDb8TrWovHsSvaVIZDlTqym29C6UqhzwcJx4CYr+AlrMywA0cA== + "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== -"@types/node@*": - version "14.0.27" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.27.tgz#a151873af5a5e851b51b3b065c9e63390a9e0eb1" - integrity sha512-kVrqXhbclHNHGu9ztnAwSncIgJv/FaxmzXJvGXNdcCpV1b8u1/Mi6z6m0vwy0LzKeXFTPLH0NzwmoJ3fNCIq0g== +"@types/common-tags@^1.8.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@types/common-tags/-/common-tags-1.8.0.tgz#79d55e748d730b997be5b7fce4b74488d8b26a6b" + integrity sha512-htRqZr5qn8EzMelhX/Xmx142z218lLyGaeZ3YR8jlze4TATRU9huKKvuBmAJEW4LCC4pnY1N6JAm6p85fMHjhg== -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +"@types/config@^0.0.38": + version "0.0.38" + resolved "https://registry.yarnpkg.com/@types/config/-/config-0.0.38.tgz#ca30679b21b5b297299467e3a3f1c8e2e64b9170" + integrity sha512-z2WizAfIFgSv8SQfQ8c0LlbDAcK47D/o93XW6bxZ9t3bs4fmmfAPjk1nhAIBTG84PBBCHfSPM+8g7vhLdbFokg== -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== +"@types/cron@^1.7.2": + version "1.7.2" + resolved "https://registry.yarnpkg.com/@types/cron/-/cron-1.7.2.tgz#e9fb420da616920dae82d13adfca53282ffaab6e" + integrity sha512-AEpNLRcsVSc5AdseJKNHpz0d4e8+ow+abTaC0fKDbAU86rF1evoFF0oC2fV9FdqtfVXkG2LKshpLTJCFOpyvTg== dependencies: - event-target-shim "^5.0.0" + "@types/node" "*" + moment ">=2.14.0" + +"@types/json-schema@^7.0.7": + version "7.0.7" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad" + integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA== + +"@types/needle@^2.5.1": + version "2.5.1" + resolved "https://registry.yarnpkg.com/@types/needle/-/needle-2.5.1.tgz#2923f4a63a66048aed3038d76e8bc83b6905c784" + integrity sha512-OeI+1hQI6wzIKRwmK0XNJ1k0hpS9+p6Q4SvmnNNr6BpGCCjPIeR1FdlUV/ruw6GYCP3qmJ+iusXwIGtL4nq3Iw== + dependencies: + "@types/node" "*" + +"@types/node@*", "@types/node@^15.12.4": + version "15.12.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-15.12.4.tgz#e1cf817d70a1e118e81922c4ff6683ce9d422e26" + integrity sha512-zrNj1+yqYF4WskCMOHwN+w9iuD12+dGm0rQ35HLl9/Ouuq52cEtd0CH9qMgrdNmi5ejC1/V7vKEXYubB+65DkA== + +"@typescript-eslint/eslint-plugin@^4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.0.tgz#1a66f03b264844387beb7dc85e1f1d403bd1803f" + integrity sha512-KcF6p3zWhf1f8xO84tuBailV5cN92vhS+VT7UJsPzGBm9VnQqfI9AsiMUFUCYHTYPg1uCCo+HyiDnpDuvkAMfQ== + dependencies: + "@typescript-eslint/experimental-utils" "4.28.0" + "@typescript-eslint/scope-manager" "4.28.0" + debug "^4.3.1" + functional-red-black-tree "^1.0.1" + regexpp "^3.1.0" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/experimental-utils@4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.0.tgz#13167ed991320684bdc23588135ae62115b30ee0" + integrity sha512-9XD9s7mt3QWMk82GoyUpc/Ji03vz4T5AYlHF9DcoFNfJ/y3UAclRsfGiE2gLfXtyC+JRA3trR7cR296TEb1oiQ== + dependencies: + "@types/json-schema" "^7.0.7" + "@typescript-eslint/scope-manager" "4.28.0" + "@typescript-eslint/types" "4.28.0" + "@typescript-eslint/typescript-estree" "4.28.0" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/parser@^4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.0.tgz#2404c16751a28616ef3abab77c8e51d680a12caa" + integrity sha512-7x4D22oPY8fDaOCvkuXtYYTQ6mTMmkivwEzS+7iml9F9VkHGbbZ3x4fHRwxAb5KeuSkLqfnYjs46tGx2Nour4A== + dependencies: + "@typescript-eslint/scope-manager" "4.28.0" + "@typescript-eslint/types" "4.28.0" + "@typescript-eslint/typescript-estree" "4.28.0" + debug "^4.3.1" + +"@typescript-eslint/scope-manager@4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.0.tgz#6a3009d2ab64a30fc8a1e257a1a320067f36a0ce" + integrity sha512-eCALCeScs5P/EYjwo6se9bdjtrh8ByWjtHzOkC4Tia6QQWtQr3PHovxh3TdYTuFcurkYI4rmFsRFpucADIkseg== + dependencies: + "@typescript-eslint/types" "4.28.0" + "@typescript-eslint/visitor-keys" "4.28.0" + +"@typescript-eslint/types@4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.0.tgz#a33504e1ce7ac51fc39035f5fe6f15079d4dafb0" + integrity sha512-p16xMNKKoiJCVZY5PW/AfILw2xe1LfruTcfAKBj3a+wgNYP5I9ZEKNDOItoRt53p4EiPV6iRSICy8EPanG9ZVA== + +"@typescript-eslint/typescript-estree@4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.0.tgz#e66d4e5aa2ede66fec8af434898fe61af10c71cf" + integrity sha512-m19UQTRtxMzKAm8QxfKpvh6OwQSXaW1CdZPoCaQuLwAq7VZMNuhJmZR4g5281s2ECt658sldnJfdpSZZaxUGMQ== + dependencies: + "@typescript-eslint/types" "4.28.0" + "@typescript-eslint/visitor-keys" "4.28.0" + debug "^4.3.1" + globby "^11.0.3" + is-glob "^4.0.1" + semver "^7.3.5" + tsutils "^3.21.0" + +"@typescript-eslint/visitor-keys@4.28.0": + version "4.28.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.0.tgz#255c67c966ec294104169a6939d96f91c8a89434" + integrity sha512-PjJyTWwrlrvM5jazxYF5ZPs/nl0kHDZMVbuIcbpawVXaDPelp3+S9zpOz5RmVUfS/fD5l5+ZXNKnWhNYjPzCvw== + dependencies: + "@typescript-eslint/types" "4.28.0" + eslint-visitor-keys "^2.0.0" + +"@yarnpkg/parsers@^2.4.0-rc.3": + version "2.4.0-rc.4" + resolved "https://registry.yarnpkg.com/@yarnpkg/parsers/-/parsers-2.4.0-rc.4.tgz#c155e646b259922510ed3d83801caef12fb5e8ed" + integrity sha512-zENsLbLf992oL0vR56Zh0NWdMvDNmdNfXaabfio2BX/FQfQbwMbVMYt5s763wIdyapu9RWte+jJNA9v+J0qBjg== + dependencies: + js-yaml "^3.10.0" + tslib "^1.13.0" acorn-jsx@^5.3.1: version "5.3.1" @@ -70,7 +250,7 @@ acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c" integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w== -ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: +ajv@^6.10.0, ajv@^6.12.4: version "6.12.4" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.4.tgz#0614facc4522127fa713445c6bfd3ebd376e2234" integrity sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ== @@ -95,6 +275,13 @@ ansi-colors@^3.2.1: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + ansi-regex@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" @@ -132,10 +319,13 @@ ansi-styles@^4.1.0: "@types/color-name" "^1.1.1" color-convert "^2.0.1" -any-promise@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" aproba@^1.0.3: version "1.2.0" @@ -150,6 +340,11 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -157,56 +352,77 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" +array-back@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" + integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== astral-regex@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= +async@^3.1.0, async@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" + integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2" - integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA== +autopm@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/autopm/-/autopm-1.3.1.tgz#b334bd11d1dbca4a1951b1752389aa80d103fd0d" + integrity sha512-gaFNW4oTaeQarZUIP7VnBAHmSrACUrc5ra8P6jids6Sj+3cWUqTc08RgfVT1YEFPD0MBWM8Mie5DMRUB7h25IQ== + dependencies: + builtin-modules "^3.2.0" + compare-versions "^3.6.0" + fast-glob "^3.2.5" + package-json "^6.5.0" + require-package-name "^2.0.1" + source-map-support "^0.5.19" balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -block-stream@*: - version "0.0.9" - resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" - integrity sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo= +better-sqlite3@^7.1.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-7.4.1.tgz#9daab6fb5be44460772992478ccda2db53605b7d" + integrity sha512-sk1kW3PsWE7W7G9qbi5TQxCROlQVR8YWlp4srbyrwN5DrLeamKfrm3JExwOiNSAYyJv8cw5/2HOfvF/ipZj4qg== dependencies: - inherits "~2.0.0" + bindings "^1.5.0" + prebuild-install "^6.0.1" + tar "^6.1.0" + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + +bl@^4.0.3, bl@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" brace-expansion@^1.1.7: version "1.1.11" @@ -216,25 +432,50 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +braces@^3.0.1, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +builtin-modules@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.2.0.tgz#45d5db99e7ee5e6bc4f362e008bf917ab5049887" + integrity sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA== + +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -cat-loggr@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/cat-loggr/-/cat-loggr-1.2.2.tgz#2496fc66e87665a65a1334e60a7a138bbb96c46e" - integrity sha512-4CiRwzPZ4E5/1XX+zgu4cxUZ0otElnSYUjx5KZO+ZhthGUSH5ly7UrMXqcYHC/yep+pv1HhXJAP8KkCPt7G2AA== - dependencies: - chalk "^2.4.1" - dayjs "^1.10.5" - -chalk@^2.0.0, chalk@^2.4.1: +chalk@^2.0.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -251,17 +492,79 @@ chalk@^4.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +chalk@^4.1.0, chalk@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" + integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +chokidar@^3.5.0: + version "3.5.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" + integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + chownr@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-spinners@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.0.tgz#36c7dc98fb6a9a76bd6238ec3f77e2425627e939" + integrity sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q== + +cli-width@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" + integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== + +clone-response@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= + dependencies: + mimic-response "^1.0.0" + +clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= -color-convert@^1.9.0: +color-convert@^1.9.0, color-convert@^1.9.1: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== @@ -280,17 +583,64 @@ color-name@1.1.3: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@~1.1.4: +color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== +color-string@^1.5.2: + version "1.5.5" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.5.tgz#65474a8f0e7439625f3d27a6a19d89fc45223014" + integrity sha512-jgIoum0OfQfq9Whcfc2z/VhCNcmQjWbey6qBX0vqt7YICflUmBCh9E9CiQD5GSJ+Uehixm3NUwHVhqUAWRivZg== dependencies: - delayed-stream "~1.0.0" + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@3.0.x: + version "3.0.0" + resolved "https://registry.yarnpkg.com/color/-/color-3.0.0.tgz#d920b4328d534a3ac8295d68f7bd4ba6c427be9a" + integrity sha512-jCpd5+s0s0t7p3pHQKpnJ0TpQKKdleP71LWcA0aqiljpiuAkOSUFN/dyH8ZwF0hRmFlrIuRhufds1QyEP9EB+w== + dependencies: + color-convert "^1.9.1" + color-string "^1.5.2" + +colors@^1.2.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +colorspace@1.1.x: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.2.tgz#e0128950d082b86a2168580796a0aa5d6c68d8c5" + integrity sha512-vt+OoIP2d76xLhjwbBaucYlNSpPsrJWPlBTtwCpQKIu6/CSMutyzX93O/Do0qzpH3YoHEes8YEFXyZ797rEhzQ== + dependencies: + color "3.0.x" + text-hex "1.0.x" + +command-line-args@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.1.1.tgz#88e793e5bb3ceb30754a86863f0401ac92fd369a" + integrity sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg== + dependencies: + array-back "^3.0.1" + find-replace "^3.0.0" + lodash.camelcase "^4.3.0" + typical "^4.0.0" + +commander@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + +common-tags@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" + integrity sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw== + +compare-versions@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.6.0.tgz#1a5689913685e5a87637b8d3ffca75514ec41d62" + integrity sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA== concat-map@0.0.1: version "0.0.1" @@ -309,11 +659,23 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= -core-util-is@1.0.2, core-util-is@~1.0.0: +core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cron@^1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/cron/-/cron-1.8.2.tgz#4ac5e3c55ba8c163d84f3407bde94632da8370ce" + integrity sha512-Gk2c4y6xKEO8FSAUTklqtfSr7oTq0CiPQeLBG5Fl0qoXpZyMcj1SG59YL+hqq04bu6/IuEA7lMkYDAplQNKkyg== + dependencies: + moment-timezone "^0.5.x" + cross-spawn@^7.0.2: version "7.0.2" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.2.tgz#d0d7dcfa74e89115c7619f4f721a94e1fdb716d6" @@ -323,25 +685,11 @@ cross-spawn@^7.0.2: shebang-command "^2.0.0" which "^2.0.1" -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -dayjs@^1.10.5: +dayjs@^1.10.4: version "1.10.5" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.5.tgz#5600df4548fc2453b3f163ebb2abbe965ccfb986" integrity sha512-BUFis41ikLz+65iH6LHQCDm4YPMj5r1YFLdupPIyM4SGcXMmtiLQ7U37i+hGS8urIuqe7I/ou3IS1jVc4nbN4g== -debug@^3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - debug@^4.0.1, debug@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" @@ -349,6 +697,27 @@ debug@^4.0.1, debug@^4.1.1: dependencies: ms "^2.1.1" +debug@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + dependencies: + ms "2.1.2" + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= + dependencies: + mimic-response "^1.0.0" + +decompress-response@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986" + integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== + dependencies: + mimic-response "^2.0.0" + deep-extend@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" @@ -359,26 +728,67 @@ deep-is@^0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= +defaults@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d" + integrity sha1-xlYFHpgX2f8I7YgUd/P+QBnz730= + dependencies: + clone "^1.0.2" + +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= -denque@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/denque/-/denque-1.5.0.tgz#773de0686ff2d8ec2ff92914316a47b73b1c73de" - integrity sha512-CYiCSgIF1p6EUByQPlGkKnP1M9g0ZV3qMIrqMqZqdwazygIA/YP2vrbcyl1h/WppKJTdl1F85cXIle+394iDAQ== - -detect-libc@^1.0.2: +detect-libc@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= +dexare@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/dexare/-/dexare-1.3.1.tgz#71823b900dae3413b2a25dc00d143c59a8ca7077" + integrity sha512-uwk/+1l5EvbsT3dGufp3jrzWk1J5IFErQbazlXgfE3BDJXSEMxv+JSecPq+i/BazQc4ETVP3qQGF22fMIfUCBg== + dependencies: + "@discordjs/collection" "^0.1.6" + common-tags "^1.8.0" + eris "^0.15.0" + eventemitter3 "^4.0.7" + lodash "^4.17.20" + +dexare@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/dexare/-/dexare-2.0.1.tgz#18a2bf8370a1b2f4db6fe14803b247489b09d830" + integrity sha512-UyuWwJBi1MCmhh0Vvxdj5UIDV0QMMELE9KODLagSJ/Wmte8TLjYbrij3wSGdYgy6dv7CBWcO9Vb3vWnlf3oXqQ== + dependencies: + "@discordjs/collection" "^0.1.6" + common-tags "^1.8.0" + eris "^0.15.0" + eventemitter3 "^4.0.7" + lodash "^4.17.20" + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +displayastree@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/displayastree/-/displayastree-2.0.0.tgz#cf7aa8c50cbd1398d46ddd435b26c22c614487cf" + integrity sha512-v3mQ/DTdrOiVxk1Jmut/ywN5uCTYNThcW71+Kn+w8fw2xkFYRyC0kbrXNuduXVLfkXVTpa2HYdz6bImiGyhkEg== + doctrine@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" @@ -386,24 +796,28 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -dottie@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/dottie/-/dottie-2.0.2.tgz#cc91c0726ce3a054ebf11c55fbc92a7f266dd154" - integrity sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg== - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= emoji-regex@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +enabled@2.0.x: + version "2.0.0" + resolved "https://registry.yarnpkg.com/enabled/-/enabled-2.0.0.tgz#f9dd92ec2d6f4bbc0d5d1e64e21d61cd4665e7c2" + integrity sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ== + +end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + enquirer@^2.3.5: version "2.3.5" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.5.tgz#3ab2b838df0a9d8ab9e7dff235b0e8712ef92381" @@ -411,7 +825,12 @@ enquirer@^2.3.5: dependencies: ansi-colors "^3.2.1" -eris@^0.15.1: +eol@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/eol/-/eol-0.9.1.tgz#f701912f504074be35c6117a5c4ade49cd547acd" + integrity sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg== + +eris@^0.15.0: version "0.15.1" resolved "https://registry.yarnpkg.com/eris/-/eris-0.15.1.tgz#6b44e6d4675c271def7484725a0edede9e798960" integrity sha512-IQ3BPW6OjgFoqjdh+irPOa1jFlkotk+WNu2GQQ7QAQfbzQEPZgn+F+hpOxfMUXPHOZMX4sPKLkVDkMHAssBYhw== @@ -431,6 +850,18 @@ escape-string-regexp@^4.0.0: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +eslint-config-prettier@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a" + integrity sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew== + +eslint-plugin-prettier@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz#cdbad3bf1dbd2b177e9825737fe63b476a08f0c7" + integrity sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw== + dependencies: + prettier-linter-helpers "^1.0.0" + eslint-scope@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" @@ -446,6 +877,13 @@ eslint-utils@^2.1.0: dependencies: eslint-visitor-keys "^1.1.0" +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" @@ -456,10 +894,10 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== -eslint@^7.28.0: - version "7.28.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.28.0.tgz#435aa17a0b82c13bb2be9d51408b617e49c1e820" - integrity sha512-UMfH0VSjP0G4p3EWirscJEQ/cHqnT/iuH6oNZOB94nBjWbMnhGEPxsZm1eyIW0C/9jLI0Fow4W5DXLjEI7mn1g== +eslint@^7.29.0: + version "7.29.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.29.0.tgz#ee2a7648f2e729485e4d0bd6383ec1deabc8b3c0" + integrity sha512-82G/JToB9qIy/ArBzIWG9xvvwL3R86AlCjtGw+A29OMZDqhTybz/MByORSukGxeI+YPCR4coYyITKk8BFH9nDA== dependencies: "@babel/code-frame" "7.12.11" "@eslint/eslintrc" "^0.4.2" @@ -549,36 +987,47 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - eventemitter3@^4.0.7: version "4.0.7" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== +expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-glob@^3.1.1, fast-glob@^3.2.4, fast-glob@^3.2.5: + version "3.2.5" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" + integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.0" + merge2 "^1.3.0" + micromatch "^4.0.2" + picomatch "^2.2.1" + fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -589,6 +1038,30 @@ fast-levenshtein@^2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fast-safe-stringify@^2.0.4: + version "2.0.7" + resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" + integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== + +fastq@^1.6.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858" + integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g== + dependencies: + reusify "^1.0.4" + +fecha@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.1.tgz#0a83ad8f86ef62a091e22bb5a039cd03d23eecce" + integrity sha512-MMMQ0ludy/nBs1/o0zVOiKTpG7qMbonKUzjJgQFEuvq6INZ1OraKPRAWkBq5vlKLOUMpmNYG1JoN3oDPUQ9m3Q== + +figures@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -596,6 +1069,25 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" +file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-replace@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" + integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== + dependencies: + array-back "^3.0.1" + flat-cache@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" @@ -609,52 +1101,47 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.0.tgz#a5d06b4a8b01e3a63771daa5cb7a1903e2e57067" integrity sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA== -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= +fn.name@1.x.x: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" + integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" +fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-minipass@^1.2.5: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" - integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== +fs-extra@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1" + integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== dependencies: - minipass "^2.6.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-minipass@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= -fstream@^1.0.0, fstream@^1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" - integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== - dependencies: - graceful-fs "^4.1.2" - inherits "~2.0.0" - mkdirp ">=0.5 0" - rimraf "2" +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== functional-red-black-tree@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= -fuzzy@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/fuzzy/-/fuzzy-0.1.3.tgz#4c76ec2ff0ac1a36a9dccf9a00df8623078d4ed8" - integrity sha1-THbsL/CsGjap3M+aAN+GIweNTtg= - gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -669,21 +1156,38 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= - dependencies: - assert-plus "^1.0.0" +get-stdin@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53" + integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg== -glob-parent@^5.1.2: +get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= + +glob-parent@^5.1.0, glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" -glob@^7.0.3, glob@^7.1.3: +glob@^7.1.3: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -702,23 +1206,39 @@ globals@^13.6.0, globals@^13.9.0: dependencies: type-fest "^0.20.2" -graceful-fs@^4.1.2: - version "4.2.4" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" - integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== +globby@^11.0.3: + version "11.0.4" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" + integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.1.1" + ignore "^5.1.4" + merge2 "^1.3.0" + slash "^3.0.0" + +got@^9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + +graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.6" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" + integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== has-flag@^3.0.0: version "3.0.0" @@ -735,34 +1255,33 @@ has-unicode@^2.0.0: resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" +http-cache-semantics@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== -iconv-lite@^0.4.4: +iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" -ignore-walk@^3.0.1: - version "3.0.3" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" - integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== - dependencies: - minimatch "^3.0.4" +ieee754@^1.1.13: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== +ignore@^5.1.4: + version "5.1.8" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" + integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== + import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" @@ -776,11 +1295,6 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= -inflection@1.12.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.12.0.tgz#a200935656d6f5f6bc4dc7502e1aecb703228416" - integrity sha1-ogCTVlbW9fa8TcdQLhrstwMihBY= - inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -789,7 +1303,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@~2.0.0, inherits@~2.0.3: +inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -799,6 +1313,38 @@ ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== +inquirer@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.1.1.tgz#7c53d94c6d03011c7bb2a947f0dca3b98246c26a" + integrity sha512-hUDjc3vBkh/uk1gPfMAD/7Z188Q8cvTGl0nxwaCdwSbzFh6ZKkZh+s2ozVxbE5G9ZNRyeY0+lgbAIOUFsFf98w== + dependencies: + ansi-escapes "^4.2.1" + chalk "^4.1.1" + cli-cursor "^3.1.0" + cli-width "^3.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.21" + mute-stream "0.0.8" + ora "^5.3.0" + run-async "^2.4.0" + rxjs "^6.6.6" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -821,17 +1367,32 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-glob@^4.0.0, is-glob@^4.0.1: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== dependencies: is-extglob "^2.1.1" -is-typedarray@~1.0.0: +is-interactive@^1.0.0: version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" + integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== isarray@~1.0.0: version "1.0.0" @@ -843,16 +1404,19 @@ isexe@^2.0.0: resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +js-yaml@^3.10.0: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + js-yaml@^3.13.1: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" @@ -861,10 +1425,10 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= json-schema-traverse@^0.4.1: version "0.4.1" @@ -876,20 +1440,15 @@ json-schema-traverse@^1.0.0: resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - json-stable-stringify-without-jsonify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= +json2xml@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/json2xml/-/json2xml-0.1.3.tgz#9ae7c220bedd7c66a668e26f7ac182f6704eca21" + integrity sha1-mufCIL7dfGamaOJvesGC9nBOyiE= json5@^2.1.1: version "2.1.3" @@ -898,15 +1457,43 @@ json5@^2.1.1: dependencies: minimist "^1.2.5" -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + +kuler@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" + integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== + +leasot@^12.0.0: + version "12.0.0" + resolved "https://registry.yarnpkg.com/leasot/-/leasot-12.0.0.tgz#78c5df2c941c7285374c8d992866e22163241b22" + integrity sha512-TMe3cJTRUMpXsOFNXCig5U84wM44y84vawkl2fC7iAJif88l/b7BtTt49VrkMsivlxlqHYVu5PjuxB9sRQf39w== + dependencies: + async "^3.2.0" + chalk "^4.1.0" + commander "^7.2.0" + eol "^0.9.1" + get-stdin "^8.0.0" + globby "^11.0.3" + json2xml "^0.1.3" + lodash "^4.17.21" + log-symbols "^4.1.0" + strip-ansi "^6.0.0" + text-table "^0.2.0" levn@^0.4.1: version "0.4.1" @@ -916,6 +1503,11 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" @@ -931,22 +1523,79 @@ lodash.truncate@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM= -lodash@^4.17.20: +lodash@^4.17.20, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== -mime-db@1.44.0: - version "1.44.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" - integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== - -mime-types@^2.1.12, mime-types@~2.1.19: - version "2.1.27" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" - integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== +log-symbols@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== dependencies: - mime-db "1.44.0" + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +logform@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/logform/-/logform-2.2.0.tgz#40f036d19161fc76b68ab50fdc7fe495544492f2" + integrity sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg== + dependencies: + colors "^1.2.1" + fast-safe-stringify "^2.0.4" + fecha "^4.2.0" + ms "^2.1.1" + triple-beam "^1.3.0" + +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +merge2@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.2: + version "4.0.4" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" + integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== + dependencies: + braces "^3.0.1" + picomatch "^2.2.3" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-response@^1.0.0, mimic-response@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimic-response@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" + integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== minimatch@^3.0.4: version "3.0.4" @@ -955,145 +1604,86 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.5: +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== -minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== +minipass@^3.0.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" + integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" + yallist "^4.0.0" -minizlib@^1.2.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== +minizlib@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== dependencies: - minipass "^2.9.0" + minipass "^3.0.0" + yallist "^4.0.0" -"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" +mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== -moment-timezone@^0.5.31: - version "0.5.31" - resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.31.tgz#9c40d8c5026f0c7ab46eda3d63e49c155148de05" - integrity sha512-+GgHNg8xRhMXfEbv81iDtrVeTcWt0kWmTEY1XQK14dICTXnWJnT0dxdlPspwqF3keKMVPXwayEsk1DI0AA/jdA== +mkdirp@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + +moment-timezone@^0.5.x: + version "0.5.33" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.33.tgz#b252fd6bb57f341c9b59a5ab61a8e51a73bbd22c" + integrity sha512-PTc2vcT8K9J5/9rDEPe5czSIKgLoGsH8UNpA4qZTVw0Vd/Uz19geE9abbIOQKaAQFcnQ3v5YEXrbSc5BpshH+w== dependencies: moment ">= 2.9.0" -"moment@>= 2.9.0", moment@^2.26.0, moment@^2.29.1: +"moment@>= 2.9.0", moment@>=2.14.0: version "2.29.1" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== -ms@^2.1.1: +ms@2.1.2, ms@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + +napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= -needle@^2.2.1: - version "2.5.0" - resolved "https://registry.yarnpkg.com/needle/-/needle-2.5.0.tgz#e6fc4b3cc6c25caed7554bd613a5cf0bac8c31c0" - integrity sha512-o/qITSDR0JCyCKEQ1/1bnUXMmznxabbwi/Y4WwJElf+evwJNFNwIDMCCt5IigFVxgeGBJESLohGtIS9gEzo1fA== +node-abi@^2.21.0: + version "2.30.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.30.0.tgz#8be53bf3e7945a34eea10e0fc9a5982776cf550b" + integrity sha512-g6bZh3YCKQRdwuO/tSZZYJAw622SjsRfJ2X0Iy4sSOHZ34/sPPdVBn8fev2tj7njzLwuqPw9uMtGsGkO5kIQvg== dependencies: - debug "^3.2.6" - iconv-lite "^0.4.4" - sax "^1.2.4" + semver "^5.4.1" -node-addon-api@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.1.0.tgz#98b21931557466c6729e51cb77cd39c965f42239" - integrity sha512-flmrDNB06LIl5lywUz7YlNGZH/5p0M7W28k8hzd9Lshtdh1wshD2Y+U4h9LD6KObOy1f+fEVdgprPrEymjM5uw== +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== -node-fetch@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== +normalize-url@^4.1.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== -node-gyp@3.x: - version "3.8.0" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-3.8.0.tgz#540304261c330e80d0d5edce253a68cb3964218c" - integrity sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA== - dependencies: - fstream "^1.0.0" - glob "^7.0.3" - graceful-fs "^4.1.2" - mkdirp "^0.5.0" - nopt "2 || 3" - npmlog "0 || 1 || 2 || 3 || 4" - osenv "0" - request "^2.87.0" - rimraf "2" - semver "~5.3.0" - tar "^2.0.0" - which "1" - -node-pre-gyp@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz#db1f33215272f692cd38f03238e3e9b47c5dd054" - integrity sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q== - dependencies: - detect-libc "^1.0.2" - mkdirp "^0.5.1" - needle "^2.2.1" - nopt "^4.0.1" - npm-packlist "^1.1.6" - npmlog "^4.0.2" - rc "^1.2.7" - rimraf "^2.6.1" - semver "^5.3.0" - tar "^4" - -"nopt@2 || 3": - version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= - dependencies: - abbrev "1" - -nopt@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" - integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== - dependencies: - abbrev "1" - osenv "^0.1.4" - -npm-bundled@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" - integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA== - dependencies: - npm-normalize-package-bin "^1.0.1" - -npm-normalize-package-bin@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" - integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== - -npm-packlist@^1.1.6: - version "1.4.8" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e" - integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A== - dependencies: - ignore-walk "^3.0.1" - npm-bundled "^1.0.1" - npm-normalize-package-bin "^1.0.1" - -"npmlog@0 || 1 || 2 || 3 || 4", npmlog@^4.0.2: +npmlog@^4.0.1: version "4.1.2" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== @@ -1108,23 +1698,32 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= -once@^1.3.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= dependencies: wrappy "1" +one-time@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/one-time/-/one-time-1.0.0.tgz#e06bc174aed214ed58edede573b433bbf827cb45" + integrity sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g== + dependencies: + fn.name "1.x.x" + +onetime@^5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + optionator@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" @@ -1142,23 +1741,40 @@ opusscript@^0.0.8: resolved "https://registry.yarnpkg.com/opusscript/-/opusscript-0.0.8.tgz#00b49e81281b4d99092d013b1812af8654bd0a87" integrity sha512-VSTi1aWFuCkRCVq+tx/BQ5q9fMnQ9pVZ3JU4UHKqTkf0ED3fKEPdr+gKAAl3IA2hj9rrP6iyq3hlcJq3HELtNQ== -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= +ora@^5.3.0, ora@^5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" + integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== + dependencies: + bl "^4.1.0" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-spinners "^2.5.0" + is-interactive "^1.0.0" + is-unicode-supported "^0.1.0" + log-symbols "^4.1.0" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" -os-tmpdir@^1.0.0: +os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= -osenv@0, osenv@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" - integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + +package-json@^6.5.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" + integrity sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ== dependencies: - os-homedir "^1.0.0" - os-tmpdir "^1.0.0" + got "^9.6.0" + registry-auth-token "^4.0.0" + registry-url "^5.0.0" + semver "^6.2.0" parent-module@^1.0.0: version "1.0.1" @@ -1177,16 +1793,57 @@ path-key@^3.1.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" + integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== + +prebuild-install@^6.0.1: + version "6.1.3" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.1.3.tgz#8ea1f9d7386a0b30f7ef20247e36f8b2b82825a2" + integrity sha512-iqqSR84tNYQUQHRXalSKdIaM8Ov1QxOVuBNWI7+BzZWv6Ih9k75wOnH1rGQ9WWTaaLkTpxWKIciOF0KyfM74+Q== + dependencies: + detect-libc "^1.0.3" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^2.21.0" + npmlog "^4.0.1" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^3.0.3" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc= + +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.1.tgz#76903c3f8c4449bc9ac597acefa24dc5ad4cbea6" + integrity sha512-p+vNbgpLjif/+D+DwAZAbndtRrR0md0MwfmOVN9N+2RgyACMT+7tfaRnT+WDPkqnuVwleyuBIG2XBxKDme3hPA== + process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -1197,22 +1854,33 @@ progress@^2.0.0: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -psl@^1.1.28: - version "1.8.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" - integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" -punycode@^2.1.0, punycode@^2.1.1: +punycode@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -rc@^1.2.7: +quick.db@^7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/quick.db/-/quick.db-7.1.3.tgz#dd111dac3aa0cf818f07306b537ca6f8b4b2ef7b" + integrity sha512-0S1fVb9OAZGhkI4ZIc5Oe4yWMwhz20xSsziwd6+yGWKKMsPt+XOfj/gD5CesGxd2WdqBkZFBiP8ZqWDu55HLHA== + dependencies: + better-sqlite3 "^7.1.1" + lodash "^4.17.20" + +rc@^1.2.7, rc@^1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== @@ -1222,7 +1890,7 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" -readable-stream@^2.0.6: +readable-stream@^2.0.6, readable-stream@^2.3.7: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -1235,92 +1903,75 @@ readable-stream@^2.0.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" -redis-commands@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/redis-commands/-/redis-commands-1.7.0.tgz#15a6fea2d58281e27b1cd1acfb4b293e278c3a89" - integrity sha512-nJWqw3bTFy21hX/CPKHth6sfhZbdiHP6bTawSgQBlKOVRG7EZkfHbbHwQJnrE4vsQf0CMNE+3gJ4Fmm16vdVlQ== - -redis-errors@^1.0.0, redis-errors@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" - integrity sha1-62LSrbFeTq9GEMBK/hUpOEJQq60= - -redis-parser@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" - integrity sha1-tm2CjNyv5rS4pCin3vTGvKwxyLQ= +readable-stream@^3.1.1, readable-stream@^3.4.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" + integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== dependencies: - redis-errors "^1.0.0" + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" -redis@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/redis/-/redis-3.1.2.tgz#766851117e80653d23e0ed536254677ab647638c" - integrity sha512-grn5KoZLr/qrRQVwoSkmzdbw6pwF+/rwODtrOr6vuBRiR/f3rjSTGupbF90Zpqm2oenix8Do6RV7pYEkGwlKkw== +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: - denque "^1.5.0" - redis-commands "^1.7.0" - redis-errors "^1.2.0" - redis-parser "^3.0.0" + picomatch "^2.2.1" regexpp@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2" integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q== -request@^2.87.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== +registry-auth-token@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.1.tgz#6d7b4006441918972ccd5fedcd41dc322c79b250" + integrity sha512-6gkSb4U6aWJB4SF2ZvLb76yCBjcvufXBqvvEx1HbmKPkutswjW1xNVRY0+daljIYRbogN7O0etYSlbiaEQyMyw== dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" + rc "^1.2.8" + +registry-url@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-5.1.0.tgz#e98334b50d5434b81136b44ec638d9c2009c5009" + integrity sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw== + dependencies: + rc "^1.2.8" require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== -require-reload@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/require-reload/-/require-reload-0.2.2.tgz#29a7591846caf91b6e8a3cda991683f95f8d7d42" - integrity sha1-KadZGEbK+RtuijzamRaD+V+NfUI= +require-package-name@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/require-package-name/-/require-package-name-2.0.1.tgz#c11e97276b65b8e2923f75dabf5fb2ef0c3841b9" + integrity sha1-wR6XJ2tluOKSP3Xav1+y7ww4Qbk= resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -retry-as-promised@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/retry-as-promised/-/retry-as-promised-3.2.0.tgz#769f63d536bec4783549db0777cb56dadd9d8543" - integrity sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg== +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= dependencies: - any-promise "^1.3.0" + lowercase-keys "^1.0.0" -rimraf@2, rimraf@^2.6.1: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== dependencies: - glob "^7.1.3" + onetime "^5.1.0" + signal-exit "^3.0.2" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== rimraf@^3.0.2: version "3.0.2" @@ -1329,7 +1980,26 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" -safe-buffer@^5.0.1, safe-buffer@^5.1.2: +run-async@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +rxjs@^6.6.6: + version "6.6.7" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" + integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== + dependencies: + tslib "^1.9.0" + +safe-buffer@^5.0.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -1339,54 +2009,32 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sax@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" - integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== - -semver@^5.3.0: +semver@^5.4.1: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@^7.2.1, semver@^7.3.2: +semver@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +semver@^7.2.1: version "7.3.2" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== -semver@~5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" - integrity sha1-myzl094C0XxgEq0yaqa00M9U+U8= - -sequelize-pool@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-6.1.0.tgz#caaa0c1e324d3c2c3a399fed2c7998970925d668" - integrity sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg== - -sequelize@^6.6.2: - version "6.6.2" - resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-6.6.2.tgz#3681b0a4aeb106e31079d3a537d88542051dab2e" - integrity sha512-H/zrzmTK+tis9PJaSigkuXI57nKBvNCtPQol0yxCvau1iWLzSOuq8t3tMOVeQ+Ep8QH2HoD9/+FCCIAqzUr/BQ== +semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== dependencies: - debug "^4.1.1" - dottie "^2.0.0" - inflection "1.12.0" - lodash "^4.17.20" - moment "^2.26.0" - moment-timezone "^0.5.31" - retry-as-promised "^3.2.0" - semver "^7.3.2" - sequelize-pool "^6.0.0" - toposort-class "^1.0.1" - uuid "^8.1.0" - validator "^10.11.0" - wkx "^0.5.0" + lru-cache "^6.0.0" set-blocking@~2.0.0: version "2.0.0" @@ -1405,11 +2053,37 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -signal-exit@^3.0.0: +signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3" + integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA== + dependencies: + decompress-response "^4.2.0" + once "^1.3.1" + simple-concat "^1.0.0" + +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo= + dependencies: + is-arrayish "^0.3.1" + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + slice-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" @@ -1419,35 +2093,33 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" +source-map-support@^0.5.17, source-map-support@^0.5.19: + version "0.5.19" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" + integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -sqlite3@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/sqlite3/-/sqlite3-5.0.2.tgz#00924adcc001c17686e0a6643b6cbbc2d3965083" - integrity sha512-1SdTNo+BVU211Xj1csWa8lV6KM0CtucDwRyA0VHl91wEH1Mgh7RxUpI4rVvG7OhHrzCSGaVyW5g8vKvlrk9DJA== - dependencies: - node-addon-api "^3.0.0" - node-pre-gyp "^0.11.0" - optionalDependencies: - node-gyp "3.x" +stack-trace@0.0.x: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" +steno@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/steno/-/steno-2.0.0.tgz#1dff26d139f7771012c068693afdca4cd00f5ebd" + integrity sha512-GhVTL9HHZk2R+ApyU/rDFbSZRoXjyaGYWkt0Esxz6+Ocwbn7Etbz6SzlvX5tanuYIRyQ2q8E3+GMuAfih772Fw== string-width@^1.0.1: version "1.0.2" @@ -1466,6 +2138,15 @@ string-width@^1.0.1: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string-width@^4.1.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" + integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.0" + string-width@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" @@ -1475,6 +2156,13 @@ string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" +string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -1539,45 +2227,132 @@ table@^6.0.9: string-width "^4.2.0" strip-ansi "^6.0.0" -tar@^2.0.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.2.tgz#0ca8848562c7299b8b446ff6a4d60cdbb23edc40" - integrity sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA== - dependencies: - block-stream "*" - fstream "^1.0.12" - inherits "2" - -tar@^4: - version "4.4.13" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" - integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== +tar-fs@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== dependencies: chownr "^1.1.1" - fs-minipass "^1.2.5" - minipass "^2.8.6" - minizlib "^1.2.1" - mkdirp "^0.5.0" - safe-buffer "^5.1.2" - yallist "^3.0.3" + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^2.1.4" + +tar-stream@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== + dependencies: + bl "^4.0.3" + end-of-stream "^1.4.1" + fs-constants "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.1.1" + +tar@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" + integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^3.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + +text-hex@1.0.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" + integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= -toposort-class@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toposort-class/-/toposort-class-1.0.1.tgz#7ffd1f78c8be28c3ba45cd4e1a3f5ee193bd9988" - integrity sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg= +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== dependencies: - psl "^1.1.28" - punycode "^2.1.1" + os-tmpdir "~1.0.2" + +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +tree-kill@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== + +triple-beam@^1.2.0, triple-beam@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" + integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== + +ts-devscript@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/ts-devscript/-/ts-devscript-3.0.5.tgz#8d54cf5978c52d072f1cbd99c21ec8101c75c57c" + integrity sha512-IwNbuiU328Q5j65fyLWUSjeO0UgbuU6MSVsCCfbHKw+vi9rhNDs2oNuCVQ0gJsLA7G3Iai9UFR2IWr9zvJDKGw== + dependencies: + "@yarnpkg/parsers" "^2.4.0-rc.3" + autopm "^1.3.1" + chalk "^4.1.1" + chokidar "^3.5.0" + command-line-args "^5.1.1" + compare-versions "^3.6.0" + debug "^4.3.1" + displayastree "^2.0.0" + fast-glob "^3.2.4" + fs-extra "^10.0.0" + inquirer "^8.1.0" + leasot "^12.0.0" + ora "^5.4.1" + source-map-support "^0.5.19" + tree-kill "^1.2.2" + typescript "^4.3.2" + +ts-node@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.0.0.tgz#05f10b9a716b0b624129ad44f0ea05dac84ba3be" + integrity sha512-ROWeOIUvfFbPZkoDis0L/55Fk+6gFQNZwwKPLinacRl6tsxstTF1DbAcLKkovwnpKMVvOMHP1TIbnwXwtLg1gg== + dependencies: + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + source-map-support "^0.5.17" + yn "3.1.1" + +tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" tunnel-agent@^0.6.0: version "0.6.0" @@ -1586,11 +2361,6 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - tweetnacl@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" @@ -1608,6 +2378,26 @@ type-fest@^0.20.2: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +typescript@^4.3.2, typescript@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.4.tgz#3f85b986945bcf31071decdd96cf8bfa65f9dcbc" + integrity sha512-uauPG7XZn9F/mo+7MrsRjyvbxFpzemRjKEZXS4AK83oP2KKOJPvb+9cO/gmnv8arWZvhnjVOXz7B49m1l0e9Ew== + +typical@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" + integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + uri-js@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" @@ -1615,46 +2405,29 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -util-deprecate@~1.0.1: +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha1-FrXK/Afb42dsGxmZF3gj1lA6yww= + dependencies: + prepend-http "^2.0.0" + +util-deprecate@^1.0.1, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -uuid@^8.1.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.0.tgz#ab738085ca22dc9a8c92725e459b1d507df5d6ea" - integrity sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ== - v8-compile-cache@^2.0.3: version "2.1.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" integrity sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g== -validator@^10.11.0: - version "10.11.0" - resolved "https://registry.yarnpkg.com/validator/-/validator-10.11.0.tgz#003108ea6e9a9874d31ccc9e5006856ccd76b228" - integrity sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw== - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= +wcwidth@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g= dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -which@1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" + defaults "^1.0.3" which@^2.0.1: version "2.0.2" @@ -1670,12 +2443,28 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" -wkx@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.5.0.tgz#c6c37019acf40e517cc6b94657a25a3d4aa33e8c" - integrity sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg== +winston-transport@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.4.0.tgz#17af518daa690d5b2ecccaa7acf7b20ca7925e59" + integrity sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw== dependencies: - "@types/node" "*" + readable-stream "^2.3.7" + triple-beam "^1.2.0" + +winston@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.3.3.tgz#ae6172042cafb29786afa3d09c8ff833ab7c9170" + integrity sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw== + dependencies: + "@dabh/diagnostics" "^2.0.2" + async "^3.1.0" + is-stream "^2.0.0" + logform "^2.2.0" + one-time "^1.0.0" + readable-stream "^3.4.0" + stack-trace "0.0.x" + triple-beam "^1.3.0" + winston-transport "^4.4.0" word-wrap@^1.2.3: version "1.2.3" @@ -1692,7 +2481,12 @@ ws@^7.2.1: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== -yallist@^3.0.0, yallist@^3.0.3: +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yn@3.1.1: version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==