commit 3c2acdaa01a935b244f66c7fd81a6cb736ba6333
parent 8bc6825b0d808bc86675ed826a49f959cdcadf62
Author: Demonstrandum <moi@knutsen.co>
Date: Sun, 22 Mar 2020 21:16:34 +0000
Types for everything, multiple guilds, and version update.
Diffstat:
12 files changed, 168 insertions(+), 85 deletions(-)
diff --git a/lib/commands/crabbing.ts b/lib/commands/crabbing.ts
@@ -1,8 +1,8 @@
-import { Attachment } from 'discord.js';
+import { MessageAttachment } from 'discord.js';
export default (home_scope: HomeScope) => {
const { message } = home_scope;
- const attached = new Attachment(
+ const attached = new MessageAttachment(
'./lib/resources/crabbing.jpg',
'crabbing.jpg');
message.channel.send('Danny, having a jolly time.', attached);
diff --git a/lib/commands/help.ts b/lib/commands/help.ts
@@ -23,7 +23,7 @@ export default (home_scope: HomeScope) => {
let command : string = args[0].trim();
if (command.head() === CONFIG.commands.prefix)
command = command.tail();
- command = expand_alias(command, args).toLowerCase();
+ command = expand_alias(command, args, message).toLowerCase();
const help_index = KNOWN_COMMANDS.indexOf(command);
diff --git a/lib/commands/kiss.ts b/lib/commands/kiss.ts
@@ -1,5 +1,5 @@
import { FORMATS } from '.././extensions';
-import { RichEmbed, Message } from 'discord.js';
+import { MessageEmbed, Message } from 'discord.js';
export default (home_scope: HomeScope) => {
const { message, args }
@@ -24,7 +24,7 @@ export default (home_scope: HomeScope) => {
"https://i.imgur.com/8fcnQFS.gif",
];
- const embed = new RichEmbed()
+ const embed = new MessageEmbed()
.setColor('#ba3d8a')
.setTitle("Uh-oh... You're getting a kiss!")
.setDescription(`${to.format(FORMATS.bold)}, you got a kissu from \
diff --git a/lib/commands/pat.ts b/lib/commands/pat.ts
@@ -1,4 +1,4 @@
-import { Message, Attachment, RichEmbed } from 'discord.js';
+import { Message, MessageAttachment, MessageEmbed } from 'discord.js';
import { FORMATS } from '../extensions';
import Jimp from 'jimp';
@@ -43,17 +43,17 @@ export default (home_scope: HomeScope) => {
return;
}
- const attachment = new Attachment(buffer, filename);
- const embed = new RichEmbed()
+ const attachment = new MessageAttachment(buffer, filename);
+ const embed = new MessageEmbed()
.setColor('#b943e8')
.setTitle("Incoming pat")
.setDescription(description)
- .attachFile(attachment)
+ .attachFiles([attachment])
.setImage(`attachment://${filename}`);
message.channel.send(embed);
});
};
- pat(message.mentions.users.first().avatarURL);
+ pat(message.mentions.users.first().avatarURL());
};
diff --git a/lib/commands/ship.ts b/lib/commands/ship.ts
@@ -1,7 +1,7 @@
import { createHash } from 'crypto';
import { FORMATS } from '../extensions';
-import { Message, Attachment, RichEmbed } from 'discord.js';
+import { Message, MessageAttachment, MessageEmbed } from 'discord.js';
import Jimp from 'jimp';
@@ -110,14 +110,14 @@ export default (home_scope : HomeScope) => {
if (e && e.message)
return error_msg(e);
- const attachment = new Attachment(buffer, filename);
- const embed = new RichEmbed()
+ const attachment = new MessageAttachment(buffer, filename);
+ const embed = new MessageEmbed()
.setColor('#b943e8')
.setTitle(`Love grade between \
${users[0].username} & \
${users[1].username}`.squeeze())
.setDescription(response)
- .attachFile(attachment)
+ .attachFiles([attachment])
.setImage(`attachment://${filename}`);
message.channel.send(embed);
diff --git a/lib/default.ts b/lib/default.ts
@@ -2,12 +2,7 @@
/// and to act as a reference to how the config shall be
/// laid out. All fields are accounted for here.
-export default {
- name: "Simp'O'Matic",
- tag: "#1634",
- permissions: 8,
- lang: 'en',
-
+const DEFAULT_GUILD_CONFIG : ConfigType = {
pp_sizes: {
'541761315887120399': 16
},
@@ -15,6 +10,7 @@ export default {
weather_locations: {
'541761315887120399': 'Moscow'
},
+
commands: {
prefix: '!',
max_history: 40,
@@ -80,6 +76,7 @@ export default {
response: 'desu'
},
],
+ trigger: [],
// Blacklist (initially everyone can do everything,
// except for those listed specifically on this list).
blacklist: {
@@ -131,5 +128,6 @@ export default {
]
}
}
-
};
+
+export default DEFAULT_GUILD_CONFIG;
diff --git a/lib/extensions.ts b/lib/extensions.ts
@@ -5,8 +5,57 @@ declare global {
HELP_SOURCE: string, HELP_KEY: string,
GIT_URL: string, HELP_MESSAGES: string[],
HELP_SECTIONS: string[] , ALL_HELP: string[],
- CONFIG: any, SECRETS: any, KNOWN_COMMANDS: string[],
- expand_alias: (operator: string, args: string[]) => string
+ CONFIG: ConfigType, SECRETS: any, KNOWN_COMMANDS: string[],
+ expand_alias: (operator: string, args: string[], message: Message) => string
+ };
+
+ type MatchType = {
+ match: string | RegExp,
+ response: string
+ };
+
+ type IgnoreType = {
+ commands?: boolean,
+ commands_elevated?: boolean,
+ speech?: boolean
+ };
+
+ type ConfigType = {
+ pp_sizes: { [key: string]: number }
+ weather_locations: { [key: string]: string },
+ commands: {
+ prefix: string,
+ max_history: number,
+ not_understood: string,
+ aliases: { [key: string]: string },
+ }
+ rules: {
+ respond: MatchType[],
+ reject: MatchType[],
+ replace: MatchType[],
+ trigger: MatchType[],
+ blacklist: {
+ channels: string[],
+ users: {
+ [key: string]: IgnoreType
+ },
+ groups: {
+ [key: string]: IgnoreType
+ }
+ },
+ whitelist: {
+ users: string[],
+ groups: string[]
+ }
+ }
+ };
+
+ type GlobalConfigType = {
+ name: string,
+ tag: string,
+ permissions: number,
+ lang: 'en' | 'en-us' | 'en-gb',
+ guilds: { [key: string]: ConfigType }
};
interface Array<T> {
diff --git a/lib/format_oed.ts b/lib/format_oed.ts
@@ -1,4 +1,4 @@
-import { Attachment } from 'discord.js';
+import { MessageAttachment } from 'discord.js';
import { pp } from './utils';
// Mmm... spaghetti...
@@ -56,7 +56,7 @@ export default (res, message) => {
if (pron.audioFile) {
msg += ` Audio file: ${pron.audioFile}\n`;
has_sent_audio = !has_sent_audio;
- const attach = new Attachment(
+ const attach = new MessageAttachment(
pron.audioFile,
pron.audioFile.split('/').slice(-1)[0]
);
diff --git a/lib/main.ts b/lib/main.ts
@@ -3,7 +3,7 @@ process.stdin.resume();
// Discord Bot API.
import { Discord, On, Client } from '@typeit/discord';
-import { Message, Attachment, TextChannel } from 'discord.js';
+import { Message, MessageAttachment, TextChannel } from 'discord.js';
// System interaction modules.
import {
@@ -20,8 +20,8 @@ import { deep_merge, pp, compile_match,
deep_copy, recursive_regex_to_string } from './utils';
import format_oed from './format_oed'; // O.E.D. JSON entry to markdown.
-// Default bot configuration JSON.
-import DEFAULT_CONFIG from './default';
+// Default bot configuration for a Guild, JSON.
+import DEFAULT_GUILD_CONFIG from './default';
// API specific modules.
import web_search from './api/google';
@@ -32,9 +32,16 @@ import { pastebin_latest,
// Anything that hasn't been defined in `bot.json`
// will be taken care of by the defaults.
-let CONFIG = deep_merge(
- DEFAULT_CONFIG,
- JSON.parse(read_file('./bot.json', 'utf-8')));
+let GLOBAL_CONFIG : GlobalConfigType = {
+ name: "Simp'O'Matic",
+ tag: "#1634",
+ permissions: 8,
+ lang: 'en',
+
+ guilds: {
+ "337815809097465856": deep_copy(DEFAULT_GUILD_CONFIG)
+ }
+};
// Store secrets in an object, retrieved from shell's
// environment variables.
@@ -84,11 +91,12 @@ export class SimpOMatic {
`${__dirname}/*Discord.ts`
);
console.log('Secrets:', pp(SECRETS));
- console.log('Configured Variables:', pp(CONFIG));
console.log('Known commands:', pp(KNOWN_COMMANDS));
}
- expand_alias(operator: string, args: string[]) {
+ expand_alias(operator: string, args: string[], message: Message) {
+ const CONFIG = GLOBAL_CONFIG.guilds[message.guild.id];
+
const expander = (unexpanded: string) => {
let expansion = unexpanded;
if (CONFIG.commands.aliases.hasOwnProperty(unexpanded))
@@ -115,6 +123,8 @@ export class SimpOMatic {
}
process_command(message : Message) {
+ const CONFIG = GLOBAL_CONFIG.guilds[message.guild.id];
+
if (message.content.startsWith('..')) return;
const last_command = this._COMMAND_HISTORY.last();
@@ -151,7 +161,7 @@ export class SimpOMatic {
let operator = words[0].toLowerCase();
// Expansion of aliases will expand aliases used within
// the alias definition too. Yay.
- operator = this.expand_alias(operator, args);
+ operator = this.expand_alias(operator, args, message);
if (operator === 'CYCLIC_ALIAS') {
message.reply('The command you just used has aliases that go'
+ ' 300 levels deep, or the alias is cyclically dependant.'
@@ -344,7 +354,7 @@ export class SimpOMatic {
oed_lookup({
word: query,
- lang: CONFIG.lang,
+ lang: GLOBAL_CONFIG.lang,
id: SECRETS.oxford.id,
key: SECRETS.oxford.key
}).then(res => {
@@ -405,7 +415,7 @@ export class SimpOMatic {
if (export_string.length < 1980) {
message.channel.send("```json\n" + export_string + "\n```");
}
- const attach = new Attachment(file_dest, file_name);
+ const attach = new MessageAttachment(file_dest, file_name);
message.channel.send("**Export:**", attach);
message.answer(`A copy of this export (\`export-${today}.json\`) \
@@ -440,6 +450,8 @@ export class SimpOMatic {
}
process_generic(message : Message) {
+ const CONFIG = GLOBAL_CONFIG.guilds[message.guild.id];
+
const { content } = message;
if (!content) return; // Message with no content (deleted)...
for (const responder of CONFIG.rules.respond) {
@@ -463,6 +475,7 @@ export class SimpOMatic {
}
async last_message(opts) : Promise<string> {
+ const CONFIG = GLOBAL_CONFIG.guilds[opts.guild.id];
const channel = opts.channel as TextChannel;
if (!opts.offset) opts.offset = 1;
@@ -487,8 +500,7 @@ export class SimpOMatic {
let filter = m => m.content;
if (opts.mention)
filter = m => m.content && m.author.toString() === opts.mentioning;
-
- const messages = await channel.fetchMessages({
+ const messages = await channel.messages.fetch({
limit: CONFIG.commands.max_history
});
// Remember that the _latest_ message, is the one that
@@ -510,7 +522,8 @@ export class SimpOMatic {
if (expansions[i].length === 2) { // !! expansion
expansions[i] = await this.last_message({
command: true,
- channel: message.channel
+ channel: message.channel,
+ guild: message.guild
});
continue;
}
@@ -539,10 +552,18 @@ export class SimpOMatic {
@On("message")
async on_message(message : Message, client : Client) {
+ const guild_id = message.guild.id;
+
+ // Initialise completely new Guilds.
+ if (!GLOBAL_CONFIG.guilds.hasOwnProperty(guild_id))
+ GLOBAL_CONFIG.guilds[guild_id] = deep_copy(DEFAULT_GUILD_CONFIG);
+
+ const CONFIG = GLOBAL_CONFIG.guilds[guild_id];
// Ignore empty messages...
if (!message.content) return;
console.log('Message acknowledged.');
+ console.log('Message from Guild ID:', guild_id);
if (SimpOMatic._CLIENT.user.id === message.author.id) {
return;
}
@@ -580,8 +601,8 @@ export class SimpOMatic {
const on_termination = () => {
// Back-up the resultant CONFIG to an external file.
console.log('Cleaning up...');
- write_file(`${process.cwd()}/export-exit.json`, export_config(CONFIG, {}));
- pastebin_update(export_config(CONFIG, {}));
+ write_file(`${process.cwd()}/export-exit.json`, export_config(GLOBAL_CONFIG, {}));
+ pastebin_update(export_config(GLOBAL_CONFIG, {}));
// Make sure we saved ok.
return new Promise(res => setTimeout(() => {
res(null);
@@ -592,13 +613,18 @@ const on_termination = () => {
// CONFIG will eventually update to the online version.
pastebin_latest().then(res => {
- CONFIG = deep_merge(CONFIG, res);
+ GLOBAL_CONFIG = deep_merge(GLOBAL_CONFIG, res);
// Remove any duplicates.
- CONFIG = export_config(CONFIG, { ugly: true });
- CONFIG = JSON.parse(CONFIG);
+ const gc_string = export_config(GLOBAL_CONFIG, { ugly: true });
+ GLOBAL_CONFIG = JSON.parse(gc_string);
// Precompile all regular-expressions in known places.
- ['respond', 'reject', 'replace']
- .each(name => CONFIG.rules[name].mut_map(compile_match));
+ for(const guild in GLOBAL_CONFIG.guilds)
+ if (GLOBAL_CONFIG.guilds.hasOwnProperty(guild))
+ ['respond', 'reject', 'replace']
+ .each(name =>
+ GLOBAL_CONFIG.guilds[guild].rules[name]
+ .mut_map(compile_match));
+
// Start The Simp'O'Matic.
SimpOMatic.start();
}).catch(console.warn);
@@ -609,4 +635,3 @@ process.on('exit', on_termination);
process.on('SIGINT', on_termination);
process.on('SIGUSR1', on_termination);
process.on('SIGUSR2', on_termination);
-process.on('uncaughtException', on_termination);
diff --git a/lib/utils.ts b/lib/utils.ts
@@ -97,11 +97,14 @@ export const export_config = (obj, { ugly = false }) => {
const o = recursive_regex_to_string(deep_clone(obj));
// Make sure all rules are unique,
// i.e. eliminate duplicate rules.
- ['respond', 'reject', 'replace']
- .forEach(name => o.rules[name] = o.rules[name]
- .map(JSON.stringify)
- .unique()
- .map(JSON.parse));
+
+ for (const guild in obj.guilds)
+ if (obj.guilds.hasOwnProperty(guild))
+ ['respond', 'reject', 'replace']
+ .each(name => o.guilds[guild].rules[name] = o.guilds[guild].rules[name]
+ .map(JSON.stringify)
+ .unique()
+ .map(JSON.parse));
return JSON.stringify(o, null, ugly ? null : 4);
};
diff --git a/package.json b/package.json
@@ -34,13 +34,13 @@
},
"dependencies": {
"@typeit/discord": "^1.0.3",
- "@types/node": "^13.9.0",
+ "@types/node": "^13.9.3",
"@types/node-fetch": "^2.5.5",
"@types/ws": "^7.2.2",
"better-pastebin": "^0.4.1",
"cowsay": "^1.4.0",
"deepcopy": "^2.0.0",
- "discord.js": "11.6.1",
+ "discord.js": "12.0.2",
"figlet": "^1.3.0",
"figlet-cli": "^0.1.1",
"fortune-teller": "^0.1.2",
diff --git a/yarn.lock b/yarn.lock
@@ -30,6 +30,11 @@
dependencies:
regenerator-runtime "^0.13.4"
+"@discordjs/collection@^0.1.5":
+ version "0.1.5"
+ resolved "https://registry.yarnpkg.com/@discordjs/collection/-/collection-0.1.5.tgz#1781c620b4c88d619bd0373a1548e5a6025e3d3a"
+ integrity sha512-CU1q0UXQUpFNzNB7gufgoisDHP7n+T3tkqTsp3MNUkVJ5+hS3BCvME8uCXAUFlz+6T2FbTCu75A+yQ7HMKqRKw==
+
"@jimp/bmp@^0.9.6":
version "0.9.6"
resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.9.6.tgz#379e261615d7c1f3b52af4d5a0f324666de53d7d"
@@ -324,10 +329,10 @@
"@types/node" "*"
form-data "^3.0.0"
-"@types/node@*", "@types/node@^13.9.0":
- version "13.9.2"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.2.tgz#ace1880c03594cc3e80206d96847157d8e7fa349"
- integrity sha512-bnoqK579sAYrQbp73wwglccjJ4sfRdKU7WNEZ5FW4K2U6Kc0/eZ5kvXG0JKsEKFB50zrFmfFt52/cvBbZa7eXg==
+"@types/node@*", "@types/node@^13.9.3":
+ version "13.9.3"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-13.9.3.tgz#6356df2647de9eac569f9a52eda3480fa9e70b4d"
+ integrity sha512-01s+ac4qerwd6RHD+mVbOEsraDHSgUaefQlEdBbUolnQFjKwCr7luvAlEwW1RFojh67u0z4OUTjPn9LEl4zIkA==
"@types/ws@^7.2.2":
version "7.2.3"
@@ -700,16 +705,19 @@ diff@^4.0.1:
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
-discord.js@11.6.1:
- version "11.6.1"
- resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-11.6.1.tgz#be5a0e0fc8f91fa46d9cd265261268948bcf8dc5"
- integrity sha512-UV7rMQL2xtHtbHAaGwRlAhEepHjz3V0UEEoWd89QbLMu3MV0D7+xkYCaAhlxnvuJWbhPO8p49Anx8qJ/SrcdwQ==
+discord.js@12.0.2:
+ version "12.0.2"
+ resolved "https://registry.yarnpkg.com/discord.js/-/discord.js-12.0.2.tgz#c4d68f1363d7fc05ed71a42dba6b930966ed8602"
+ integrity sha512-iZiEA4Y61gqq/EjFfLXnkRK9pLapnax/vTVDUhs/mAhyqozAy0GOlk/MZI9rSa1iIoKTWRq6P9CRKhLNT2wUnA==
dependencies:
- long "^4.0.0"
- prism-media "^0.0.4"
- snekfetch "^3.6.4"
- tweetnacl "^1.0.0"
- ws "^6.0.0"
+ "@discordjs/collection" "^0.1.5"
+ abort-controller "^3.0.0"
+ form-data "^3.0.0"
+ node-fetch "^2.6.0"
+ prism-media "^1.2.0"
+ setimmediate "^1.0.5"
+ tweetnacl "^1.0.3"
+ ws "^7.2.1"
dom-serializer@0:
version "0.2.2"
@@ -1353,11 +1361,6 @@ lodash@^4.17.15:
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
-long@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28"
- integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==
-
lru-cache@^5.0.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
@@ -1569,10 +1572,10 @@ prelude-ls@~1.1.2:
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=
-prism-media@^0.0.4:
- version "0.0.4"
- resolved "https://registry.yarnpkg.com/prism-media/-/prism-media-0.0.4.tgz#df5ddc6463670c97ff0e9cbac3c3e0db18df326f"
- integrity sha512-dG2w7WtovUa4SiYTdWn9H8Bd4JNdei2djtkP/Bk9fXq81j5Q15ZPHYSwhUVvBRbp5zMkGtu0Yk62HuMcly0pRw==
+prism-media@^1.2.0:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/prism-media/-/prism-media-1.2.1.tgz#168f323712bcaacb1d70ae613bf9d9dc44cf43d4"
+ integrity sha512-R3EbKwJiYlTvGwcG1DpUt+06DsxOGS5W4AMEHT7oVOjG93MjpdhGX1whHyjnqknylLMupKAsKMEXcTNRbPe6Vw==
process@~0.5.1:
version "0.5.2"
@@ -1590,9 +1593,9 @@ punycode@^2.1.0, punycode@^2.1.1:
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
qs@^6.7.0:
- version "6.9.1"
- resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.1.tgz#20082c65cb78223635ab1a9eaca8875a29bf8ec9"
- integrity sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA==
+ version "6.9.2"
+ resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.2.tgz#a27b695006544a04bf0e6c6a7e8120778926d5bd"
+ integrity sha512-2eQ6zajpK7HwqrY1rRtGw5IZvjgtELXzJECaEDuzDFo2jjnIXpJSimzd4qflWZq6bLLi+Zgfj5eDrAzl/lptyg==
qs@~6.5.2:
version "6.5.2"
@@ -1697,10 +1700,10 @@ semver@^5.3.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
-snekfetch@^3.6.4:
- version "3.6.4"
- resolved "https://registry.yarnpkg.com/snekfetch/-/snekfetch-3.6.4.tgz#d13e80a616d892f3d38daae4289f4d258a645120"
- integrity sha512-NjxjITIj04Ffqid5lqr7XdgwM7X61c/Dns073Ly170bPQHLm6jkmelye/eglS++1nfTWktpP6Y2bFXjdPlQqdw==
+setimmediate@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
+ integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
source-map@~0.6.1:
version "0.6.1"
@@ -1839,7 +1842,7 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
-tweetnacl@^1.0.0:
+tweetnacl@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596"
integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==
@@ -1961,13 +1964,18 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
-ws@^6.0.0, ws@^6.1.0:
+ws@^6.1.0:
version "6.2.1"
resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb"
integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==
dependencies:
async-limiter "~1.0.0"
+ws@^7.2.1:
+ version "7.2.3"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46"
+ integrity sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==
+
xhr@^2.0.1:
version "2.5.0"
resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.5.0.tgz#bed8d1676d5ca36108667692b74b316c496e49dd"