commit 9988c4ad1258af32328b6421b78794d5c29fcb35
parent e2536d0ab96905e9271c66e5777eb0929378474d
Author: Demonstrandum <moi@knutsen.co>
Date: Sun, 8 Mar 2020 15:16:22 +0000
Added !help and some more commands.
Diffstat:
17 files changed, 656 insertions(+), 1101 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -2,8 +2,18 @@
secrets.json
export_secrets.sh
-# Node
+# Node / NPM / Yarn
node_modules/
+package-lock.json
+yarn.lock
-# Build dir
+# Build files
build/
+export.json
+export*.json
+
+# Deployment info
+.now
+
+# Logs
+*.log
diff --git a/HELP.md b/HELP.md
@@ -0,0 +1,45 @@
+**KEY:**
+` ! ` — is the standard command prefix.
+`[...]` — specifies an option/argument to the command (required).
+`<...>` — specifies an optional option/argument to the command (not-required).
+
+▬▬▬
+
+- `!help` — Shows this page.
+- `!export` — Exports current configuration, and saves it.
+- `!prefix [new]` — Changes the prefix for sending this bot commands (default is `!`). Can only be one (1) character/symbol/grapheme/rune long.
+- `!id <who>` — Print ID of user, or self if no-one is specified.
+- `!alias` — Manage aliases to commands:
+ - `!alias ![the-alias] ![the-command]` — to add a new alias.
+ - `!alias <ls>` — lists all aliases numerically.
+ - `!alias rm ![the-alias]` — removes the alias by name.
+ - `!alias rm #[alias-index]` — removes alias by index.
+- `!ignore` — What the bot should ignore:
+ - `!ignore channel [#channel-name]` — ignores everything in said channel.
+ - `!ignore user [@user-name]` — ignores everything that user says/does.
+ - `!ignore user speech [@user-name]` — ignores any non-commands given by that user.
+ - `!ignore user commands [@user-name]` — ignores all commands that user tries to use.
+ - `!ignore user commands elevated [@user-name]` — ignores all elevated/high-permissions commands that user tries to use.
+ - `!ignore group ...` — works exactly like ignore-user, but for groups instead.
+ - `!ignore not ...` — works exactly like all other ignore-commands, but does the opposite (toggles that rule ignore-rule on-off).
+ - `!ignore whitelist [type] [@name]` — Will exempt certain users or groups from any of the ignore-rules, ever. (`[type]` is either `user` or `group`)
+ - `!ignore <ls>` — lists all ignore rules by type.
+ - `!ignore rm [type] [@name]` — clears all ignore rules for a certain type (types are: `user`, `channel` or `group`).
+- `!respond` — How the bot should respond to certain messages:
+ - `!respond [match] [reply]` — matches an expression said (using regular-expressions, i.e. `/regex/flags`), and replies with a message.
+ - `!respond <ls>` — list all response rules numerically.
+ - `!respond rm #[rule-index]` — removes the response-rule by index.
+- `!reject` — Deletes messages meeting certain patterns:
+ - `!reject [match] <reply>` — rejects certain messages, matching a regular-expression (specifying a reply is optional).
+ - `!reject <ls>` — numerically lists all rejection rules.
+ - `!reject rm #[rule-index]` — removes the rejection-rule specified by a numerical index.
+- `!replace` — Bots currently do not have the ability to edit other users messages. We can only wait.
+- `!define [word]` — Looks a word up in the Oxford English Dictionary.
+- `!urban [slang]` — Looks up a piece of slang in the _Urban Dictionary_.
+- `!search [web-search-terms]` — Performs a web-search and returns the most appropriate URL found.
+- `!image [image-search-terms]` — Searches for images specified by the terms given, and send a link to the most relevant one.
+- `!youtube [youtube-search-terms]` — Searches for and returns a relevant _YouTube_ video.
+- `!cron` — Run commands repeatedly based on some timer (Google cron syntax for more info):
+ - `!cron [minute] [hour] [day-of-month] [month] [day-of-week] ![command] <...>` — runs a command (with or without arguments) repeatedly as specified by the schedule signature.
+ - `!cron <ls>` — lists all active cron-jobs numerically.
+ - `!cron rm #[job-index]` — removes a cron-job by index.
diff --git a/README.md b/README.md
@@ -0,0 +1,71 @@
+# The Simp'O'Matic
+
+## WIP
+
+Currently most of the features in the `HELP.md` page, have not been
+implemented. Please my fren, if you have the time, send some pull
+requests my way.
+
+Yours, Sammy (in desperation for a nice FOSS-bot).
+
+## Help / Bot-Commands
+
+See [HELP.md](./HELP.md) file (keep in mind, that the file has
+been formatted for better viewing through Discord, might look funky
+with GitHub rendering).
+
+## Getting Up & Running
+
+Make sure you have `node` (`v12.x`) and `yarn`installed
+(`npm` also possible).
+
+- Clean up from previous build/install:
+```sh
+yarn clean
+```
+- Install dependencies:
+```sh
+yarn install
+```
+- Build/Compile files:
+```sh
+yarn build
+```
+- Run the bot locally:
+```sh
+yarn run
+```
+- Or deploy it with `now`:
+```sh
+yarn deploy
+```
+
+In both cases (`deploy` or `start`) you'll need your secrets set up
+(API keys etc.).
+
+### Local Secrets
+
+Make sure locally, you have the following secrets exported
+as environment variables:
+```sh
+export BOT_API_TOKEN="exampleExampleExampleExample"
+export RAPID_API_KEY="exampleExampleExampleExample"
+export CLIENT_KEY="exampleExampleExampleExample"
+export CLIENT_ID="exampleExampleExampleExample"
+export OXFORD_ID="exampleExampleExampleExample"
+export OXFORD_KEY="exampleExampleExampleExample"
+```
+
+### Now Deployment Secrets
+
+`now` has a `secrets` functionality, which will store your secrets, and
+export them as environment variables, for your `now`, you can do:
+```sh
+now secrets add discord-bot-api-token "$BOT_API_TOKEN"
+now secrets add rapid-api-key "$RAPID_API_KEY"
+now secrets add discord-client-key "$CLIENT_KEY"
+now secrets add discord-client-id "$CLIENT_ID"
+now secrets add oxford-dictionary-id "$OXFORD_ID"
+now secrets add oxford-dictionary-key "$OXFORD_KEY"
+```
+For some context, have a look in `./now.json`.
diff --git a/bot.json b/bot.json
@@ -5,5 +5,20 @@
"commands": {
"prefix": "!"
+ },
+
+ "rules": {
+ "respond": [
+ {
+ "match": "/Good (Morning|Day) (Star|Sun)shine/i",
+ "response": "The Earth says Hello!"
+ }
+ ],
+ "replace": [
+ {
+ "match": "/Yahweh/i",
+ "response": "Adonai"
+ }
+ ]
}
}
diff --git a/build.sh b/build.sh
@@ -1,11 +1,17 @@
#!/bin/sh
-[ ! -d "./node_modules" ] && echo "Installing..." && npm install
+bold="$(tput bold)"
+reset="$(tput sgr0)"
+
+[ ! -d "./node_modules" ] && echo "${bold}Installing...${reset}" && yarn install
rm -rf ./build
-mkdir -p ./build
+mkdir -p ./build ./public
-echo "Copying files..."
-cp ./bot.json ./generate_secrets.sh ./build
+echo "${bold}Copying config files...${reset}"
+cp ./bot.json ./generate_secrets.sh ./HELP.md ./build
+echo "${bold}Compiling TypeScript...${reset}"
+./node_modules/.bin/tsc -b ./tsconfig.json
+echo -e "\n${bold}Build done.${reset}"
diff --git a/generate_secrets.sh b/generate_secrets.sh
@@ -14,8 +14,12 @@ cat <<- JSON
"id": "$CLIENT_ID"
},
- "contextual": {
- "key": "$CONTEXTUAL_API_KEY"
+ "rapid": {
+ "key": "$RAPID_API_KEY"
+ },
+ "oxford": {
+ "id": "$OXFORD_ID",
+ "key": "$OXFORD_KEY"
}
}
JSON
diff --git a/lib/api/urban.ts b/lib/api/urban.ts
@@ -0,0 +1,25 @@
+import unirest from 'unirest';
+
+export const urban_search = options => new Promise((resolve, reject) => {
+ console.log('Searching Urban Dictionary, with options: ', options);
+
+ const url = 'https://mashape-community-urban-dictionary.p.rapidapi.com/define';
+
+ const req = unirest('GET', url);
+
+ req.query({
+ "term": options.query
+ });
+
+ req.headers({
+ "x-rapidapi-host": "mashape-community-urban-dictionary.p.rapidapi.com",
+ "x-rapidapi-key": options.key
+ });
+
+ req.end(res => {
+ if (res.error) return reject(res.error);
+ return resolve(res.body);
+ });
+});
+
+export default urban_search;
diff --git a/lib/api/web.ts b/lib/api/web.ts
@@ -0,0 +1,41 @@
+import unirest from 'unirest';
+
+export const web_search = options => new Promise((resolve, reject) => {
+ console.log('Searching the web, with options: ', options);
+
+ let api = 'WebSearchAPI';
+ switch (options.type) {
+ case 'image':
+ api = 'ImageSearchAPI';
+ break;
+ case 'web':
+ api = 'WebSearchAPI';
+ break;
+ case 'news':
+ api = 'NewsSearchAPI';
+ break;
+ }
+ const url = `https://contextualwebsearch-websearch-v1.p.rapidapi.com/api/Search/${api}`;
+
+ const req = unirest('GET', url);
+
+ req.query({
+ "autoCorrect": "false",
+ "pageNumber": "1",
+ "pageSize": "10",
+ "q": options.query,
+ "safeSearch": "false"
+ });
+
+ req.headers({
+ "x-rapidapi-host": "contextualwebsearch-websearch-v1.p.rapidapi.com",
+ "x-rapidapi-key": options.key
+ });
+
+ req.end(res => {
+ if (res.error) return reject(res.error);
+ return resolve(res.body);
+ });
+});
+
+export default web_search;
diff --git a/lib/default.ts b/lib/default.ts
@@ -0,0 +1,102 @@
+/// A default config file, that adds some basic functionality,
+/// 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,
+
+ commands: {
+ prefix: '!',
+ not_understood: "Command not understood",
+ aliases: {
+ 'img': 'image',
+ 'i': 'image',
+ 'h': 'help',
+ 's': 'search',
+ 'yt': 'youtube',
+ 'd': 'define',
+ 'oed': 'define',
+ 'ud': 'urban',
+ 'blacklist': 'ignore',
+ 'whitelist': 'ignore whitelist',
+ 'w': 'weather',
+ 'reply': 'respond',
+ 'reject': 'delete'
+ },
+ },
+
+ rules: {
+ // Below are the different kinds of _rules_.
+ respond: [
+ {
+ match: "/^\\s*thanks.*\\s*$/i",
+ response: 'Obama.'
+ },
+ ],
+ reject: [
+ {
+ match: "/\\.{4,}/",
+ response: null
+ },
+ ],
+ replace: [ // Message editing functionality not a thing yet...
+ {
+ match: "/tbh/i",
+ response: 'desu'
+ },
+ ],
+ // Blacklist (initially everyone can do everything,
+ // except for those listed specifically on this list).
+ blacklist: {
+ channels: [
+ 'music', 'news'
+ ],
+ users: {
+ // Should all be numbers/hashes, this one is bogus:
+ "instcel": {
+ commands: true,
+ commands_elevated: false,
+ speech: true,
+ },
+ // For real this time:
+ // -> `accelarion#0764`
+ // a.k.a. instcel,
+ // a.k.a. instgen
+ // a.k.a. installgentoo
+ "409461942495871016": {
+ commands: true,
+ commands_elevated: false,
+ speech: true
+ }
+ },
+ groups: {
+ // Should all be numbers/hashes, these are bogus.
+ "obese": {
+ commands_elevated: false,
+ },
+ "bpd": {
+ commands: false,
+ }
+ },
+ },
+
+ // In case you blacklist @everyone or something,
+ // you can override completely, to obtain all permissions just
+ // by putting them on the whitelist.
+ whitelist: {
+ users: [
+ // Dr. Henry Kissinger#5457
+ "265958795254038535",
+ // Danny#1986
+ "541761315887120399"
+ ],
+ groups: [
+ // Will all be numbers/hashes too.
+ "bourgeoisie"
+ ]
+ }
+ }
+
+}
diff --git a/lib/extensions.ts b/lib/extensions.ts
@@ -0,0 +1,44 @@
+// Array Extensions:
+interface Array<T> {
+ unique() : Array<T>
+ mut_unique(): Array<T>
+ mut_map(f : (T) => any) : Array<any>
+}
+
+Array.prototype.unique = function () {
+ return this.filter((e, i) => this.indexOf(e) === i)
+}
+
+Array.prototype.mut_unique = function () {
+ const uniq = this.unique();
+ Object.assign(this, uniq);
+ this.splice(uniq.length);
+ return this;
+}
+
+Array.prototype.mut_map = function (f) {
+ for (const i in this) {
+ this[i] = f(this[i]);
+ }
+ return this;
+}
+
+// String Extensions:
+interface String {
+ squeeze() : string
+}
+
+String.prototype.squeeze = function () {
+ return this.split(/[ ]+/).join(' ');
+};
+
+
+// Number Extensions:
+interface Number {
+ round_to(dp : number) : number
+}
+
+Number.prototype.round_to = function (dp : number) {
+ const exp = 10 ** dp;
+ return Math.round(this.valueOf() * exp) / exp;
+};
diff --git a/lib/main.ts b/lib/main.ts
@@ -1,28 +1,62 @@
import { Discord, On, Client } from '@typeit/discord';
-import { Message } from 'discord.js';
+import { Message, MessageAttachment } from 'discord.js';
-import { readFileSync as read } from 'fs';
-import { execSync } from 'child_process';
+import {
+ readFileSync as read_file,
+ writeFileSync as write_file,
+} from 'fs';
+import { execSync as shell } from 'child_process';
+import { inspect } from 'util';
-import './utils';
-import { search } from './search_api';
+import './extensions';
+import { deep_merge, pp, compile_match, export_config } from './utils';
+import DEFAULT_CONFIG from './default';
+import web_search from './api/web';
+import urban_search from './api/urban';
-const BOT_CONFIG = JSON.parse(read('./bot.json', 'utf-8'));
-const SECRETS = JSON.parse(execSync('sh ./generate_secrets.sh').toString());
+// Anything that hasn't been defined in `bot.json`
+// will be taken care of by the defaults.
+const CONFIG = deep_merge(
+ DEFAULT_CONFIG,
+ JSON.parse(read_file('./bot.json', 'utf-8')));
+
+// Precompile all regular-expressions in known places.
+['respond', 'reject', 'replace']
+ .forEach(name => CONFIG.rules[name].mut_map(compile_match))
+
+// Store secrets in an object, retrieved from shell's
+// environment variables.
+const SECRETS = JSON.parse(shell('sh ./generate_secrets.sh').toString());
+
+// Load HELP.md file, and split text smart-ly
+// (to fit within 2000 characters).
+const HELP = read_file('./HELP.md');
+const help_sections = HELP.toString()
+ .replace(/\n -/g, '\n \u25b8')
+ .replace(/\n- /g, '@@@\n\u2b25 ')
+ .split('@@@');
+
+let acc = "";
+let new_messages = [];
+
+for (const msg of help_sections)
+ if (acc.length + msg.length >= 1990) {
+ new_messages.push(acc);
+ acc = "";
+ } else { acc += msg; }
+
+new_messages.push(acc);
+const HELP_MESSAGES = new_messages;
+
+console.log(HELP_MESSAGES);
@Discord
export class SimpOMatic {
private static _client : Client;
- private _prefix : string = BOT_CONFIG.commands.prefix || '!';
- private _not_understood : string = BOT_CONFIG.not_understood
- || "Command not understood";
constructor() {
- console.log('Configured Variables: ', {
- "_prefix": this._prefix,
- "_not_understood": this._not_understood
- });
- console.log('Secrets: ', SECRETS);
+ console.log('Secrets:', pp(SECRETS));
+ console.log('Configured Variables:', pp(CONFIG));
}
static start() {
@@ -33,50 +67,153 @@ export class SimpOMatic {
);
}
- @On("message")
- async on_message(message : Message, client : Client) {
- console.log('Message acknowledged.');
- if (SimpOMatic._client.user.id === message.author.id
- || message.content[0] !== this._prefix) {
- return;
- }
+ process_command(message : Message) {
+ const words = message.content.slice(1).split(' ');
- console.log('Message received: ', message.content);
+ let command = words[0];
+ if (CONFIG.commands.aliases.hasOwnProperty(command))
+ command = CONFIG.commands.aliases[command];
+ command = command.toLowerCase();
- const words = message.content.slice(1).toLowerCase().split(' ');
- const command = words[0];
const args = words.slice(1);
+ console.log('Received command: ', [command, args]);
+
switch (command) {
- case "ping":
- message.reply("ponggers.");
+ case "ping": {
+ message.reply("PONGGERS!");
+ break;
+ } case 'help': {
+ message.reply('**HELP:**');
+ for (const msg of HELP_MESSAGES)
+ message.channel.send(msg);
+ break;
+ } case "id": {
+ const reply = `User ID: ${message.author.id}
+ Author: ${message.author}
+ Message ID: ${message.id}`.squeeze();
+ console.log(`Replied: ${reply}`);
+ message.reply(reply);
+ break;
+ } case "search": {
+ const query = args.join(' ');
+
+ web_search({
+ type: "search",
+ query,
+ key: SECRETS.rapid.key
+ }).then((res: object) => {
+ if (res['value'].length === 0) {
+ message.reply('No such results found.');
+ return;
+ }
+ message.reply(`Web search for ‘${query}’, found: ${res['value'][0].url}`);
+ }).catch(e => message.reply(`Error fetching results:\n${e}`));
break;
- case "img":
+ } case "image": {
const query = args.join(' ');
- search({
+
+ web_search({
type: "image",
query,
- key: SECRETS.contextual.key
- }).then((res : object) => {
- if (res['value'].length === 0)
+ key: SECRETS.rapid.key
+ }).then(res => {
+ if (res['value'].length === 0) {
message.reply('No such images found.');
- message.reply(`Image of ${query}: ${res['value'][0].url}`);
- }).catch(err => message.reply('Error fetching image.'));
+ return;
+ }
+ message.reply(`Image found for ‘${query}’: ${res['value'][0].url}`);
+ }).catch(e =>
+ message.reply(`Error fetching image:\n${e}`));
break;
- case "milkies":
- message.reply(`${(4 + Math.random() * 15).round_to(3)} gallons of milkies \
- have been deposited in your mouth.`.squeeze());
+ } case "urban": {
+ const query = args.join(' ');
+ urban_search({ query, key: SECRETS.rapid.key }).then(res => {
+ if (res['list'].length === 0) {
+ message.reply(`Congratulations, not even Urban \
+ Dictionary knows what you're trying to say.`.squeeze());
+ return;
+ }
+ const entry = res['list'][0];
+ const def = entry.definition.replace(/\[|\]/g, '');
+
+ message.reply(`Urban Dictionary defines \
+ ‘${query}’, as:\n> ${def}`.squeeze());
+ message.channel.send(`Link: ${entry.permalink}`);
+ }).catch(e => message.reply(`Error fetching definition:\n${e}`));
+ break;
+ } case "milkies": {
+ message.reply(`${(4 + Math.random() * 15).round_to(3)} gallons \
+ of milkies have been deposited in your mouth.`.squeeze());
+ break;
+ } case "say": {2
+ message.reply(`Me-sa says: “${args.join(' ')}”`);
break;
- case "say":
- message.reply(`Me says: "${args.join(' ')}"`);
+ } case "export": {
+ let export_string = export_config(CONFIG, {});
+ if (export_string.length > 1980) {
+ export_string = export_config(CONFIG, { ugly: true });
+ }
+
+ const today = (new Date())
+ .toISOString()
+ .replace(/\..*/, '')
+ .split('T')
+ .reverse()
+ .join('_');
+
+ const file_name = `export-${today}.json`
+ const file_dest = `${process.cwd()}/${file_name}`;
+ write_file(file_dest, export_config(CONFIG, {}));
+
+ if (export_string.length < 1980) {
+ message.channel.send("```json\n" + export_string + "\n```");
+ } else {
+ const attach = new MessageAttachment(file_dest);
+ attach.name = file_name;
+ message.channel.send("**Export:**", attach);
+ }
+
+ message.reply(`A copy of this export (\`export-${today}.json\`) \
+ has been saved to the local file system.`.squeeze());
break;
- default:
- message.reply(
- `\`[!!]\` ${this._not_understood}. (\`${command}\`)`);
+ }
+ default: {
+ message.reply(`
+ :warning: ${CONFIG.commands.not_understood}.
+ > \`${CONFIG.commands.prefix}${command}\``.squeeze());
break;
+ }
}
}
-}
+ process_generic(message : Message) {
+ const { content } = message;
+ if (content.includes('bot'))
+ message.reply("The hell you sayn' about bots?");
+ // TODO: Process _rules_ appropriately.
+ }
+
+ @On("message")
+ async on_message(message : Message, client : Client) {
+ console.log('Message acknowledged.');
+ if (SimpOMatic._client.user.id === message.author.id) {
+ return;
+ }
+ console.log('Message received:', message.content);
+ if (message.content[0] === CONFIG.commands.prefix) {
+ console.log('Message type: command.')
+ this.process_command(message);
+ } else {
+ console.log('Message type: generic.')
+ this.process_generic(message);
+ }
+ }
+}
+
+// Start The Simp'O'Matic.
SimpOMatic.start();
+
+// Back-up the resultant CONFIG to an external file.
+write_file(`${process.cwd()}/export.json`, export_config(CONFIG, {}));
diff --git a/lib/search_api.ts b/lib/search_api.ts
@@ -1,39 +0,0 @@
-import unirest from 'unirest';
-
-export const search = options => new Promise((resolve, reject) => {
- console.log('Searching the web, with options: ', options);
-
- let api = 'WebSearchAPI';
- switch (options.type) {
- case 'image':
- api = 'ImageSearchAPI';
- break;
- case 'web':
- api = 'WebSearchAPI';
- break;
- case 'news':
- api = 'NewsSearchAPI';
- break;
- }
- const url = `https://contextualwebsearch-websearch-v1.p.rapidapi.com/api/Search/${api}`;
-
- const req = unirest('GET', url);
-
- req.query({
- "autoCorrect": "false",
- "pageNumber": "1",
- "pageSize": "10",
- "q": options.query,
- "safeSearch": "false"
- });
-
- req.headers({
- "x-rapidapi-host": "contextualwebsearch-websearch-v1.p.rapidapi.com",
- "x-rapidapi-key": options.key
- });
-
- req.end(res => {
- if (res.error) return reject(res.error);
- return resolve(res.body);
- });
-});
diff --git a/lib/utils.ts b/lib/utils.ts
@@ -1,20 +1,86 @@
-// String Utils:
+import { inspect } from 'util';
+import deep_clone from 'deepcopy';
+import './extensions';
-String.prototype.squeeze = function () {
- return this.split(/\s+/).join(' ');
-};
+export const type: (obj: any) => string = (global => obj =>
+ (obj === global)
+ ? 'global'
+ : ({})
+ .toString.call(obj)
+ .match(/\s([a-z|A-Z]+)/)[1]
+ .toLowerCase())(this);
-interface String {
- squeeze() : string
-}
+export const pp = o => inspect(o, {
+ colors: true,
+ showHidden: false,
+ depth: 8
+});
+
+export const deep_merge_pair = (target, source) => {
+ Object.keys(source).forEach(key => {
+ const target_value = target[key];
+ const source_value = source[key];
+ if (Array.isArray(target_value)
+ && Array.isArray(source_value)) {
+ target[key] = target_value.concat(...source_value);
+ }
+ else if (type(target_value) === 'object'
+ && type(source_value) === 'object') {
+ target[key] = deep_merge_pair(target_value, source_value);
+ }
+ else {
+ target[key] = source_value;
+ }
+ });
-// Number Utils:
-Number.prototype.round_to = function (dp : number) {
- const exp = 10 ** dp;
- return Math.round(this.valueOf() * exp) / exp;
+ return target;
}
-interface Number {
- round_to(dp : number) : number
+export const deep_merge = (...objects) =>
+ (objects.length === 2)
+ ? deep_merge_pair(objects[0], objects[1])
+ : deep_merge_pair(objects[0], deep_merge(objects.slice(1)));
+
+
+export const parse_regex = (s : string) => {
+ let temp = s.split('/');
+ const options = temp.pop();
+ temp.shift();
+ const contents = temp.join('/');
+ return new RegExp(contents, options);
+};
+
+export const compile_match = obj => {
+ const o = deep_clone(obj);
+ if (type(o.match) === 'string') {
+ o.match = parse_regex(o.match);
+ }
+ return o;
+};
+
+const recursive_regex_to_string = o => {
+ if (type(o) === 'regexp') {
+ return o.toString();
+ }
+ if (type(o) === 'object' || type(o) === 'array') {
+ for (const key in o) {
+ o[key] = recursive_regex_to_string(o[key]);
+ }
+ return o;
+ }
+ return o;
}
+
+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));
+
+ return JSON.stringify(o, null, ugly ? null : 4);
+};
diff --git a/now.json b/now.json
@@ -2,10 +2,13 @@
"name": "simpomatic",
"version": 1,
"public": true,
+
"env": {
"BOT_API_TOKEN": "@discord-bot-api-token",
- "CONTEXTUAL_API_KEY": "@contextual-web-api-key",
+ "RAPID_API_KEY": "@rapid-api-key",
"CLIENT_KEY": "@discord-client-key",
- "CLIENT_ID": "@discord-client-id"
+ "CLIENT_ID": "@discord-client-id",
+ "OXFORD_ID": "@oxford-dictionary-id",
+ "OXFORD_KEY": "@oxford-dictionary-key"
}
}
diff --git a/package-lock.json b/package-lock.json
@@ -1,987 +0,0 @@
-{
- "name": "simpomatic",
- "version": "0.1.0",
- "lockfileVersion": 1,
- "requires": true,
- "dependencies": {
- "@discordjs/collection": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/@discordjs/collection/-/collection-0.1.5.tgz",
- "integrity": "sha512-CU1q0UXQUpFNzNB7gufgoisDHP7n+T3tkqTsp3MNUkVJ5+hS3BCvME8uCXAUFlz+6T2FbTCu75A+yQ7HMKqRKw=="
- },
- "@typeit/discord": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/@typeit/discord/-/discord-1.0.3.tgz",
- "integrity": "sha512-s0ahyW51Rz3jDZNODbK5kJoZxBwxahQ5CevpaimZ5KlJylSBA8lM39IRx5QlBOG9TMVktJ2KehMzUDqxkm41PQ==",
- "requires": {
- "glob": "^7.1.4"
- }
- },
- "@types/node": {
- "version": "13.7.7",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.7.tgz",
- "integrity": "sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg=="
- },
- "@types/ws": {
- "version": "7.2.2",
- "resolved": "https://registry.npmjs.org/@types/ws/-/ws-7.2.2.tgz",
- "integrity": "sha512-oqnI3DbGCVI9zJ/WHdFo3CUE8jQ8CVQDUIKaDtlTcNeT4zs6UCg9Gvk5QrFx2QPkRszpM6yc8o0p4aGjCsTi+w==",
- "requires": {
- "@types/node": "*"
- }
- },
- "abab": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz",
- "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg=="
- },
- "abort-controller": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
- "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
- "requires": {
- "event-target-shim": "^5.0.0"
- }
- },
- "acorn": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz",
- "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg=="
- },
- "acorn-globals": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz",
- "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==",
- "requires": {
- "acorn": "^6.0.1",
- "acorn-walk": "^6.0.1"
- },
- "dependencies": {
- "acorn": {
- "version": "6.4.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz",
- "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw=="
- }
- }
- },
- "acorn-walk": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz",
- "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA=="
- },
- "ajv": {
- "version": "6.12.0",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.0.tgz",
- "integrity": "sha512-D6gFiFA0RRLyUbvijN74DWAjXSFxWKaWP7mldxkVhyhAV3+SWA9HEJPHQ2c9soIeTFJqcSdFDGFgdqs1iUU2Hw==",
- "requires": {
- "fast-deep-equal": "^3.1.1",
- "fast-json-stable-stringify": "^2.0.0",
- "json-schema-traverse": "^0.4.1",
- "uri-js": "^4.2.2"
- }
- },
- "asn1": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
- "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
- "requires": {
- "safer-buffer": "~2.1.0"
- }
- },
- "assert-plus": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
- "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
- },
- "async": {
- "version": "0.9.2",
- "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
- "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
- },
- "asynckit": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
- "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
- },
- "aws-sign2": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
- "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
- },
- "aws4": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz",
- "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug=="
- },
- "axios": {
- "version": "0.18.1",
- "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.1.tgz",
- "integrity": "sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==",
- "requires": {
- "follow-redirects": "1.5.10",
- "is-buffer": "^2.0.2"
- }
- },
- "balanced-match": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
- },
- "bcrypt-pbkdf": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
- "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
- "requires": {
- "tweetnacl": "^0.14.3"
- },
- "dependencies": {
- "tweetnacl": {
- "version": "0.14.5",
- "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
- "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
- }
- }
- },
- "brace-expansion": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
- "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
- "requires": {
- "balanced-match": "^1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "browser-process-hrtime": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz",
- "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw=="
- },
- "caseless": {
- "version": "0.12.0",
- "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
- "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
- },
- "combined-stream": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
- "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
- "requires": {
- "delayed-stream": "~1.0.0"
- }
- },
- "concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
- },
- "core-util-is": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
- "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
- },
- "cssom": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz",
- "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw=="
- },
- "cssstyle": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.2.0.tgz",
- "integrity": "sha512-sEb3XFPx3jNnCAMtqrXPDeSgQr+jojtCeNf8cvMNMh1cG970+lljssvQDzPq6lmmJu2Vhqood/gtEomBiHOGnA==",
- "requires": {
- "cssom": "~0.3.6"
- },
- "dependencies": {
- "cssom": {
- "version": "0.3.8",
- "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
- "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="
- }
- }
- },
- "dashdash": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
- "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
- "requires": {
- "assert-plus": "^1.0.0"
- }
- },
- "data-urls": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz",
- "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==",
- "requires": {
- "abab": "^2.0.3",
- "whatwg-mimetype": "^2.3.0",
- "whatwg-url": "^8.0.0"
- }
- },
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "requires": {
- "ms": "2.0.0"
- }
- },
- "decimal.js": {
- "version": "10.2.0",
- "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.2.0.tgz",
- "integrity": "sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw=="
- },
- "deep-is": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
- "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
- },
- "delayed-stream": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
- "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
- },
- "discord.js": {
- "version": "12.0.1",
- "resolved": "https://registry.npmjs.org/discord.js/-/discord.js-12.0.1.tgz",
- "integrity": "sha512-lUlrkAWSb5YTB1WpSZHjeUXxGlHK8VDjrlHLEP4lJj+etFAellURpmRYl29OPJ/7arQWB879pP4rvhhzpdOF7w==",
- "requires": {
- "@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"
- }
- },
- "domexception": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz",
- "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==",
- "requires": {
- "webidl-conversions": "^5.0.0"
- }
- },
- "duckduckgo-images-api": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/duckduckgo-images-api/-/duckduckgo-images-api-1.0.4.tgz",
- "integrity": "sha512-s9iDQMMFeETtfU5Tp5i5GA19XRmU3QrER9EUhwnUdcb76ZgrpLglcQhNiF1G9Gj31LXaUIlki0sa53eRD/FjyA==",
- "requires": {
- "axios": "^0.18.0"
- }
- },
- "ecc-jsbn": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
- "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
- "requires": {
- "jsbn": "~0.1.0",
- "safer-buffer": "^2.1.0"
- }
- },
- "escodegen": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.1.tgz",
- "integrity": "sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==",
- "requires": {
- "esprima": "^4.0.1",
- "estraverse": "^4.2.0",
- "esutils": "^2.0.2",
- "optionator": "^0.8.1",
- "source-map": "~0.6.1"
- }
- },
- "esprima": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
- },
- "estraverse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
- "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="
- },
- "esutils": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
- "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
- },
- "event-target-shim": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
- "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="
- },
- "extend": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
- "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
- },
- "extsprintf": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
- "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
- },
- "fast-deep-equal": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
- "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA=="
- },
- "fast-json-stable-stringify": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
- "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
- },
- "fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
- },
- "follow-redirects": {
- "version": "1.5.10",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
- "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
- "requires": {
- "debug": "=3.1.0"
- }
- },
- "forever-agent": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
- "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
- },
- "form-data": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz",
- "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==",
- "requires": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.8",
- "mime-types": "^2.1.12"
- }
- },
- "fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
- },
- "getpass": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
- "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
- "requires": {
- "assert-plus": "^1.0.0"
- }
- },
- "glob": {
- "version": "7.1.6",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
- "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
- "requires": {
- "fs.realpath": "^1.0.0",
- "inflight": "^1.0.4",
- "inherits": "2",
- "minimatch": "^3.0.4",
- "once": "^1.3.0",
- "path-is-absolute": "^1.0.0"
- }
- },
- "har-schema": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
- "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
- },
- "har-validator": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
- "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
- "requires": {
- "ajv": "^6.5.5",
- "har-schema": "^2.0.0"
- }
- },
- "html-encoding-sniffer": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz",
- "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==",
- "requires": {
- "whatwg-encoding": "^1.0.5"
- }
- },
- "http-signature": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
- "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
- "requires": {
- "assert-plus": "^1.0.0",
- "jsprim": "^1.2.2",
- "sshpk": "^1.7.0"
- }
- },
- "iconv-lite": {
- "version": "0.4.24",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
- "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
- "requires": {
- "safer-buffer": ">= 2.1.2 < 3"
- }
- },
- "inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
- "requires": {
- "once": "^1.3.0",
- "wrappy": "1"
- }
- },
- "inherits": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
- "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
- },
- "ip-regex": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz",
- "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk="
- },
- "is-buffer": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
- "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A=="
- },
- "is-potential-custom-element-name": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz",
- "integrity": "sha1-DFLlS8yjkbssSUsh6GJtczbG45c="
- },
- "is-typedarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
- "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
- },
- "isstream": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
- "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
- },
- "jsbn": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
- "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
- },
- "jsdom": {
- "version": "16.2.0",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.2.0.tgz",
- "integrity": "sha512-6VaW3UWyKbm9DFVIAgTfhuwnvqiqlRYNg5Rk6dINTVoZT0eKz+N86vQZr+nqt1ny1lSB1TWZJWSEWQAfu8oTpA==",
- "requires": {
- "abab": "^2.0.3",
- "acorn": "^7.1.0",
- "acorn-globals": "^4.3.4",
- "cssom": "^0.4.4",
- "cssstyle": "^2.2.0",
- "data-urls": "^2.0.0",
- "decimal.js": "^10.2.0",
- "domexception": "^2.0.1",
- "escodegen": "^1.13.0",
- "html-encoding-sniffer": "^2.0.0",
- "is-potential-custom-element-name": "^1.0.0",
- "nwsapi": "^2.2.0",
- "parse5": "5.1.1",
- "request": "^2.88.0",
- "request-promise-native": "^1.0.8",
- "saxes": "^4.0.2",
- "symbol-tree": "^3.2.4",
- "tough-cookie": "^3.0.1",
- "w3c-hr-time": "^1.0.1",
- "w3c-xmlserializer": "^2.0.0",
- "webidl-conversions": "^5.0.0",
- "whatwg-encoding": "^1.0.5",
- "whatwg-mimetype": "^2.3.0",
- "whatwg-url": "^8.0.0",
- "ws": "^7.2.1",
- "xml-name-validator": "^3.0.0"
- }
- },
- "json-schema": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
- "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
- },
- "json-schema-traverse": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
- "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
- },
- "json-stringify-safe": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
- "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
- },
- "jsprim": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
- "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
- "requires": {
- "assert-plus": "1.0.0",
- "extsprintf": "1.3.0",
- "json-schema": "0.2.3",
- "verror": "1.10.0"
- }
- },
- "levn": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
- "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
- "requires": {
- "prelude-ls": "~1.1.2",
- "type-check": "~0.3.2"
- }
- },
- "lodash": {
- "version": "4.17.15",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
- "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
- },
- "lodash.sortby": {
- "version": "4.7.0",
- "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
- "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg="
- },
- "mime": {
- "version": "2.4.4",
- "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.4.tgz",
- "integrity": "sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA=="
- },
- "mime-db": {
- "version": "1.43.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
- "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ=="
- },
- "mime-types": {
- "version": "2.1.26",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
- "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
- "requires": {
- "mime-db": "1.43.0"
- }
- },
- "minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
- "requires": {
- "brace-expansion": "^1.1.7"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
- },
- "node-fetch": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
- "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA=="
- },
- "nwsapi": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
- "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ=="
- },
- "oauth-sign": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
- "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
- },
- "once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
- "requires": {
- "wrappy": "1"
- }
- },
- "optionator": {
- "version": "0.8.3",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
- "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
- "requires": {
- "deep-is": "~0.1.3",
- "fast-levenshtein": "~2.0.6",
- "levn": "~0.3.0",
- "prelude-ls": "~1.1.2",
- "type-check": "~0.3.2",
- "word-wrap": "~1.2.3"
- }
- },
- "parse5": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
- "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug=="
- },
- "path-is-absolute": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
- "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
- },
- "performance-now": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
- "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
- },
- "prelude-ls": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
- "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
- },
- "prism-media": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/prism-media/-/prism-media-1.2.1.tgz",
- "integrity": "sha512-R3EbKwJiYlTvGwcG1DpUt+06DsxOGS5W4AMEHT7oVOjG93MjpdhGX1whHyjnqknylLMupKAsKMEXcTNRbPe6Vw=="
- },
- "psl": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/psl/-/psl-1.7.0.tgz",
- "integrity": "sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ=="
- },
- "punycode": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
- "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
- },
- "qs": {
- "version": "6.5.2",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
- "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
- },
- "request": {
- "version": "2.88.2",
- "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz",
- "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==",
- "requires": {
- "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"
- },
- "dependencies": {
- "form-data": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
- "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
- "requires": {
- "asynckit": "^0.4.0",
- "combined-stream": "^1.0.6",
- "mime-types": "^2.1.12"
- }
- },
- "tough-cookie": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
- "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
- "requires": {
- "psl": "^1.1.28",
- "punycode": "^2.1.1"
- }
- }
- }
- },
- "request-promise-core": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.3.tgz",
- "integrity": "sha512-QIs2+ArIGQVp5ZYbWD5ZLCY29D5CfWizP8eWnm8FoGD1TX61veauETVQbrV60662V0oFBkrDOuaBI8XgtuyYAQ==",
- "requires": {
- "lodash": "^4.17.15"
- }
- },
- "request-promise-native": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.8.tgz",
- "integrity": "sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ==",
- "requires": {
- "request-promise-core": "1.1.3",
- "stealthy-require": "^1.1.1",
- "tough-cookie": "^2.3.3"
- },
- "dependencies": {
- "tough-cookie": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz",
- "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==",
- "requires": {
- "psl": "^1.1.28",
- "punycode": "^2.1.1"
- }
- }
- }
- },
- "safe-buffer": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz",
- "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg=="
- },
- "safer-buffer": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
- "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
- },
- "saxes": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/saxes/-/saxes-4.0.2.tgz",
- "integrity": "sha512-EZOTeQ4bgkOaGCDaTKux+LaRNcLNbdbvMH7R3/yjEEULPEmqvkFbFub6DJhJTub2iGMT93CfpZ5LTdKZmAbVeQ==",
- "requires": {
- "xmlchars": "^2.2.0"
- }
- },
- "setimmediate": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
- "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "optional": true
- },
- "sshpk": {
- "version": "1.16.1",
- "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
- "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
- "requires": {
- "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"
- },
- "dependencies": {
- "tweetnacl": {
- "version": "0.14.5",
- "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
- "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
- }
- }
- },
- "stealthy-require": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
- "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks="
- },
- "symbol-tree": {
- "version": "3.2.4",
- "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
- "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="
- },
- "tough-cookie": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz",
- "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==",
- "requires": {
- "ip-regex": "^2.1.0",
- "psl": "^1.1.28",
- "punycode": "^2.1.1"
- }
- },
- "tr46": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.0.2.tgz",
- "integrity": "sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg==",
- "requires": {
- "punycode": "^2.1.1"
- }
- },
- "tslib": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz",
- "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA=="
- },
- "tunnel-agent": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
- "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
- "requires": {
- "safe-buffer": "^5.0.1"
- }
- },
- "tweetnacl": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.3.tgz",
- "integrity": "sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw=="
- },
- "type-check": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
- "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
- "requires": {
- "prelude-ls": "~1.1.2"
- }
- },
- "typescript": {
- "version": "3.8.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz",
- "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w=="
- },
- "unirest": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/unirest/-/unirest-0.6.0.tgz",
- "integrity": "sha512-BdYdcYJHXACqZ53k8Zz7QlNK/1W/HjCZlmg1OaaN/oTSp4FTWh0upXGSJsG88PljDBpSrNc2R649drasUA9NEg==",
- "requires": {
- "form-data": "^0.2.0",
- "mime": "^2.4.0",
- "request": "^2.88.0"
- },
- "dependencies": {
- "combined-stream": {
- "version": "0.0.7",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz",
- "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=",
- "requires": {
- "delayed-stream": "0.0.5"
- }
- },
- "delayed-stream": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz",
- "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8="
- },
- "form-data": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz",
- "integrity": "sha1-Jvi8JtpkQOKZy9z7aQNcT3em5GY=",
- "requires": {
- "async": "~0.9.0",
- "combined-stream": "~0.0.4",
- "mime-types": "~2.0.3"
- }
- },
- "mime-db": {
- "version": "1.12.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz",
- "integrity": "sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc="
- },
- "mime-types": {
- "version": "2.0.14",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz",
- "integrity": "sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY=",
- "requires": {
- "mime-db": "~1.12.0"
- }
- }
- }
- },
- "uri-js": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
- "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
- "requires": {
- "punycode": "^2.1.0"
- }
- },
- "uuid": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
- "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="
- },
- "verror": {
- "version": "1.10.0",
- "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
- "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
- "requires": {
- "assert-plus": "^1.0.0",
- "core-util-is": "1.0.2",
- "extsprintf": "^1.2.0"
- }
- },
- "w3c-hr-time": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz",
- "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=",
- "requires": {
- "browser-process-hrtime": "^0.1.2"
- }
- },
- "w3c-xmlserializer": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
- "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==",
- "requires": {
- "xml-name-validator": "^3.0.0"
- }
- },
- "webidl-conversions": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz",
- "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA=="
- },
- "whatwg-encoding": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
- "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
- "requires": {
- "iconv-lite": "0.4.24"
- }
- },
- "whatwg-mimetype": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
- "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g=="
- },
- "whatwg-url": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.0.0.tgz",
- "integrity": "sha512-41ou2Dugpij8/LPO5Pq64K5q++MnRCBpEHvQr26/mArEKTkCV5aoXIqyhuYtE0pkqScXwhf2JP57rkRTYM29lQ==",
- "requires": {
- "lodash.sortby": "^4.7.0",
- "tr46": "^2.0.0",
- "webidl-conversions": "^5.0.0"
- }
- },
- "word-wrap": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
- "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
- },
- "wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
- },
- "ws": {
- "version": "7.2.1",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.1.tgz",
- "integrity": "sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A=="
- },
- "xml-name-validator": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
- "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw=="
- },
- "xmlchars": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
- "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
- }
- }
-}
diff --git a/package.json b/package.json
@@ -9,12 +9,17 @@
"license": "GPL-3.0",
"author": "Sammy et Frens",
"version": "0.1.0",
+ "engines": {
+ "node": ">=10.0.0"
+ },
"main": "./build/main.js",
"types": "./build/main.d.ts",
"scripts": {
- "build": "./build.sh && tsc -b ./tsconfig.json",
+ "build": "./build.sh",
+ "reset": "rm -rf ./build ./node_modules ./yarn.lock ./packages-lock.json",
"start": "node .",
- "quick": "npm run build && npm run start"
+ "quick": "yarn run build && yarn run start",
+ "deploy": "now && echo \"Remeber to scale: `now scale [url] 1 1`\""
},
"homepage": "https://github.com/Demonstrandum/simpomatic",
"repository": {
@@ -25,17 +30,16 @@
"url": "https://github.com/Demonstrandum/simpomatic/issues"
},
"dependencies": {
- "typescript": "^3.8.3",
"@typeit/discord": "1.0.3",
- "@types/node": "",
- "@types/ws": "",
+ "@types/node": "^13.7.7",
+ "@types/ws": "^7.2.2",
+ "deepcopy": "^2.0.0",
"discord.js": "12.0.1",
- "duckduckgo-images-api": "^1.0.4",
- "jsdom": "^16.2.0",
"tslib": "^1.10.0",
+ "typescript": "^3.8.3",
"unirest": "^0.6.0"
},
- "engines": {
- "node": "13.9.0"
+ "devDependencies": {
+ "now": "^17.0.4"
}
}
diff --git a/public/index.html b/public/index.html
@@ -0,0 +1,8 @@
+<html>
+ <head>
+ <title>Simp'O'Matic</title>
+ </head>
+ <body>
+ This is a Discord Bot.
+ </body>
+</html>